Changeset 437 for soft/giet_vm/giet_drivers
- Timestamp:
- Nov 3, 2014, 10:53:00 AM (10 years ago)
- Location:
- soft/giet_vm/giet_drivers
- Files:
-
- 4 deleted
- 31 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_drivers/bdv_driver.c
r426 r437 6 6 // Copyright (c) UPMC-LIP6 7 7 /////////////////////////////////////////////////////////////////////////////////// 8 // The bdv_driver.c and bdv_driver.h files are part ot the GIET-VM kernel.9 // This driver supports the SocLib vci_block_device component, that is10 // a single channel, block oriented, external storage contrÃŽler.11 //12 // The _bdv_read() and _bdv_write() functions are always blocking.13 // They can be called in 3 modes:14 //15 // - In BOOT mode, these functions use a polling policy on the BDV STATUS16 // register to detect transfer completion, as interrupts are not activated.17 // This mode is used by the boot code to load the map.bin file into memory18 // (before MMU activation), or to load the .elf files (after MMU activation).19 //20 // - In KERNEL mode, these functions use a descheduling strategy:21 // The ISR executed when transfer completes should restart the calling task.22 // There is no checking of user access right to the memory buffer.23 // This mode must be used, for an "open" system call.24 //25 // - In USER mode, these functions use a descheduling strategy:26 // The ISR executed when transfer completes should restart the calling task,27 // The user access right to the memory buffer must be checked.28 // This mode must be used for a "read/write" system call.29 //30 // As the BDV component can be used by several programs running in parallel,31 // the _bdv_lock variable guaranties exclusive access to the device. The32 // _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock.33 //34 // Finally, the memory buffer must fulfill the following conditions:35 // - The buffer must be word aligned,36 // - The buffer must be mapped in user space for an user access,37 // - The buffer must be writable in case of (to_mem) access,38 // - The total number of physical pages occupied by the user buffer cannot39 // be larger than 512 pages if the IOMMU is activated,40 // - All physical pages occupied by the user buffer must be contiguous41 // if the IOMMU is not activated.42 // An error code is returned if these conditions are not verified.43 //44 // The SEG_IOC_BASE address must be defined in the hard_config.h file.45 ///////////////////////////////////////////////////////////////////////////////////46 8 // Implementation notes: 47 //48 9 // 1. In order to share code, the two _bdv_read() and _bdv_write() functions 49 10 // call the same _bdv_access() function. 50 //51 11 // 2. All accesses to BDV registers are done by the two 52 12 // _bdv_set_register() and _bdv_get_register() low-level functions, … … 126 86 127 87 #if GIET_DEBUG_IOC_DRIVER 128 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] enters at cycle %d\n" 129 " - to_mem = %d\n" 130 " - mode = %d\n" 131 " - paddr = %l\n" 132 " - sectors = %x\n" 133 " - lba = %x\n", 134 x, y, p, _get_proctime(), to_mem, mode, buf_paddr, count, lba ); 88 _puts("\n[BDV DEBUG] _bdv_access() : P["); 89 _putd( x ); 90 _puts(","); 91 _putd( y ); 92 _puts(","); 93 _putd( p ); 94 _puts("] enters at cycle "); 95 _putd( _get_proctime() ); 96 _puts("\n - to_mem = "); 97 _putd( to_mem ); 98 _puts("\n - mode = "); 99 _putd( mode ); 100 _puts("\n - paddr = "); 101 _putl( buf_paddr ); 102 _puts("\n - sectors = "); 103 _putd( count ); 104 _puts("\n - lba = "); 105 _putx( lba ); 106 _puts("\n"); 135 107 #endif 136 108 … … 141 113 142 114 #if GIET_DEBUG_IOC_DRIVER 143 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] get bdv_lock at cycle %d \n", 144 x, y, p, _get_proctime() ); 115 _puts("\n[BDV DEBUG] _bdv_access() : P["); 116 _putd( x ); 117 _puts(","); 118 _putd( y ); 119 _puts(","); 120 _putd( p ); 121 _puts("] get bdv_lock at cycle "); 122 _pud( _get_proctime() ); 123 _puts("\n"); 145 124 #endif 146 125 … … 160 139 161 140 #if GIET_DEBUG_IOC_DRIVER 162 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer in polling mode\n", 163 x, y, p ); 141 _puts("\n[BDV DEBUG] _bdv_access() : P["); 142 _putd( x ); 143 _puts(","); 144 _putd( y ); 145 _puts(","); 146 _putd( p ); 147 _puts("] launch transfer in polling mode\n"); 164 148 #endif 165 149 unsigned int status; … … 169 153 170 154 #if GIET_DEBUG_IOC_DRIVER 171 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] wait on BDV_STATUS register ...\n", 172 x, y, p ); 155 _puts("\n[BDV DEBUG] _bdv_access() : P["); 156 _putd( x ); 157 _puts(","); 158 _putd( y ); 159 _puts(","); 160 _putd( p ); 161 _puts("] wait on BDV_STATUS register ...\n"); 173 162 #endif 174 163 } … … 214 203 215 204 #if GIET_DEBUG_IOC_DRIVER 216 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] launch transfer in interrupt mode\n", 217 x, y, p ); 218 #endif 205 _puts("\n[BDV DEBUG] _bdv_access() : P["); 206 _putd( x ); 207 _puts(","); 208 _putd( y ); 209 _puts(","); 210 _putd( p ); 211 _puts("] launch transfer in nterrupt mode\n"); 212 #endif 213 219 214 // deschedule task 220 215 _ctx_switch(); 221 216 222 217 #if GIET_DEBUG_IOC_DRIVER 223 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] resume execution after descheduling\n", 224 x, y, p ); 218 _puts("\n[BDV DEBUG] _bdv_access() : P["); 219 _putd( x ); 220 _puts(","); 221 _putd( y ); 222 _puts(","); 223 _putd( p ); 224 _puts("] resume execution after descheduling\n"); 225 225 #endif 226 226 // restore SR 227 227 _it_restore( &save_sr ); 228 228 229 #if GIET_DEBUG_IOC_DRIVER230 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] returns from _it_restore()\n",231 x, y, p );232 #endif233 229 // analyse status 234 230 error = ( (_bdv_status == BLOCK_DEVICE_READ_ERROR) || … … 241 237 242 238 #if GIET_DEBUG_IOC_DRIVER 243 _printf("\n[BDV DEBUG] _bdv_access() : P[%d,%d,%d] exit at cycle %d / error = %d\n", 244 x, y, p, _get_proctime(), error ); 239 _puts("\n[BDV DEBUG] _bdv_access() : P["); 240 _putd( x ); 241 _puts(","); 242 _putd( y ); 243 _puts(","); 244 _putd( p ); 245 _puts("] exit at cycle "); 246 _putd( _get_proctime() ); 247 _puts(" / error = "); 248 _putd( error ) 249 _puts("\n"); 245 250 #endif 246 251 … … 249 254 250 255 /////////////////////////////////////////////////////////////////////////////// 251 // This function cheks block size, and desactivates the interrupts. 252 // Return 0 for success, > 0 if error 253 /////////////////////////////////////////////////////////////////////////////// 256 // External functions 257 /////////////////////////////////////////////////////////////////////////////// 258 259 //////////////////////// 254 260 unsigned int _bdv_init() 255 261 { 256 262 if ( _bdv_get_register( BLOCK_DEVICE_BLOCK_SIZE ) != 512 ) 257 263 { 258 _p rintf("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n");264 _puts("\n[GIET ERROR] in _bdv_init() : block size must be 512 bytes\n"); 259 265 return 1; 260 266 } … … 264 270 } 265 271 266 /////////////////////////////////////////////////////////////////////////////// 267 // Transfer data from the block device to a memory buffer. 268 // - mode : BOOT / KERNEL / USER 269 // - lba : first block index on the block device 270 // - buffer : base address of the memory buffer (must be word aligned) 271 // - count : number of blocks to be transfered. 272 // Returns 0 if success, > 0 if error. 273 /////////////////////////////////////////////////////////////////////////////// 272 //////////////////////////////////////////////// 274 273 unsigned int _bdv_read( unsigned int mode, 275 274 unsigned int lba, … … 284 283 } 285 284 286 /////////////////////////////////////////////////////////////////////////////// 287 // Transfer data from a memory buffer to the block device. 288 // - mode : BOOT / KERNEL / USER 289 // - lba : first block index on the block device 290 // - buffer : base address of the memory buffer (must be word aligned) 291 // - count : number of blocks to be transfered. 292 // Returns 0 if success, > 0 if error. 293 /////////////////////////////////////////////////////////////////////////////// 285 ///////////////////////////////////////////////// 294 286 unsigned int _bdv_write( unsigned int mode, 295 287 unsigned int lba, … … 304 296 } 305 297 306 /////////////////////////////////////////////////////////////////////////////// 307 // Returns device status. 308 /////////////////////////////////////////////////////////////////////////////// 298 ////////////////////////////// 309 299 unsigned int _bdv_get_status() 310 300 { … … 312 302 } 313 303 314 /////////////////////////////////////////////////////////////////////////////// 315 // Returns block size. 316 /////////////////////////////////////////////////////////////////////////////// 304 ////////////////////////////////// 317 305 unsigned int _bdv_get_block_size() 318 306 { … … 320 308 } 321 309 322 /////////////////////////////////////////////////////////////////////////////////// 323 // This ISR save the status, acknowledge the IRQ, 324 // and activates the task waiting on IO transfer. 325 // It can be an HWI or a SWI. 326 // 327 // TODO the _set_task_slot access should be replaced by an atomic LL/SC 328 // when the CTX_RUN bool will be replaced by a bit_vector. 329 /////////////////////////////////////////////////////////////////////////////////// 310 ///////////////////////////////////// 330 311 void _bdv_isr( unsigned int irq_type, // HWI / WTI 331 312 unsigned int irq_id, // index returned by ICU -
soft/giet_vm/giet_drivers/bdv_driver.h
r350 r437 5 5 // Maintainer: cesar fuguet 6 6 // Copyright (c) UPMC-LIP6 7 /////////////////////////////////////////////////////////////////////////////////// 8 // The bdv_driver.c and bdv_driver.h files are part ot the GIET-VM kernel. 9 // This driver supports the SocLib vci_block_device component, that is 10 // a single channel, block oriented, external storage contrÃŽler. 11 // 12 // The _bdv_read() and _bdv_write() functions are always blocking. 13 // They can be called in 3 modes: 14 // 15 // - In BOOT mode, these functions use a polling policy on the BDV STATUS 16 // register to detect transfer completion, as interrupts are not activated. 17 // This mode is used by the boot code to load the map.bin file into memory 18 // (before MMU activation), or to load the .elf files (after MMU activation). 19 // 20 // - In KERNEL mode, these functions use a descheduling strategy: 21 // The ISR executed when transfer completes should restart the calling task. 22 // There is no checking of user access right to the memory buffer. 23 // This mode must be used, for an "open" system call. 24 // 25 // - In USER mode, these functions use a descheduling strategy: 26 // The ISR executed when transfer completes should restart the calling task, 27 // The user access right to the memory buffer must be checked. 28 // This mode must be used for a "read/write" system call. 29 // 30 // As the BDV component can be used by several programs running in parallel, 31 // the _bdv_lock variable guaranties exclusive access to the device. The 32 // _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock. 33 // 34 // Finally, the memory buffer must fulfill the following conditions: 35 // - The buffer must be word aligned, 36 // - The buffer must be mapped in user space for an user access, 37 // - The buffer must be writable in case of (to_mem) access, 38 // - The total number of physical pages occupied by the user buffer cannot 39 // be larger than 512 pages if the IOMMU is activated, 40 // - All physical pages occupied by the user buffer must be contiguous 41 // if the IOMMU is not activated. 42 // An error code is returned if these conditions are not verified. 43 // 44 // The SEG_IOC_BASE address must be defined in the hard_config.h file. 7 45 /////////////////////////////////////////////////////////////////////////////////// 8 46 … … 56 94 57 95 /////////////////////////////////////////////////////////////////////////////////// 58 // BDV access functions (vci_block_device)96 // Access functions 59 97 /////////////////////////////////////////////////////////////////////////////////// 60 98 99 /////////////////////////////////////////////////////////////////////////////////// 100 // This function cheks block size == 512, and desactivates the interrupts. 101 // Return 0 for success, > 0 if error 102 /////////////////////////////////////////////////////////////////////////////////// 61 103 extern unsigned int _bdv_init(); 62 104 105 /////////////////////////////////////////////////////////////////////////////////// 106 // Transfer data from the block device to a memory buffer. 107 // - mode : BOOT / KERNEL / USER 108 // - lba : first block index on the block device 109 // - buffer : base address of the memory buffer (must be word aligned) 110 // - count : number of blocks to be transfered. 111 // Returns 0 if success, > 0 if error. 112 //////////////////////////////////////////////////////////////////////////////////// 113 extern unsigned int _bdv_read( unsigned int mode, 114 unsigned int lba, 115 unsigned long long buffer, 116 unsigned int count ); 117 118 /////////////////////////////////////////////////////////////////////////////////// 119 // Transfer data from a memory buffer to the block device. 120 // - mode : BOOT / KERNEL / USER 121 // - lba : first block index on the block device 122 // - buffer : base address of the memory buffer (must be word aligned) 123 // - count : number of blocks to be transfered. 124 // Returns 0 if success, > 0 if error. 125 /////////////////////////////////////////////////////////////////////////////////// 63 126 extern unsigned int _bdv_write( unsigned int mode, 64 127 unsigned int lba, … … 66 129 unsigned int count ); 67 130 68 extern unsigned int _bdv_read( unsigned int mode, 69 unsigned int lba, 70 unsigned long long buffer, 71 unsigned int count ); 72 131 /////////////////////////////////////////////////////////////////////////////////// 132 // Returns device status. 133 /////////////////////////////////////////////////////////////////////////////////// 73 134 extern unsigned int _bdv_get_status(); 74 135 136 /////////////////////////////////////////////////////////////////////////////////// 137 // Returns block size. 138 /////////////////////////////////////////////////////////////////////////////////// 75 139 extern unsigned int _bdv_get_block_size(); 76 140 141 /////////////////////////////////////////////////////////////////////////////////// 142 // This ISR save the status, acknowledge the IRQ, and activates the task 143 // waiting on IO transfer. It can be an HWI or a SWI. 144 // 145 // TODO the _set_task_slot access should be replaced by an atomic LL/SC 146 // when the CTX_RUN bool will be replaced by a bit_vector. 147 /////////////////////////////////////////////////////////////////////////////////// 77 148 extern void _bdv_isr( unsigned irq_type, 78 149 unsigned irq_id, 79 150 unsigned channel ); 80 151 81 ///////////////////////////////////////////////////////////////////////////////////82 152 83 153 #endif -
soft/giet_vm/giet_drivers/cma_driver.c
r320 r437 4 4 // Author : alain greiner 5 5 // Copyright (c) UPMC-LIP6 6 ///////////////////////////////////////////////////////////////////////////////////7 // The cma_driver.c and cma_driver.h files are part ot the GIET-VM kernel.8 // This driver supports the SocLib vci_chbuf_dma component, that is9 // a multi channels, chained buffer DMA controller.10 //11 // This component can be used in conjonction with the SocLib vci_frame_buffer12 // to display images, or with the SocLib vci_multi_nic controller to tranfer13 // both RX and TX packets between NIC and memory buffers.14 //15 // The SEG_DMA_BASE address must be defined in the hard_config.h file16 ////////////////////////////////////////////////////////////////////////////////////17 // Implementation notes:18 // 1. The higher level access functions can be found in the fbf_driver and19 // nic_driver files.20 // 2. All accesses to CMA registers are done by the two21 // _cma_set_register() and _cma_get_register() low-level functions,22 // that are handling virtual / physical extended addressing.23 6 /////////////////////////////////////////////////////////////////////////////////// 24 7 … … 31 14 #endif 32 15 33 /////////////////////////////////////////////////////////////////////////////// 34 // This low_level function returns the value contained in register (index). 35 /////////////////////////////////////////////////////////////////////////////// 16 ///////////////////////////////////////////////////// 36 17 unsigned int _cma_get_register( unsigned int channel, 37 18 unsigned int index ) … … 42 23 } 43 24 44 /////////////////////////////////////////////////////////////////////////////// 45 // This low-level function set a new value in register (index). 46 /////////////////////////////////////////////////////////////////////////////// 25 ///////////////////////////////////////////// 47 26 void _cma_set_register( unsigned int channel, 48 27 unsigned int index, … … 54 33 } 55 34 56 /////////////////////////////////////////////////////////////////////////////// 57 // This ISR handles the IRQ generated by a CMA channel. 58 /////////////////////////////////////////////////////////////////////////////// 35 //////////////////////////////////////////////////// 36 void _cma_start_channel( unsigned int channel, 37 unsigned long long src_paddr, 38 unsigned int src_nbufs, 39 unsigned long long dst_paddr, 40 unsigned int dst_nbufs, 41 unsigned int buf_length ) 42 { 43 _cma_set_register( channel, CHBUF_SRC_DESC , (unsigned int)(src_paddr & 0xFFFFFFFF) ); 44 _cma_set_register( channel, CHBUF_SRC_EXT , (unsigned int)(src_paddr >> 32) ); 45 _cma_set_register( channel, CHBUF_SRC_NBUFS, src_nbufs ); 46 _cma_set_register( channel, CHBUF_DST_DESC , (unsigned int)(dst_paddr & 0xFFFFFFFF) ); 47 _cma_set_register( channel, CHBUF_DST_EXT , (unsigned int)(dst_paddr >> 32) ); 48 _cma_set_register( channel, CHBUF_DST_NBUFS, dst_nbufs ); 49 _cma_set_register( channel, CHBUF_BUF_SIZE , buf_length ); 50 _cma_set_register( channel, CHBUF_PERIOD , 300 ); 51 _cma_set_register( channel, CHBUF_RUN , 1 ); 52 } 53 54 ////////////////////////////////////////////// 55 void _cma_stop_channel( unsigned int channel ) 56 { 57 _cma_set_register( channel, CHBUF_RUN , 0 ); 58 } 59 60 ////////////////////////////////////// 59 61 void _cma_isr( unsigned int irq_type, 60 62 unsigned int irq_id, 61 63 unsigned int channel ) 62 64 { 63 _p rintf("\n[GIET ERROR] _cma_isr() not implemented\n");65 _puts("\n[GIET ERROR] _cma_isr() not implemented\n"); 64 66 _exit(); 65 67 } -
soft/giet_vm/giet_drivers/cma_driver.h
r295 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The cma_driver.c and cma_driver.h files are part ot the GIET-VM kernel. 8 // This driver supports the SocLib vci_chbuf_dma component, that is 9 // a multi channels, chained buffer DMA controller. 10 // 11 // This component can be used in conjonction with the SocLib vci_frame_buffer 12 // to display images, or with the SocLib vci_multi_nic controller to tranfer 13 // RX or TX packets between NIC and memory buffers. 14 // 15 // The SEG_CMA_BASE address must be defined in the hard_config.h file 16 // 17 // All accesses to CMA registers are done by the two _cma_set_register() 18 // and _cma_get_register() low-level functions, that are handling virtual 19 // to physical extended addressing. 20 // 21 // The higher level access functions are defined in the fbf_driver 22 // and nic_driver files. 23 /////////////////////////////////////////////////////////////////////////////////// 7 24 8 25 #ifndef _GIET_CMA_DRIVERS_H_ … … 10 27 11 28 /////////////////////////////////////////////////////////////////////////////////// 12 // CMA (vci_chbuf_dma)registers offsets29 // registers offsets 13 30 /////////////////////////////////////////////////////////////////////////////////// 14 31 … … 30 47 31 48 /////////////////////////////////////////////////////////////////////////////////// 32 // CMA (vci_chbuf_dma) low-levelaccess functions49 // access functions 33 50 /////////////////////////////////////////////////////////////////////////////////// 34 51 52 //////////////////////////////////////////////////////////// 35 53 extern unsigned int _cma_get_register( unsigned int channel, 36 54 unsigned int index ); 37 55 56 /////////////////////////////////////////////////// 38 57 extern void _cma_set_register( unsigned int channel, 39 58 unsigned int index, 40 59 unsigned int value ); 41 60 61 /////////////////////////////////////////////////// 62 void _cma_start_channel( unsigned int channel, 63 unsigned long long src_paddr, 64 unsigned int src_nbufs, 65 unsigned long long dst_paddr, 66 unsigned int dst_nbufs, 67 unsigned int buf_length ); 68 69 ////////////////////////////////////////////// 70 void _cma_stop_channel( unsigned int channel ); 71 72 //////////////////////////////////////////// 42 73 extern void _cma_isr( unsigned int irq_type, 43 74 unsigned int irq_id, 44 75 unsigned int channel ); 45 46 ///////////////////////////////////////////////////////////////////////////////////47 76 48 77 #endif -
soft/giet_vm/giet_drivers/dma_driver.c
r345 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The dma_driver.c and dma_driver.h files are part ot the GIET-VM nano-kernel.8 // This driver supports the SoCLib vci_multi_dma component.9 //10 // It can exist several DMA controlers in the architecture (one per cluster),11 // and each controller can contain several channels.12 //13 // There is (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index:14 // dma_id = cluster_xy * NB_DMA_CHANNELS + loc_id15 //16 // A DMA channel is a private ressource allocated to a given processor.17 // It is exclusively used by the kernet to speedup data transfers, and18 // there is no lock protecting exclusive access to the channel.19 // As the kernel uses a polling policy on the DMA_STATUS register to detect20 // transfer completion, the DMA IRQ is not used.21 //22 // The virtual base address of the segment associated to a channel is:23 // SEG_DMA_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + DMA_SPAN * channel_id24 //25 // The SEG_DMA_BASE virtual address mus be defined in the hard_config.h file.26 ////////////////////////////////////////////////////////////////////////////////////27 7 28 8 #include <giet_config.h> … … 101 81 } 102 82 103 ////////////////////////////////////////////////////////////////////////////////// 104 // AS the GIET-VM uses a polling policy to detect transfer completion, 105 // The DMA component initialisation must disable interrupts. 106 // This function disables interrupts for one DMA channel in one cluster. 107 // Returns 0 if success, returns > 0 if error. 108 ////////////////////////////////////////////////////////////////////////////////// 83 //////////////////////////////////////////////// 109 84 unsigned int _dma_init( unsigned int cluster_xy, 110 85 unsigned int channel_id ) … … 127 102 } 128 103 129 ////////////////////////////////////////////////////////////////////////////////// 130 // This function re-initialises one DMA channel in one cluster after a transfer 131 // completion. It actually forces the channel to return in iDLE state. 132 ////////////////////////////////////////////////////////////////////////////////// 104 ////////////////////////////////////////////////// 133 105 unsigned int _dma_reset( unsigned int cluster_xy, 134 106 unsigned int channel_id ) … … 151 123 } 152 124 153 ////////////////////////////////////////////////////////////////////////////////// 154 // This function returns the status of a DMA channel in a given cluster 155 ////////////////////////////////////////////////////////////////////////////////// 125 ////////////////////////////////////////////////////// 156 126 unsigned int _dma_get_status( unsigned int cluster_xy, 157 127 unsigned int channel_id ) … … 173 143 } 174 144 175 ////////////////////////////////////////////////////////////////////////////////// 176 // This function sets the physical address (including 64 bits extension) 177 // for the source and destination buffers in a DMA channel in a given cluster 178 // and sets the transfer size to lauch the transfer. 179 ////////////////////////////////////////////////////////////////////////////////// 145 //////////////////////////////////////////////////////// 180 146 void _dma_start_transfer( unsigned int cluster_xy, // DMA cluster 181 147 unsigned int channel_id, // DMA channel … … 201 167 } 202 168 203 /////////////////////////////////////////////////////////////////////////////////// 204 // This function copies a source memory buffer to a destination memory buffer, 205 // using directly physical addresses. 206 // This blocking function is supposed to be used by the kernel only, 207 // and uses a polling policy on DMA_STATUS register to detect completion. 208 // Therefore, the DMA_IRQ is NOT used. 209 // The source and destination buffers base addresses must be word aligned, 210 // and the buffer's size must be multiple of 4. 211 // In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 212 // message is displayed on TTY0, and the system crash. 213 /////////////////////////////////////////////////////////////////////////////////// 169 /////////////////////////////////////////////////////// 214 170 void _dma_physical_copy( unsigned int cluster_xy, // DMA cluster 215 171 unsigned int channel_id, // DMA channel … … 225 181 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) ) 226 182 { 227 _p rintf("\n[GIETERROR] in _dma_physical_copy() : illegal DMA channel ");183 _puts("\n[DMA ERROR] in _dma_physical_copy() : illegal DMA channel "); 228 184 _exit(); 229 185 } … … 232 188 if ( (dst_paddr & 0x3) || (src_paddr & 0x3) || (size & 0x3) ) 233 189 { 234 _printf("\n[GIET ERROR] in _dma_physical_copy() : buffer unaligned\n"); 235 _exit(); 236 } 237 238 #if GIET_DEBUG_DMA_DRIVER 239 _printf("\n[DMA DEBUG] Start a dma_physical_copy on channel[%d,%d,%d] at cycle %d\n" 240 " - src_paddr = %l\n" 241 " - dst_paddr = %l\n" 242 " - bytes = %x\n", 243 x, y, channel_id, _get_proctime(), src_paddr, dst_paddr, size ); 190 _puts("\n[DMA ERROR] in _dma_physical_copy() : buffer unaligned\n"); 191 _exit(); 192 } 193 194 #if GIET_DEBUG_DMA_DRIVER 195 _puts("\n[DMA DEBUG] enter _dma_physical_copy() for channel["); 196 _putd( x ); 197 _puts(","); 198 _putd( y ); 199 _puts(","); 200 _putd( channel_id ); 201 _puts("] at cycle "); 202 _putd( _get_proctime() ); 203 _puts("\n - src_paddr = "); 204 _putl( src_paddr ); 205 _puts("\n - dst_paddr = "); 206 _putl( dst_paddr ); 207 _puts("\n - bytes = "); 208 _putd( size ); 209 _puts("\n"); 244 210 #endif 245 211 … … 256 222 257 223 #if GIET_DEBUG_DMA_DRIVER 258 _p rintf("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS register\n");224 _puts("\n[DMA DEBUG] _dma_physical_copy() : ... waiting on DMA_STATUS register\n"); 259 225 #endif 260 226 … … 264 230 if( status != DMA_SUCCESS ) 265 231 { 266 _printf("\n[GIET ERROR] in _dma_physical_copy() : DMA_STATUS = %x\n", status ); 267 _exit(); 268 } 232 _puts("\n[DMA ERROR] in _dma_physical_copy() : bad DMA_STATUS"); 233 _exit(); 234 } 235 269 236 // reset dma channel 270 237 _dma_reset( cluster_xy, channel_id ); 271 238 272 239 #if GIET_DEBUG_DMA_DRIVER 273 _printf("\n[DMA DEBUG] _dma_physical_copy() completed at cycle %d\n", _get_proctime() ); 240 _puts("\n[DMA DEBUG] exit _dma_physical_copy() at cycle "); 241 _putd( _get_proctime() ); 242 _puts("\n"); 274 243 #endif 275 244 276 245 #else // NB_DMA_CHANNELS == 0 277 _printf("\n[GIET ERROR] in _dma_physical_copy() : NB_DMA_CHANNELS == 0 / cycle %d\n", 278 _get_proctime);246 247 _puts("\n[DMA ERROR] in _dma_physical_copy() : NB_DMA_CHANNELS == 0\n"); 279 248 _exit(); 280 #endif 281 } 282 283 /////////////////////////////////////////////////////////////////////////////////// 284 // This function copies a source memory buffer to a destination memory buffer, 285 // making virtual to physical address translation: the MMU should be activated. 286 // This blocking function is supposed to be used by the kernel only, 287 // and uses a polling policy on DMA_STATUS register to detect completion. 288 // Therefore, the DMA_IRQ is NOT used. 289 // The source and destination buffers base addresses must be word aligned, 290 // and the buffer's size must be multiple of 4. 291 // In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 292 // message is displayed on TTY0, and the system crash. 293 /////////////////////////////////////////////////////////////////////////////////// 249 250 #endif 251 } 252 253 254 //////////////////////////////////////// 294 255 void _dma_copy( unsigned int cluster_xy, // DMA cluster 295 256 unsigned int channel_id, // DMA channel … … 306 267 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (channel_id >= NB_DMA_CHANNELS) ) 307 268 { 308 _p rintf("\n[GIETERROR] in _dma_copy() : illegal DMA channel ");269 _puts("\n[DMA ERROR] in _dma_copy() : illegal DMA channel "); 309 270 _exit(); 310 271 } … … 313 274 if ( (dst_vaddr & 0x3) || (src_vaddr & 0x3) || (size & 0x3) ) 314 275 { 315 _p rintf("\n[GIETERROR] in _dma_copy() : buffer unaligned\n");276 _puts("\n[DMA ERROR] in _dma_copy() : buffer unaligned\n"); 316 277 _exit(); 317 278 } … … 322 283 323 284 #if GIET_DEBUG_DMA_DRIVER 324 _printf("\n[DMA DEBUG] Start a dma_copy on channel[%d,%d,%d] at cycle %d\n" 325 " - src_vaddr = %x\n" 326 " - dst_vaddr = %x\n" 327 " - bytes = %x\n", 328 x, y, channel_id, _get_proctime(), src_vaddr, dst_vaddr, size ); 285 _puts("\n[DMA DEBUG] enter _dma_copy() for channel["); 286 _putd( x ); 287 _puts(","); 288 _putd( y ); 289 _puts(","); 290 _putd( channel_id ); 291 _puts("] at cycle "); 292 _putd( _get_proctime() ); 293 _puts("\n - src_vaddr = "); 294 _putx( src_vaddr ); 295 _puts("\n - dst_vaddr = "); 296 _putx( dst_vaddr ); 297 _puts("\n - bytes = "); 298 _putd( size ); 299 _puts("\n"); 329 300 #endif 330 301 … … 334 305 (size & 0x3) ) 335 306 { 336 _p rintf("\n[GIETERROR] in _dma_copy() : buffer unaligned\n");307 _puts("\n[DMA ERROR] in _dma_copy() : buffer unaligned\n"); 337 308 _exit(); 338 309 } … … 348 319 if ( ko ) 349 320 { 350 _p rintf("\n[GIETERROR] in _dma_copy() : source buffer unmapped\n");321 _puts("\n[DMA ERROR] in _dma_copy() : source buffer unmapped\n"); 351 322 _exit(); 352 323 } … … 361 332 if ( ko ) 362 333 { 363 _p rintf("\n[GIETERROR] in _dma_copy() : dest buffer unmapped\n");334 _puts("\n[DMA ERROR] in _dma_copy() : dest buffer unmapped\n"); 364 335 _exit(); 365 336 } … … 368 339 369 340 #if GIET_DEBUG_DMA_DRIVER 370 _printf(" - src_paddr = %l\n" 371 " - dst_paddr = %l\n", 372 src_paddr, dst_paddr ); 341 _puts("\n - src_paddr = "); 342 _putl( src_paddr ); 343 _puts("\n - dst_paddr = "); 344 _putl( dst_paddr ); 345 _puts("\n"); 373 346 #endif 374 347 … … 385 358 386 359 #if GIET_DEBUG_DMA_DRIVER 387 _p rintf("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register\n");360 _puts("\n[DMA DEBUG] _dma_copy() : ... waiting on DMA_STATUS register\n"); 388 361 #endif 389 362 … … 393 366 if( status != DMA_SUCCESS ) 394 367 { 395 _p rintf("\n[GIET ERROR] in _dma_copy() : DMA_STATUS = %x\n", status);368 _puts("\n[DMA ERROR] in _dma_copy() : bad DMA_STATUS\n"); 396 369 _exit(); 397 370 } … … 400 373 401 374 #if GIET_DEBUG_DMA_DRIVER 402 _printf("\n[DMA DEBUG] _dma_copy() completed at cycle %d\n", _get_proctime() ); 375 _puts("\n[DMA DEBUG] exit _dma_copy() at cycle "); 376 _putd( _get_proctime() ); 377 _puts("\n"); 403 378 #endif 404 379 405 380 #else // NB_DMA_CHANNELS == 0 406 _printf("\n[GIET ERROR] in _dma_copy() : NB_DMA_CHANNELS == 0 / cycle %d\n", 407 _get_proctime);381 382 _puts("\n[DMA ERROR] in _dma_copy() : NB_DMA_CHANNELS == 0\n"); 408 383 _exit(); 384 409 385 #endif 410 386 } // end _dma_copy 411 387 412 /////////////////////////////////////////////////////////////////////////////// 413 // This ISR handles the IRQ generated by a DMA channel. 414 /////////////////////////////////////////////////////////////////////////////// 388 ///////////////////////////////////// 415 389 void _dma_isr( unsigned int irq_type, 416 390 unsigned int irq_id, 417 391 unsigned int channel ) 418 392 { 419 _printf("\n[GIET ERROR] _dma_isr() not implemented / cycle %d\n", 420 _get_proctime() ); 393 _puts("\n[DMA ERROR] _dma_isr() not implemented\n"); 421 394 _exit(); 422 395 } -
soft/giet_vm/giet_drivers/dma_driver.h
r343 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The dma_driver.c and dma_driver.h files are part ot the GIET-VM nano-kernel. 8 // This driver supports the SoCLib vci_multi_dma component. 9 // 10 // It can exist several DMA controlers in the architecture (one per cluster), 11 // and each controller can contain several channels. 12 // 13 // There is (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index: 14 // dma_id = cluster_xy * NB_DMA_CHANNELS + loc_id 15 // 16 // A DMA channel is a private ressource allocated to a given processor. 17 // It is exclusively used by the kernet to speedup data transfers, and 18 // there is no lock protecting exclusive access to the channel. 19 // As the kernel uses a polling policy on the DMA_STATUS register to detect 20 // transfer completion, the DMA IRQ is not used. 21 // 22 // The virtual base address of the segment associated to a channel is: 23 // SEG_DMA_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + DMA_SPAN * channel_id 24 // 25 // The SEG_DMA_BASE virtual address mus be defined in the hard_config.h file. 26 //////////////////////////////////////////////////////////////////////////////////// 7 27 8 28 #ifndef _GIET_DMA_DRIVER_H_ … … 37 57 38 58 39 /////////////////////////////////////////////////////////////////////////////// ////40 // Multi DMA variables and access functions (vci_multi_dma)41 /////////////////////////////////////////////////////////////////////////////// ////59 /////////////////////////////////////////////////////////////////////////////// 60 // low-level access functions 61 /////////////////////////////////////////////////////////////////////////////// 42 62 43 // low level access functions 63 ////////////////////////////////////////////////////////////////////////////////// 64 // This function disables interrupts for one DMA channel in one cluster. 65 // AS the GIET-VM uses a polling policy to detect DMA transfer completion, 66 // the DMA component initialisation must disable interrupts. 67 // Returns 0 if success, returns > 0 if error. 68 ////////////////////////////////////////////////////////////////////////////////// 44 69 extern unsigned int _dma_init( unsigned int cluster_xy, 45 70 unsigned int channel_id ); 46 71 72 ////////////////////////////////////////////////////////////////////////////////// 73 // This function re-initialises one DMA channel in one cluster after transfer 74 // completion. It actually forces the channel to return in IDLE state. 75 ////////////////////////////////////////////////////////////////////////////////// 47 76 extern unsigned int _dma_reset( unsigned int cluster_xy, 48 77 unsigned int channel_id ); 49 78 79 ////////////////////////////////////////////////////////////////////////////////// 80 // This function returns the status of a DMA channel in a given cluster 81 ////////////////////////////////////////////////////////////////////////////////// 50 82 extern unsigned int _dma_get_status( unsigned int cluster_xy, 51 83 unsigned int channel_id ); 52 84 85 ////////////////////////////////////////////////////////////////////////////////// 86 // This function sets the physical address (including 64 bits extension) 87 // for the source and destination buffers in a DMA channel in a given cluster 88 // and sets the transfer size to lauch the transfer. 89 ////////////////////////////////////////////////////////////////////////////////// 53 90 extern void _dma_start_transfer( unsigned int cluster_xy, 54 91 unsigned int channel_id, … … 57 94 unsigned int size ); 58 95 59 // higher level access function 96 ////////////////////////////////////////////////////////////////////////////////// 97 // higher level access function 98 ////////////////////////////////////////////////////////////////////////////////// 99 100 /////////////////////////////////////////////////////////////////////////////////// 101 // This function copies a source memory buffer to a destination memory buffer, 102 // using directly physical addresses. 103 // This blocking function is supposed to be used by the kernel only, 104 // and uses a polling policy on DMA_STATUS register to detect completion. 105 // Therefore, the DMA_IRQ is NOT used. 106 // The source and destination buffers base addresses must be word aligned, 107 // and the buffer's size must be multiple of 4. 108 // In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 109 // message is displayed on TTY0, and system crash. 110 /////////////////////////////////////////////////////////////////////////////////// 60 111 extern void _dma_physical_copy( unsigned int cluster_xy, 61 112 unsigned int channel_id, … … 64 115 unsigned int size ); 65 116 117 /////////////////////////////////////////////////////////////////////////////////// 118 // This function copies a source memory buffer to a destination memory buffer, 119 // making virtual to physical address translation: the MMU should be activated. 120 // This blocking function is supposed to be used by the kernel only, 121 // and uses a polling policy on DMA_STATUS register to detect completion. 122 // Therefore, the DMA_IRQ is NOT used. 123 // The source and destination buffers base addresses must be word aligned, 124 // and the buffer's size must be multiple of 4. 125 // In case of error (buffer unmapped, unaligned, or DMA_STATUS error), an error 126 // message is displayed on TTY0, and system crash. 127 /////////////////////////////////////////////////////////////////////////////////// 66 128 extern void _dma_copy( unsigned int cluster_xy, 67 129 unsigned int channel_id, … … 71 133 unsigned int size ); 72 134 135 /////////////////////////////////////////////////////////////////////////////// 136 // This ISR should not be used by the GIET_VM, because the DMA is only 137 // used by the kernel in the boot phase, with a polling strategy. 138 /////////////////////////////////////////////////////////////////////////////// 73 139 extern void _dma_isr( unsigned int irq_type, 74 140 unsigned int irq_id, 75 141 unsigned int channel ); 76 142 77 ///////////////////////////////////////////////////////////////////////////////////78 143 79 144 #endif -
soft/giet_vm/giet_drivers/hba_driver.c
r320 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The hba_driver.c and hba_driver.h files are part ot the GIET-VM kernel.8 // This driver supports the SocLib VciMultiAhci component, that is a multi-channels,9 // block oriented, external storage contrÃŽler, respecting the AHCI standard.10 //11 // The SEG_IOC_BASE virtual address must be defined in the hard_config.h file.12 //////////////////////////////////////////////////////////////////////////////////13 7 // Implementation notes: 14 //15 8 // 1. In order to share code, the two _hba_read() and _hba_write() functions 16 9 // call the same _hba_set_cmd() function. 17 //18 10 // 2. All accesses to HBA registers are done by the two 19 11 // _hba_set_register() and _hba_get_register() low-level functions, … … 42 34 43 35 ////////////////////////////////////////////////////////////////// 44 // Global variables36 // Global variables 45 37 ////////////////////////////////////////////////////////////////// 46 38 … … 89 81 // buffer must be an integer number of blocks entirely contained in a single 90 82 // page frame. 91 // return 0 if success, > 0if error83 // return 0 if success, -1 if error 92 84 /////////////////////////////////////////////////////////////////////////////// 93 85 unsigned int _hba_cmd_set( unsigned int channel, // channel index … … 109 101 if( buffer & (block_size-1) ) 110 102 { 111 _p rintf("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n");112 return 1;103 _puts("\n[GIET ERROR] in _hba_set_cmd() : user buffer not block aligned\n"); 104 return -1; 113 105 } 114 106 … … 120 112 if( pxci & (1<<cmd_id ) ) 121 113 { 122 _printf("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel %d\n", 123 channel ); 124 return 1; 114 _puts("\n[GIET ERROR] in _hba_set_cmd() : command list full for channel "); 115 _putd( channel ); 116 _puts("\n"); 117 return -1; 125 118 } 126 119 … … 188 181 if ( ko ) 189 182 { 190 _p rintf("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n");191 return 1;183 _puts("[GIET ERROR] in _hba_set_cmd() : user buffer unmapped\n"); 184 return -1; 192 185 } 193 186 if ((flags & PTE_U) == 0) 194 187 { 195 _p rintf("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n");196 return 1;188 _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not in user space\n"); 189 return -1; 197 190 } 198 191 if (((flags & PTE_W) == 0 ) && (is_read == 0) ) 199 192 { 200 _p rintf("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n");201 return 1;193 _puts("[GIET ERROR] in _hba_set_cmd() : user buffer not writable\n"); 194 return -1; 202 195 } 203 196 … … 205 198 if( buf_id > 245 ) 206 199 { 207 _p rintf("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n");208 return 1;200 _puts("[GIET ERROR] in _hba_set_cmd() : max number of buffers is 248\n"); 201 return -1; 209 202 } 210 203 … … 218 211 cmd_table->entry[buf_id].dbc = count; 219 212 220 #if GIET_DEBUG_HBA_DRIVER221 _printf("\n- buf_index = ");222 _putd( buf_id );223 _printf(" / paddr = ");224 _putl( paddr );225 _printf(" / count = ");226 _putd( count );227 _printf("\n");228 #endif229 213 buf_id++; 230 214 } … … 237 221 cmd_table->entry[buf_id].dbc = count; 238 222 239 #if GIET_DEBUG_HBA_DRIVER240 _printf("\n- buf_index = ");241 _putd( buf_id );242 _printf(" / paddr = ");243 _putl( paddr );244 _printf(" / count = ");245 _putd( count );246 _printf("\n");247 #endif248 223 buf_id++; 249 224 } … … 257 232 cmd_table->entry[buf_id].dbc = count; 258 233 259 #if GIET_DEBUG_HBA_DRIVER260 _printf("\n- buf_index = ");261 _putd( buf_id );262 _printf(" / paddr = ");263 _putl( paddr );264 _printf(" / count = ");265 _putd( count );266 _printf("\n");267 #endif268 234 buf_id++; 269 235 … … 274 240 cmd_table->entry[buf_id].dbc = count; 275 241 276 #if GIET_DEBUG_HBA_DRIVER277 _printf("\n- buf_index = ");278 _putd( buf_id );279 _printf(" / paddr = ");280 _putl( paddr );281 _printf(" / count = ");282 _putd( count );283 _printf("\n");284 #endif285 242 buf_id++; 286 243 } … … 293 250 cmd_table->entry[buf_id].dbc = count; 294 251 295 #if GIET_DEBUG_HBA_DRIVER296 _printf("\n- buf_index = ");297 _putd( buf_id );298 _printf(" / paddr = ");299 _putl( paddr );300 _printf(" / count = ");301 _putd( count );302 _printf("\n");303 #endif304 252 buf_id++; 305 253 } … … 308 256 309 257 310 /////////////////////////////////////////////////////////////////// 311 // Register a write command in Command List and Command Table 312 // for a single physical buffer. 313 // Returns 0 if success, > 0 if error. 314 /////////////////////////////////////////////////////////////////// 315 unsigned int _hba_write( unsigned int channel, 316 unsigned int mode, 317 unsigned int lba, 318 paddr_t buffer, 319 unsigned int count ) 320 { 321 return _hba_cmd_set( channel, 322 0, // write 323 lba, 324 buffer, 325 count ); 326 } 327 328 /////////////////////////////////////////////////////////////////// 329 // Register a read command in Command List and Command Table 330 // for a single physical buffer. 331 // Returns 0 if success, > 0 if error. 332 /////////////////////////////////////////////////////////////////// 333 unsigned int _hba_read( unsigned int channel, 334 unsigned int mode, 335 unsigned int lba, 336 paddr_t buffer, 337 unsigned int count ) 338 { 339 return _hba_cmd_set( channel, 340 1, // read 341 lba, 342 buffer, 343 count ); 344 } 345 346 ////////////////////////////////////////////////////////////////// 347 // This function initializes for a given channel 348 // - the HBA hardware registers, 349 // - the command list pointer, 350 // - the command lists physical addresse, 351 // - the command tables physical addresses array, 352 ////////////////////////////////////////////////////////////////// 258 ////////////////////////////////////////////// 353 259 unsigned int _hba_init( unsigned int channel ) 354 260 { … … 381 287 if ( fail ) 382 288 { 383 _p rintf("[GIET ERROR] in _hba_init() : command list unmapped\n");384 return 1;289 _puts("[GIET ERROR] in _hba_init() : command list unmapped\n"); 290 return -1; 385 291 } 386 292 hba_cmd_list_paddr[channel] = ((paddr_t)ppn) | (vbase & 0xFFF); … … 396 302 if ( fail ) 397 303 { 398 _p rintf("[GIET ERROR] in _hba_init() : command table unmapped\n");399 return 1;304 _puts("[GIET ERROR] in _hba_init() : command table unmapped\n"); 305 return -1; 400 306 } 401 307 hba_cmd_table_paddr[channel][c] = ((paddr_t)ppn) | (vbase & 0xFFF); … … 405 311 } 406 312 407 /////////////////////////////////////////////////////////////////////////////// 408 // _hba_get_block_size() 409 // This function returns the block_size of HBA controller 410 /////////////////////////////////////////////////////////////////////////////// 313 /////////////////////////////////////////////// 314 unsigned int _hba_write( unsigned int channel, 315 unsigned int mode, 316 unsigned int lba, 317 paddr_t buffer, 318 unsigned int count ) 319 { 320 return _hba_cmd_set( channel, 321 0, // write 322 lba, 323 buffer, 324 count ); 325 } 326 327 ////////////////////////////////////////////// 328 unsigned int _hba_read( unsigned int channel, 329 unsigned int mode, 330 unsigned int lba, 331 paddr_t buffer, 332 unsigned int count ) 333 { 334 return _hba_cmd_set( channel, 335 1, // read 336 lba, 337 buffer, 338 count ); 339 } 340 341 ////////////////////////////////// 411 342 unsigned int _hba_get_block_size() 412 343 { … … 415 346 } 416 347 417 ///////////////////////////////////////////////////////////////////////////////////// 418 // This function returns the content of the HBA_PXIS register for a given channel, 419 // and reset this register to acknoledge IRQ. 420 // return 0 if success, > 0 if error 421 ///////////////////////////////////////////////////////////////////////////////////// 348 //////////////////////////////////////////////////// 422 349 unsigned int _hba_get_status( unsigned int channel ) 423 350 { … … 425 352 if( channel >= NB_IOC_CHANNELS ) 426 353 { 427 _p rintf("\n[GIET ERROR] in _hba_get_status() : illegal channel\n");354 _puts("\n[GIET ERROR] in _hba_get_status() : illegal channel\n"); 428 355 _exit(); 429 356 } -
soft/giet_vm/giet_drivers/hba_driver.h
r295 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The hba_driver.c and hba_driver.h files are part ot the GIET-VM kernel. 8 // This driver supports the SocLib VciMultiAhci component, that is a multi-channels, 9 // block oriented, external storage contrÃŽler, respecting the AHCI standard. 10 // 11 // The SEG_IOC_BASE virtual address must be defined in the hard_config.h file. 12 ////////////////////////////////////////////////////////////////////////////////// 7 13 8 14 #ifndef _GIET_HBA_DRIVERS_H_ … … 94 100 95 101 /////////////////////////////////////////////////////////////////////////////////// 96 // HBA device access functions (vci_hba)102 // access functions 97 103 /////////////////////////////////////////////////////////////////////////////////// 98 104 105 /////////////////////////////////////////////////////////////////////////////////// 106 // This function initializes for a given channel 107 // - the HBA hardware registers, 108 // - the command list pointer, 109 // - the command lists physical addresse, 110 // - the command tables physical addresses array, 111 /////////////////////////////////////////////////////////////////////////////////// 99 112 extern unsigned int _hba_init ( unsigned int channel ); 100 113 114 /////////////////////////////////////////////////////////////////////////////////// 115 // This function register a write command in Command List and Command Table 116 // for a single physical buffer, and updates the HBA_PXCI register. 117 // Returns 0 if success, > 0 if error. 118 /////////////////////////////////////////////////////////////////////////////////// 101 119 extern unsigned int _hba_write( unsigned int channel, // channel index 102 120 unsigned int mode, // BOOT / KERNEL / USER … … 105 123 unsigned int count ); // number of blocs 106 124 125 ////////////////////////////////////////////////////////////////////////////////// 126 // This function register a read command in Command List and Command Table 127 // for a single physical buffer, and updates the HBA_PXCI register. 128 // Returns 0 if success, > 0 if error. 129 ////////////////////////////////////////////////////////////////////////////////// 107 130 extern unsigned int _hba_read ( unsigned int channel, // channel index 108 131 unsigned int mode, // BOOT / KERNEL / USER … … 111 134 unsigned int count ); // number of blocks 112 135 136 ///////////////////////////////////////////////////////////////////////////////// 137 // This function returns the block_size of HBA controller 138 ///////////////////////////////////////////////////////////////////////////////// 139 extern unsigned int _hba_get_block_size (); 140 141 ///////////////////////////////////////////////////////////////////////////////////// 142 // This function returns the content of the HBA_PXIS register for a given channel, 143 // and reset this register to acknoledge IRQ. 144 // return 0 if success, > 0 if error 145 ///////////////////////////////////////////////////////////////////////////////////// 113 146 extern unsigned int _hba_get_status( unsigned int channel ); 114 115 extern unsigned int _hba_get_block_size ();116 147 117 148 -
soft/giet_vm/giet_drivers/iob_driver.c
r340 r437 4 4 // Author : alain greiner 5 5 // Copyright (c) UPMC-LIP6 6 ///////////////////////////////////////////////////////////////////////////////////7 // The iob_driver.c and iob_driver.h files are part ot the GIET-VM kernel.8 // This driver supports the TSAR vci_io_bridge, that is a bridge to access9 // The external peripherals, implementing an IO_MMU.10 // This component can be instanciated in more than one cluster.11 ///////////////////////////////////////////////////////////////////////////////////12 // The SEG_IOB_BASE virtual addresses must be defined in hard_config.h file.13 // The physical base address is supposed to be (cluster_xy << 32) | SEG_IOB_BASE.14 6 /////////////////////////////////////////////////////////////////////////////////// 15 7 … … 61 53 62 54 63 /////////////////////////////////////////////////////////////////////////////// 64 // This function invalidates a TLB entry identified by a virtual address. 65 /////////////////////////////////////////////////////////////////////////////// 55 56 /////////////////////////////////////////////////// 66 57 void _iob_inval_tlb_entry( unsigned int cluster_xy, 67 58 unsigned int vaddr ) … … 72 63 } 73 64 74 /////////////////////////////////////////////////////////////////////////////// 75 // This function sets a new value in IOB_IOMMU_PTPR register. 76 /////////////////////////////////////////////////////////////////////////////// 65 ////////////////////////////////////////////////// 77 66 void _iob_set_iommu_ptpr( unsigned int cluster_xy, 78 67 unsigned int value ) -
soft/giet_vm/giet_drivers/iob_driver.h
r340 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The iob_driver.c and iob_driver.h files are part ot the GIET-VM kernel. 8 // This driver supports the TSAR vci_io_bridge, that is a bridge to access 9 // The external peripherals, implementing an IO_MMU. 10 // The SEG_IOB_BASE virtual addresses must be defined in hard_config.h file. 11 // The physical base address is (cluster_io << 32) | SEG_IOB_BASE. 12 /////////////////////////////////////////////////////////////////////////////////// 7 13 8 14 #ifndef _GIET_IOB_DRIVER_H_ … … 10 16 11 17 /////////////////////////////////////////////////////////////////////////////////// 12 // vci_io_bridge :registers offsets and iommu error codes18 // registers offsets and iommu error codes 13 19 /////////////////////////////////////////////////////////////////////////////////// 14 20 … … 40 46 41 47 /////////////////////////////////////////////////////////////////////////////////// 42 // TSAR IOBaccess functions48 // access functions 43 49 /////////////////////////////////////////////////////////////////////////////////// 44 50 51 /////////////////////////////////////////////////////////////////////////////// 52 // This function invalidates a TLB entry identified by a virtual address. 53 /////////////////////////////////////////////////////////////////////////////// 45 54 extern void _iob_inval_tlb_entry( unsigned int cluster_xy, 46 55 unsigned int vaddr ); 47 56 57 /////////////////////////////////////////////////////////////////////////////// 58 // This function sets a new value in IOB_IOMMU_PTPR register. 59 /////////////////////////////////////////////////////////////////////////////// 48 60 extern void _iob_set_iommu_ptpr( unsigned int cluster_xy, 49 61 unsigned int value ); 50 62 51 /////////////////////////////////////////////////////////////////////////////////// 63 52 64 53 65 #endif -
soft/giet_vm/giet_drivers/ioc_driver.c
r426 r437 6 6 // Copyright (c) UPMC-LIP6 7 7 /////////////////////////////////////////////////////////////////////////////////// 8 // Implementation note: 9 // 8 // Implementation notes: 10 9 // 1) In order to share the code, the two _ioc_read() and _ioc_write() functions 11 // call the same _ioc_access() function .12 // 10 // call the same _ioc_access() function, and this function call the selected 11 // physical driver (BDV / HBA / SPI / RDK). 13 12 // 2) The IOMMU is not supported yet, but the method is the following: 14 13 // A fixed size 2 Mbytes vseg is allocated to the IOC peripheral, in the I/O … … 97 96 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 98 97 unsigned int p = procid & ((1<<P_WIDTH)-1); 99 _printf("\n[IOC DEBUG] _ioc_access() : P[%d,%d,%d] enters at cycle %d\n" 100 " - channel = %d\n" 101 " - mode = %d\n" 102 " - vaddr = %x\n" 103 " - sectors = %d\n" 104 " - lba = %x\n", 105 x, y, p, _get_proctime(), channel, mode, buf_vaddr, count, lba ); 98 _puts("\n[IOC DEBUG] _ioc_access() : P["); 99 _putd( x ); 100 _puts(","); 101 _putd( y ); 102 _puts(","); 103 _putd( p ); 104 _puts("] enters at cycle "); 105 _putd( _get_proctime() ); 106 _puts("\n - channel = "); 107 _putd( channel ); 108 _puts("\n - mode = "); 109 _putd( mode ); 110 _puts("\n - vaddr = "); 111 _putx( buf_vaddr ); 112 _puts("\n - sectors = "); 113 _putd( count ); 114 _puts("\n - lba = "); 115 _putx( lba ); 116 _puts("\n"); 106 117 #endif 107 118 … … 115 126 if ((unsigned int) buf_vaddr & 0x3) 116 127 { 117 _p rintf("\n[IOC ERROR] in _ioc_access() : buffer not word aligned\n");128 _puts("\n[IOC ERROR] in _ioc_access() : buffer not word aligned\n"); 118 129 _exit(); 119 130 } … … 122 133 if ( (USE_IOC_HBA == 0) && (channel > 0) ) 123 134 { 124 _p rintf("\n[IOC ERROR] in _ioc_access() : channel must be 0 when HBA not used\n");135 _puts("\n[IOC ERROR] in _ioc_access() : channel must be 0 when HBA not used\n"); 125 136 _exit(); 126 137 } … … 146 157 if ( ko ) 147 158 { 148 _p rintf("\n[IOC ERROR] in _ioc_access() : buffer unmapped\n");159 _puts("\n[IOC ERROR] in _ioc_access() : buffer unmapped\n"); 149 160 _exit(); 150 161 } … … 152 163 if ( (mode == IOC_USER_MODE) && ((flags & PTE_U) == 0) ) 153 164 { 154 _p rintf("\n[IOC ERROR] in _ioc_access() : buffer not user accessible\n");165 _puts("\n[IOC ERROR] in _ioc_access() : buffer not user accessible\n"); 155 166 _exit(); 156 167 } … … 158 169 if ( ((flags & PTE_W) == 0 ) && to_mem ) 159 170 { 160 _p rintf("\n[IOC ERROR] in _ioc_access() : buffer not writable\n");171 _puts("\n[IOC ERROR] in _ioc_access() : buffer not writable\n"); 161 172 _exit(); 162 173 } … … 274 285 #elif ( USE_IOC_RDK ) 275 286 276 _printf("[GIET ERROR] _ioc_get_status() should not be called"); 277 _printf(" when RAMDISK is used...\n"); 278 _exit(); 279 280 return 0; 287 return rdk_get_status(); 281 288 282 289 #endif -
soft/giet_vm/giet_drivers/ioc_driver.h
r413 r437 18 18 // USE_IOC_BDV, USE_IOC_SDC, USE_IOC_HBA, USE_IOC_RDK. 19 19 // 20 // Any physical block device driver xxx must provide the following API: 21 // - _xxx_init() 22 // - _xxx_read() 23 // - _xxx_write() 24 // - _xxx_get_status() 25 // - _xxx_get_block_size() 26 // The "channel" parameter is no transmited to single channel devices. 20 // Any physical block device driver must provide the 5 five functions defined 21 // by this generic driver. 27 22 // 28 23 // The _ioc_read() and _ioc_write() functions are always blocking for … … 67 62 // If the RAMDISK is used, an extra memory segment with virtual base address 68 63 // SEG_RDK_BASE, used by RDK driver, must be defined in hard_config.h. 69 ///////////////////////////////////////////////////////////////////////////////////70 // Implementation note:71 64 // 72 // 1) In order to share the code, the two _ioc_read() and _ioc_write() functions 73 // call the same _ioc_access() function. 74 // 75 // 2) The IOMMU is not supported yet, but the method is the following: 65 // The IOMMU is not supported yet, but the method is the following: 76 66 // A fixed size 2 Mbytes vseg is allocated to the IOC peripheral, in the I/O 77 67 // virtual space, and the user buffer is dynamically remapped to one single … … 103 93 104 94 /////////////////////////////////////////////////////////////////////////////////// 105 // IOC access functions (generic disk controller)95 // External functions 106 96 /////////////////////////////////////////////////////////////////////////////////// 107 97 108 98 /////////////////////////////////////////////////////////////////////////////// 109 // This function cheks block size, and desactivates the IOCinterrupts.99 // This function cheks block size, and desactivates interrupts. 110 100 // Return 0 for success, non zero if error. 111 101 /////////////////////////////////////////////////////////////////////////////// … … 113 103 114 104 /////////////////////////////////////////////////////////////////////////////// 115 // Transfer data from a memory buffer to the block device.116 // - mode : BOOT _PA / BOOT_VA/ KERNEL / USER105 // Transfer data from a memory buffer to the disk. 106 // - mode : BOOT / KERNEL / USER 117 107 // - lba : first block index on the block device 118 108 // - buffer : base address of the memory buffer (must be word aligned) … … 127 117 128 118 /////////////////////////////////////////////////////////////////////////////// 129 // Transfer data from the block deviceto a memory buffer.130 // - mode : BOOT _PA / BOOT_VA/ KERNEL / USER119 // Transfer data from the disk to a memory buffer. 120 // - mode : BOOT / KERNEL / USER 131 121 // - lba : first block index on the block device 132 122 // - buffer : base address of the memory buffer (must be word aligned) … … 142 132 /////////////////////////////////////////////////////////////////////////////// 143 133 // This function returns in the status variable, the transfert status, and 144 // acknowledge the IRQ if the IOC controler is not busy.134 // acknowledge the IRQ if required. 145 135 // Returns 0 if success, > 0 if error 146 136 /////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_drivers/mmc_driver.c
r426 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The mmc_driver.c and mmc_driver.h files are part ot the GIET-VM nano-kernel.8 // This driver supports the vci_mem_cache component used in the TSAR architecture.9 //10 // This component is replicated in all clusters, and can be accessed through11 // a configuration interface as a set of uncached, memory mapped registers.12 //13 // The (virtual) base address of the associated segment is:14 // SEG_MMC_BASE + cluster_id * PERI_CLUSTER_INCREMENT15 //16 // SEG_MMC_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h.17 ////////////////////////////////////////////////////////////////////////////////18 7 19 8 #include <giet_config.h> … … 82 71 } 83 72 84 /////////////////////////////////////////////////////////////////////////////////// 85 // This function invalidates all cache lines covering a memory buffer defined 86 // by the physical base address, and the length. 87 // The buffer address MSB are used to compute the cluster index. 88 /////////////////////////////////////////////////////////////////////////////////// 73 ///////////////////////////////////////// 89 74 void _mmc_inval( paddr_t buf_paddr, 90 75 unsigned int buf_length ) … … 98 83 if ( (x >= X_SIZE) || (y >= Y_SIZE) ) 99 84 { 100 _printf("\n[GIET ERROR] in _memc_inval() : illegal cluster_xy for paddr %l\n", 101 buf_paddr ); 85 _puts("\n[GIET ERROR] in _memc_inval() : illegal cluster coordinates\n"); 102 86 _exit(); 103 87 } … … 115 99 _mmc_set_register(cluster_xy, 0, MEMC_LOCK, 0); 116 100 } 117 /////////////////////////////////////////////////////////////////////////////////// 118 // This function copies to external RAM all cache lines covering a memory buffer 119 // defined by the physical base address, and the length, if they are dirty. 120 // The buffer address MSB are used to compute the cluster index. 121 /////////////////////////////////////////////////////////////////////////////////// 101 102 /////////////////////////////////////// 122 103 void _mmc_sync( paddr_t buf_paddr, 123 104 unsigned int buf_length ) … … 131 112 if ( (x >= X_SIZE) || (y >= Y_SIZE) ) 132 113 { 133 _printf( "\n[GIET ERROR] in _memc_sync() : illegal cluster_xy for paddr %l\n", 134 buf_paddr ); 114 _puts( "\n[GIET ERROR] in _memc_sync() : illegal cluster coordinates"); 135 115 _exit(); 136 116 } … … 149 129 } 150 130 151 ////////////////////////////////////////////////////////////////////////////////// 152 // This ISR access the vci_mem_cache component to get the faulty physical 153 // address and the associated SRCID. It must also acknowledge the IRQ. 154 // 155 // TODO implement... 156 ////////////////////////////////////////////////////////////////////////////////// 131 /////////////////////////////////////////////////////// 157 132 void _mmc_isr( unsigned int irq_type, // should be HWI 158 133 unsigned int irq_id, // index returned by ICU … … 163 138 unsigned int x = cluster_xy >> Y_WIDTH; 164 139 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 165 unsigned int lpid= gpid & ((1<<P_WIDTH)-1);140 unsigned int p = gpid & ((1<<P_WIDTH)-1); 166 141 167 _printf("[GIET ERROR] MMC IRQ received by processor[%d,%d,%d]" 168 " but _mmc_isr() not implemented...\n", x, y, lpid ); 142 _puts("[GIET ERROR] MMC IRQ received by processor["); 143 _putd( x ); 144 _puts(","); 145 _putd( y ); 146 _puts(","); 147 _putd( p ); 148 _puts("] but _mmc_isr() not implemented\n"); 169 149 } 170 150 -
soft/giet_vm/giet_drivers/mwr_driver.c
r333 r437 63 63 paddr_t channel_pbase ) 64 64 { 65 _p rintf(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n");65 _puts(" [GIET_ERROR] _mwr_hw_init() function not supported yet\n"); 66 66 _exit(); 67 67 -
soft/giet_vm/giet_drivers/nic_driver.c
r333 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The nic_driver.c and nic_driver.h files are part ot the GIET-VM nano-kernel.8 // This driver supports the vci_multi_nic component.9 //10 // It can exist only one network controller in the architecture, but this11 // component supports several channels.12 //13 // It can be accessed directly by software with memcpy(),14 // or it can be accessed through the vci_chbuf_dma component:15 //16 // The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to17 // implement the transfer between a data buffer (user space) and the NIC18 // buffer (kernel space). They are blocking until completion of the transfer.19 //20 // The _nic_cma_*_init() and _nic_cma_stop() functions use the VciChbufDma component21 // to transfer a flow of packets from the NIC RX hard chbuf (two containers)22 // to an user RX chbuf (two containers), and to transfer another flow of packets23 // from an user TX chbuf (two containers) to the NIC TX chbuf (two containers).24 // One NIC channel and two CMA channels must be allocated to the task25 // in the mapping_info data structure.26 //27 // The SEG_NIC_BASE address must be defined in the hard_config.h file.28 //////////////////////////////////////////////////////////////////////////////////29 7 30 8 #include <giet_config.h> 31 9 #include <nic_driver.h> 10 #include <cma_driver.h> 32 11 #include <utils.h> 12 #include <ctx_handler.h> 13 #include <vmem.h> 33 14 34 15 #if !defined(GIET_USE_IOMMU) … … 44 25 #endif 45 26 27 #if !defined(X_IO) 28 # error: You must define X_IO in the hard_config.h file 29 #endif 30 31 #if !defined(Y_IO) 32 # error: You must define Y_IO in the hard_config.h file 33 #endif 34 46 35 #if ( NB_NIC_CHANNELS > 8 ) 47 36 # error: NB_NIC_CHANNELS cannot be larger than 8 … … 60 49 #endif 61 50 51 #if !defined( GIET_CHBUF_NBUFS ) 52 # error: You must define GIET_CHBUF_NBUFS in the giet_config.h file 53 #endif 54 62 55 #define in_unckdata __attribute__((section (".unckdata"))) 63 56 64 57 /////////////////////////////////////////////////////////////////////////////// 65 // This low_level function returns the value contained in register (index).66 /////////////////////////////////////////////////////////////////////////////// 67 unsigned int _nic_get_ register( unsigned int channel,68 unsigned int index )58 // This low_level function returns the value contained in a channel register. 59 /////////////////////////////////////////////////////////////////////////////// 60 unsigned int _nic_get_channel_register( unsigned int channel, 61 unsigned int index ) 69 62 { 70 63 unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + … … 74 67 75 68 /////////////////////////////////////////////////////////////////////////////// 76 // This low-level function set a new value in register (index).77 /////////////////////////////////////////////////////////////////////////////// 78 void _nic_set_ register( unsigned int channel,79 unsigned int index,80 unsigned int value )69 // This low-level function set a new value in a channel register. 70 /////////////////////////////////////////////////////////////////////////////// 71 void _nic_set_channel_register( unsigned int channel, 72 unsigned int index, 73 unsigned int value ) 81 74 { 82 75 unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + … … 85 78 } 86 79 87 ////////////////////////////////////////////////////////////////////////////////// 88 // Transfer data from an memory buffer to the NIC device using a memcpy. 89 // - buffer : base address of the memory buffer. 90 // - length : number of bytes to be transfered. 91 ////////////////////////////////////////////////////////////////////////////////// 92 unsigned int _nic_sync_write( const void* buffer, 93 unsigned int length ) 94 { 95 _printf("[GIET ERROR] _nic_sync_write function not implemented / cycle %d\n", 96 _get_proctime() ); 97 _exit(); 98 99 return 0; 100 } 101 ////////////////////////////////////////////////////////////////////////////////// 102 // Transfer data from the NIC device to a memory buffer using a memcpy. 103 // - buffer : base address of the memory buffer. 104 // - length : number of bytes to be transfered. 105 ////////////////////////////////////////////////////////////////////////////////// 106 unsigned int _nic_sync_read( const void* buffer, 107 unsigned int length ) 108 { 109 _printf("[GIET ERROR] _nic_sync_read function not implemented / cycle %d\n", 110 _get_proctime() ); 111 _exit(); 112 113 return 0; 114 } 115 ////////////////////////////////////////////////////////////////////////////////// 116 // Returns 0 if success, > 0 if error. 117 ////////////////////////////////////////////////////////////////////////////////// 118 unsigned int _nic_cma_start( ) 119 { 120 _printf("[GIET ERROR] _nic_cma_start() not implemented / cycle %d\n", 121 _get_proctime() ); 122 _exit(); 123 124 return 0; 125 } 126 ////////////////////////////////////////////////////////////////////////////////// 127 // Returns 0 if success, > 0 if error. 128 ////////////////////////////////////////////////////////////////////////////////// 129 unsigned int _nic_cma_stop() 130 { 131 _printf("[GIET ERROR] _nic_cma_stop() not implemented / cycle %d\n", 132 _get_proctime() ); 133 _exit(); 134 135 return 0; 136 } 137 138 ////////////////////////////////////////////////////////////////////////////////// 139 // This ISR handles IRQx from a NIC RX channeL 140 ////////////////////////////////////////////////////////////////////////////////// 80 /////////////////////////////////////////////////////////////////////////////// 81 // This low_level function returns the value contained in a global register. 82 /////////////////////////////////////////////////////////////////////////////// 83 unsigned int _nic_get_global_register( unsigned int index ) 84 { 85 unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 86 NIC_CHANNEL_SPAN * NB_NIC_CHANNELS + index; 87 return _io_extended_read( vaddr ); 88 } 89 90 /////////////////////////////////////////////////////////////////////////////// 91 // This low-level function set a new value in a global register. 92 /////////////////////////////////////////////////////////////////////////////// 93 void _nic_set_global_register( unsigned int index, 94 unsigned int value ) 95 { 96 unsigned int* vaddr = (unsigned int*)SEG_NIC_BASE + 97 NIC_CHANNEL_SPAN * NB_NIC_CHANNELS + index; 98 _io_extended_write( vaddr, value ); 99 } 100 101 //////////////////////////////////////////// 102 int _nic_global_init( unsigned int channels, 103 unsigned int vis, 104 unsigned int bc_enable, 105 unsigned int bypass_enable ) 106 { 107 _nic_set_global_register( NIC_G_VIS , vis ); 108 _nic_set_global_register( NIC_G_NB_CHAN , channels ); 109 _nic_set_global_register( NIC_G_BC_ENABLE , bc_enable ); 110 _nic_set_global_register( NIC_G_BYPASS_ENABLE, bypass_enable ); 111 _nic_set_global_register( NIC_G_ON , 1 ); 112 113 return 0; 114 } 115 116 //////////////////////////////////////////// 117 int _nic_channel_init( unsigned int index, 118 unsigned int mac4, 119 unsigned int mac2 ) 120 { 121 unsigned int base = SEG_NIC_BASE; 122 unsigned int extend = (X_IO << Y_WIDTH) + Y_IO; 123 124 _nic_set_channel_register( index, NIC_RX_DESC_LO_0 + 4096, base ); 125 _nic_set_channel_register( index, NIC_RX_DESC_LO_1 + 4096, base + 0x1000 ); 126 _nic_set_channel_register( index, NIC_TX_DESC_LO_0 + 4096, base + 0x2000 ); 127 _nic_set_channel_register( index, NIC_TX_DESC_LO_1 + 4096, base + 0x3000 ); 128 129 _nic_set_channel_register( index, NIC_RX_DESC_HI_0 , extend ); 130 _nic_set_channel_register( index, NIC_RX_DESC_HI_1 , extend ); 131 _nic_set_channel_register( index, NIC_TX_DESC_HI_0 , extend ); 132 _nic_set_channel_register( index, NIC_TX_DESC_HI_1 , extend ); 133 134 _nic_set_channel_register( index, NIC_MAC_4 , mac4 ); 135 _nic_set_channel_register( index, NIC_MAC_2 , mac2 ); 136 137 _nic_set_channel_register( index, NIC_RX_RUN , 1 ); 138 _nic_set_channel_register( index, NIC_TX_RUN , 1 ); 139 140 return 0; 141 } 142 143 ///////////////////////////////////////////////////////////////////////////////////// 144 // Synchronous access functions 145 ///////////////////////////////////////////////////////////////////////////////////// 146 147 /////////////////////////////////////////////// 148 int _nic_sync_send( unsigned int channel, 149 unsigned long long user_paddr ) 150 { 151 unsigned long long nic_paddr; // nic buffer physical address 152 unsigned int done = 0; 153 unsigned int lsb; 154 unsigned int msb; 155 156 if ( channel >= NB_NIC_CHANNELS ) 157 { 158 _puts("[GIET ERROR] in _timer_sync_send()\n"); 159 return -1; 160 } 161 162 // poll the NIC buffers 163 while ( done == 0 ) 164 { 165 // test availability of NIC TX buffer 0 166 lsb = _nic_get_channel_register( channel, NIC_TX_DESC_LO_0 ); 167 msb = _nic_get_channel_register( channel, NIC_TX_DESC_HI_0 ); 168 if ( (msb & 0x80000000) == 0 ) 169 { 170 msb = msb & 0x0000FFFF; 171 done = 1; 172 continue; 173 } 174 175 // test availability of NIC TX buffer 1 176 lsb = _nic_get_channel_register( channel, NIC_TX_DESC_LO_1 ); 177 msb = _nic_get_channel_register( channel, NIC_TX_DESC_HI_1 ); 178 if ( (msb & 0x80000000) == 0 ) 179 { 180 msb = msb & 0x0000FFFF; 181 done = 1; 182 continue; 183 } 184 185 // random delay (average value: 380 cycle) 186 _random_wait( 8 ); 187 } 188 189 // make the transfer 190 nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32); 191 192 _physical_memcpy( nic_paddr , user_paddr, 4096 ); 193 194 return 0; 195 } 196 197 /////////////////////////////////////////////////// 198 int _nic_sync_receive( unsigned int channel, 199 unsigned long long user_paddr ) 200 { 201 unsigned long long nic_paddr; // nic buffer physical address 202 unsigned int done = 0; 203 unsigned int lsb; 204 unsigned int msb; 205 206 if ( channel >= NB_NIC_CHANNELS ) 207 { 208 _puts("[GIET ERROR] in _timer_sync_receive()\n"); 209 return -1; 210 } 211 212 // polling the NIC buffers 213 while ( done == 0 ) 214 { 215 // test availability of NIC RX buffer 0 216 lsb = _nic_get_channel_register( channel, NIC_RX_DESC_LO_0 ); 217 msb = _nic_get_channel_register( channel, NIC_RX_DESC_HI_0 ); 218 if ( (msb & 0x80000000) == 1 ) 219 { 220 msb = msb & 0x0000FFFF; 221 done = 1; 222 continue; 223 } 224 225 // test availability of NIC RX buffer 1 226 lsb = _nic_get_channel_register( channel, NIC_RX_DESC_LO_1 ); 227 msb = _nic_get_channel_register( channel, NIC_RX_DESC_HI_1 ); 228 if ( (msb & 0x80000000) == 1 ) 229 { 230 msb = msb & 0x0000FFFF; 231 done = 1; 232 continue; 233 } 234 235 // random delay (average value: 380 cycle) 236 _random_wait( 8 ); 237 } 238 239 // make the transfer 240 nic_paddr = (unsigned long long)lsb + (((unsigned long long)msb) << 32); 241 242 _physical_memcpy( user_paddr, nic_paddr , 4096 ); 243 244 return 0; 245 } 246 247 ///////////////////////////////////////////////////////////////////////////////////// 248 // CMA access functions 249 ///////////////////////////////////////////////////////////////////////////////////// 250 251 ////////////////////////////////////////////////////////////// 252 int _nic_cma_receive( unsigned int nic_channel, 253 unsigned int cma_channel, 254 nic_chbuf_t* kernel_chbuf ) 255 256 { 257 unsigned int nic_chbuf_lsb; // 32 LSB bits of the NIC chbuf physical address 258 unsigned int nic_chbuf_msb; // 16 MSB bits of the NIC chbuf physical address 259 unsigned int mem_chbuf_lsb; // 32 LSB bits of the kernel chbuf physical address 260 unsigned int mem_chbuf_msb; // 16 MSB bits of the kernel chbuf physical address 261 262 unsigned int ppn; 263 unsigned int flags; 264 265 // checking parameters 266 if ( nic_channel >= NB_NIC_CHANNELS ) 267 { 268 _puts("[GIET ERROR] in _nic_cma_start_receive() : nic_channel index too large\n"); 269 return -1; 270 } 271 if ( cma_channel >= NB_CMA_CHANNELS ) 272 { 273 _puts("[GIET ERROR] in _nic_cma_start_receive() : cma_channel index too large\n"); 274 return -1; 275 } 276 277 // get the NIC_RX chbuf descriptor physical address 278 nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1000; 279 nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO; 280 281 // compute the kernel chbuf physical address 282 unsigned int ptab = _get_context_slot(CTX_PTAB_ID); 283 unsigned int vaddr = (unsigned int)kernel_chbuf; 284 unsigned int ko = _v2p_translate( (page_table_t*)ptab, 285 vaddr, 286 &ppn, 287 &flags ); 288 if ( ko ) 289 { 290 _puts("\n[GIET ERROR] in _nic_cma_start_receive() : kernel buffer unmapped\n"); 291 return -1; 292 } 293 294 mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF); 295 mem_chbuf_msb = ppn >> 20; 296 297 // initializes CMA registers defining the source chbuf (NIC_RX) 298 _cma_set_register( cma_channel, CHBUF_SRC_DESC , nic_chbuf_lsb ); 299 _cma_set_register( cma_channel, CHBUF_DST_EXT , nic_chbuf_msb ); 300 _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 ); 301 302 // initializes CMA registers defining the destination chbuf (kernel memory) 303 _cma_set_register( cma_channel, CHBUF_DST_DESC , mem_chbuf_lsb ); 304 _cma_set_register( cma_channel, CHBUF_DST_EXT , mem_chbuf_msb ); 305 _cma_set_register( cma_channel, CHBUF_DST_NBUFS, GIET_CHBUF_NBUFS ); 306 307 // set buffer size, polling period, and start 308 _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 ); 309 _cma_set_register( cma_channel, CHBUF_PERIOD , 300 ); 310 _cma_set_register( cma_channel, CHBUF_RUN , 1 ); 311 312 return 0; 313 } 314 315 ////////////////////////////////////////////////////////// 316 int _nic_cma_send( unsigned int nic_channel, 317 unsigned int cma_channel, 318 nic_chbuf_t* kernel_chbuf ) 319 { 320 unsigned int nic_chbuf_lsb; // 32 LSB bits of the NIC chbuf physical address 321 unsigned int nic_chbuf_msb; // 16 MSB bits of the NIC chbuf physical address 322 unsigned int mem_chbuf_lsb; // 32 LSB bits of the kernel chbuf physical address 323 unsigned int mem_chbuf_msb; // 16 MSB bits of the kernel chbuf physical address 324 325 unsigned int ppn; 326 unsigned int flags; 327 328 // checking parameters 329 if ( nic_channel >= NB_NIC_CHANNELS ) 330 { 331 _puts("[GIET ERROR] in _nic_cma_start_send() : nic_channel index too large\n"); 332 return -1; 333 } 334 if ( cma_channel >= NB_CMA_CHANNELS ) 335 { 336 _puts("[GIET ERROR] in _nic_cma_start_send() : cma_channel index too large\n"); 337 return -1; 338 } 339 340 // get the NIC_TX chbuf descriptor physical address 341 nic_chbuf_lsb = SEG_NIC_BASE + (nic_channel * NIC_CHANNEL_SPAN) + 0x1010; 342 nic_chbuf_msb = (X_IO << Y_WIDTH) + Y_IO; 343 344 // compute the kernel chbuf physical address 345 unsigned int ptab = _get_context_slot(CTX_PTAB_ID); 346 unsigned int vaddr = (unsigned int)kernel_chbuf; 347 unsigned int ko = _v2p_translate( (page_table_t*)ptab, 348 vaddr, 349 &ppn, 350 &flags ); 351 if ( ko ) 352 { 353 _puts("\n[GIET ERROR] in _nic_cma_start_send() : kernel buffer unmapped\n"); 354 return -1; 355 } 356 357 mem_chbuf_lsb = (ppn << 12) | (vaddr & 0x00000FFF); 358 mem_chbuf_msb = ppn >> 20; 359 360 // initializes CMA registers defining the source chbuf (kernel memory) 361 _cma_set_register( cma_channel, CHBUF_SRC_DESC , mem_chbuf_lsb ); 362 _cma_set_register( cma_channel, CHBUF_DST_EXT , mem_chbuf_msb ); 363 _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, GIET_CHBUF_NBUFS ); 364 365 // initializes CMA registers defining the destination chbuf (NIC_TX) 366 _cma_set_register( cma_channel, CHBUF_DST_DESC , nic_chbuf_lsb ); 367 _cma_set_register( cma_channel, CHBUF_DST_EXT , nic_chbuf_msb ); 368 _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 ); 369 370 // set buffer size, polling period, and start 371 _cma_set_register( cma_channel, CHBUF_BUF_SIZE , 4096 ); 372 _cma_set_register( cma_channel, CHBUF_PERIOD , 300 ); 373 _cma_set_register( cma_channel, CHBUF_RUN , 1 ); 374 375 return 0; 376 } 377 378 //////////////////////////////////////////////////////////////////////////////////////////// 379 // Interrupt Service Routines 380 //////////////////////////////////////////////////////////////////////////////////////////// 381 382 //////////////////////////////////////// 141 383 void _nic_rx_isr( unsigned int irq_type, 142 384 unsigned int irq_id, 143 385 unsigned int channel ) 144 386 { 145 _printf("[GIET ERROR] _nic_rx_isr() not implemented / cycle %d\n", 146 _get_proctime() ); 147 _exit(); 148 } 149 150 ////////////////////////////////////////////////////////////////////////////////// 151 // This ISR handles IRQx from a NIC RX channeL 152 ////////////////////////////////////////////////////////////////////////////////// 387 _puts("[NIC WARNING] RX buffers are full for NIC channel "); 388 _putd( channel ); 389 _puts("\n"); 390 } 391 392 //////////////////////////////////////// 153 393 void _nic_tx_isr( unsigned int irq_type, 154 394 unsigned int irq_id, 155 395 unsigned int channel ) 156 396 { 157 _p rintf("[GIET ERROR] _nic_tx_isr() not implemented / cycle %d\n",158 _get_proctime());159 _ exit();397 _puts("[NIC WARNING] TX buffers are full for NIC channel "); 398 _putd( channel ); 399 _puts("\n"); 160 400 } 161 401 -
soft/giet_vm/giet_drivers/nic_driver.h
r295 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The nic_driver.c and nic_driver.h files are part ot the GIET-VM nano-kernel. 8 // This driver supports the vci_multi_nic component. 9 // 10 // It can exist only one network controller in the architecture, but this 11 // component supports several channels. 12 // 13 // It can be accessed directly by software with memcpy(), 14 // or it can be accessed through the vci_chbuf_dma component: 15 // 16 // The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to 17 // implement the transfer between a data buffer (user space) and the NIC 18 // buffer (kernel space). They are blocking until completion of the transfer. 19 // 20 // The _nic_cma_start() and _nic_cma_stop() functions use the VciChbufDma component 21 // to transfer a flow of packets from the NIC RX hard chbuf (two containers) 22 // to an user RX chbuf (two containers), and to transfer another flow of packets 23 // from an user TX chbuf (two containers) to the NIC TX chbuf (two containers). 24 // One NIC channel and two CMA channels must be allocated to the task 25 // in the mapping_info data structure. 26 // 27 // All these access functions return -1 in case of error. 28 // 29 // The SEG_NIC_BASE address must be defined in the hard_config.h file. 30 ////////////////////////////////////////////////////////////////////////////////// 7 31 8 32 #ifndef _GIET_NIC_DRIVERS_H_ 9 33 #define _GIET_NIC_DRIVERS_H_ 10 34 35 #include <giet_config.h> 36 11 37 /////////////////////////////////////////////////////////////////////////////////// 12 // NIC Registers (vci_multi_nic)38 // Global Addressable Registers 13 39 /////////////////////////////////////////////////////////////////////////////////// 14 40 … … 50 76 }; 51 77 52 ///////////////////////////////////////////////////////////////////// 78 ///////////////////////////////////////////////////////////////////////////////////// 79 // Channel Addressable Registers 53 80 // A container descriptor has the following form: 54 // LOW WORD : Container LSB base address 55 // HIGH WORD: Container status (leftmost bit), '1' means full 56 // Base address MSB extension, if needed (right aligned) 57 ////////////////////////////////////////////////////////////////////// 81 // LOW WORD : 32 LSB bits of the container physical base address 82 // HIGH WORD : 16 MSB bits of the container physical base address + status (bit 31) 83 ///////////////////////////////////////////////////////////////////////////////////// 58 84 enum SoclibMultiNicChannelRegisters 59 85 { … … 72 98 }; 73 99 100 101 //////////////////////////////////////////////////////////////////////////////////// 102 // Chained Buffer Descriptor Structure 103 //////////////////////////////////////////////////////////////////////////////////// 104 typedef struct nic_chbuf_s 105 { 106 unsigned long long buf[GIET_CHBUF_NBUFS]; // array of buffer descriptors 107 unsigned int buf_length; // buffer length (bytes) 108 unsigned int nb_buffers; // actual number of buffers 109 } nic_chbuf_t; 110 74 111 /////////////////////////////////////////////////////////////////////////////////// 75 // NIC device access functions (vci_multi_nic)112 // Initialization functions 76 113 /////////////////////////////////////////////////////////////////////////////////// 77 114 78 extern unsigned int _nic_sync_write( const void* buffer, 79 unsigned int length ); 115 extern int _nic_global_init( unsigned int channels, 116 unsigned int vis, 117 unsigned int bc_enable, 118 unsigned int bypass_enable ); 80 119 81 extern unsigned int _nic_sync_read( const void* buffer, 82 unsigned int length ); 120 extern int _nic_channel_init( unsigned int index, 121 unsigned int mac4, 122 unsigned int mac2 ); 83 123 84 extern unsigned int _nic_cma_start(); 124 /////////////////////////////////////////////////////////////////////////////////// 125 // Blocking functions using a physical_memcpy() 126 /////////////////////////////////////////////////////////////////////////////////// 85 127 86 extern unsigned int _nic_cma_stop(); 128 extern int _nic_sync_receive( unsigned int channel, 129 unsigned long long user_paddr ); 130 131 extern int _nic_sync_send( unsigned int channel, 132 unsigned long long user_paddr ); 133 134 /////////////////////////////////////////////////////////////////////////////////// 135 // Non blocking functions using the chained buffer DMA 136 /////////////////////////////////////////////////////////////////////////////////// 137 138 extern int _nic_cma_receive( unsigned int nic_channel, 139 unsigned int cma_channel, 140 nic_chbuf_t* kernel_chbuf ); 141 142 extern int _nic_cma_send( unsigned int nic_channel, 143 unsigned int cma_channel, 144 nic_chbuf_t* kernel_chbuf ); 145 146 /////////////////////////////////////////////////////////////////////////////////// 147 // Interrupt Service Routines 148 /////////////////////////////////////////////////////////////////////////////////// 87 149 88 150 extern void _nic_rx_isr( unsigned int irq_type, … … 94 156 unsigned int channel ); 95 157 96 ///////////////////////////////////////////////////////////////////////////////////97 158 98 159 -
soft/giet_vm/giet_drivers/pic_driver.c
r413 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // Implementation note:8 // All physical accesses to device registers are done by the two9 // _pic_get_register(), _pic_set_register() low-level functions,10 // that are handling virtual / physical addressing.11 ///////////////////////////////////////////////////////////////////////////////////12 7 13 8 #include <pic_driver.h> 9 #include <giet_config.h> 10 #include <hard_config.h> 14 11 #include <utils.h> 15 12 … … 18 15 #endif 19 16 20 ///////////////////////////////////////////////////// ////////////////////////////17 ///////////////////////////////////////////////////// 21 18 unsigned int _pic_get_register( unsigned int channel, 22 19 unsigned int index ) … … 26 23 } 27 24 28 ///////////////////////////////////////////// ////////////////////////////////////25 ///////////////////////////////////////////// 29 26 void _pic_set_register( unsigned int channel, 30 27 unsigned int index, … … 36 33 37 34 38 ///////////////////////////////////// ////////////////////////////////////////////35 ///////////////////////////////////// 39 36 void _pic_init( unsigned int channel, // source PIC HWI channel 40 37 unsigned int vaddr, // dest XCU WTI address … … 46 43 } 47 44 48 //////////////////////////////////////////////////// /////////////////////////////45 //////////////////////////////////////////////////// 49 46 unsigned int _pic_get_status( unsigned int channel ) 50 47 { -
soft/giet_vm/giet_drivers/pic_driver.h
r413 r437 15 15 16 16 /////////////////////////////////////////////////////////////////////////////////// 17 // PIC (vci_iopic)registers offsets17 // registers offsets 18 18 /////////////////////////////////////////////////////////////////////////////////// 19 19 … … 29 29 30 30 ////////////////////////////////////////////////////////////////////////////////// 31 // PICaccess functions31 // access functions 32 32 ////////////////////////////////////////////////////////////////////////////////// 33 33 -
soft/giet_vm/giet_drivers/rdk_driver.c
r405 r437 6 6 // Copyright (c) UPMC-LIP6 7 7 /////////////////////////////////////////////////////////////////////////////////// 8 // The rdk_driver.c and rdk_driver.h files are part ot the GIET-VM kernel.9 //10 // This driver supports a virtual disk implemented as a memory segment,11 // in the address space.12 //13 // The _rdk_read() and _rdk_write() blocking functions use a software memcpy,14 // whatever the selected mode. They return only when the transfer is completed.15 // As the number of concurrent accesses is not bounded, these functions16 // don't use the _ioc_lock variable.17 //18 // The SEG_RDK_BASE virtual address must be defined in the hard_config.h19 // file when the USE_RAMDISK flag is set.20 ///////////////////////////////////////////////////////////////////////////////////21 8 22 9 #include <giet_config.h> … … 24 11 #include <rdk_driver.h> 25 12 #include <utils.h> 26 #include <tty_driver.h>27 #include <ctx_handler.h>28 13 29 14 #if !defined(SEG_RDK_BASE) … … 31 16 #endif 32 17 33 /////////////////////////////////////////////////////////////////////////////// 34 // _rdk_init() 35 // This function does nothing, and return 0 for success. 36 /////////////////////////////////////////////////////////////////////////////// 18 ////////////////////////////////////////////// 37 19 unsigned int _rdk_init( unsigned int channel ) 38 20 { … … 40 22 } 41 23 42 /////////////////////////////////////////////////////////////////////////////// 43 // _rdk_read() 44 // Transfer data from the RAMDISK to a memory buffer. 45 // - mode : BOOT / KERNEL / USER 46 // - lba : first block index on the block device 47 // - buffer : virtual base address of the memory buffer 48 // - count : number of blocks to be transfered. 49 // Returns 0 if success, > 0 if error. 50 /////////////////////////////////////////////////////////////////////////////// 24 ////////////////////////////////////////// 51 25 unsigned int _rdk_read( unsigned int lba, 52 26 unsigned int buffer, 53 27 unsigned int count) 54 28 { 29 #if USE_IOC_RDK 55 30 56 31 #if GIET_DEBUG_IOC_DRIVER 57 _printf("\n[IOC DEBUG] Enter _rdk_read() at cycle %d" 58 "\n - vaddr = %x" 59 "\n - sectors = %d" 60 "\n - lba = %x", 61 _get_proctime(), buffer, count, lba ); 32 _puts("\n[IOC DEBUG] Enter _rdk_read() at cycle "); 33 _putd( _get_proctime() ); 34 _puts("\n - vaddr = "); 35 _putx( buffer ); 36 -puts("\n - sectors = "); 37 _putd( count ); 38 -puts("\n - lba = "); 39 _putx( lba ); 40 _puts("\n"); 62 41 #endif 63 42 64 #if USE_IOC_RDK65 43 char* src = (char*)SEG_RDK_BASE + (512*lba); 66 44 char* dst = (char*)buffer; 67 45 memcpy( dst, src, count*512 ); 68 46 return 0; 47 69 48 #else 70 _printf("[GIET ERROR] _rdk_read() should not be used if USE_IOC_RDK not set\n"); 49 50 _puts("[GIET ERROR] _rdk_read() should not be used if USE_IOC_RDK not set\n"); 71 51 return 1; 52 72 53 #endif 73 54 } 74 55 75 /////////////////////////////////////////////////////////////////////////////// 76 // _rdk_write() 77 // Transfer data from a memory buffer to the block device. 78 // - mode : BOOT / KERNEL / USER 79 // - lba : first block index on the block device 80 // - buffer : virtual base address of the memory buffer 81 // - count : number of blocks to be transfered. 82 // Returns 0 if success, > 0 if error. 83 /////////////////////////////////////////////////////////////////////////////// 56 ////////////////////////////////////////// 84 57 unsigned int _rdk_write( unsigned int lba, 85 58 unsigned int buffer, 86 59 unsigned int count ) 87 60 { 61 #if USE_IOC_RDK 88 62 89 63 #if GIET_DEBUG_IOC_DRIVER 90 _printf("\n[IOC DEBUG] Enter _rdk_write() at cycle %d" 91 "\n - vaddr = %x" 92 "\n - sectors = %d" 93 "\n - lba = %x", 94 _get_proctime(), buffer, count, lba ); 64 _puts("\n[IOC DEBUG] Enter _rdk_write() at cycle "); 65 _putd( _get_proctime() ); 66 _puts("\n - vaddr = "); 67 _putx( buffer ); 68 -puts("\n - sectors = "); 69 _putd( count ); 70 -puts("\n - lba = "); 71 _putx( lba ); 72 _puts("\n"); 95 73 #endif 96 74 97 #if USE_IOC_RDK98 75 char* dst = (char*)SEG_RDK_BASE + (512*lba); 99 76 char* src = (char*)buffer; 100 77 memcpy( dst, src, count*512 ); 101 78 return 0; 79 102 80 #else 103 _printf("[GIET ERROR] _rdk_write() should not be used if USE_IOC_RDK not set\n"); 81 82 _puts("[GIET ERROR] _rdk_write() should not be used if USE_IOC_RDK not set\n"); 104 83 return 1; 84 105 85 #endif 106 86 } 107 87 108 /////////////////////////////////////////////////////////////////////////////// 109 // _rdk_get_block_size() 110 // This function returns the block_size. 111 /////////////////////////////////////////////////////////////////////////////// 88 ////////////////////////////////// 112 89 unsigned int _rdk_get_block_size() 113 90 { 114 91 return 512; 92 } 93 94 ////////////////////////////// 95 unsigned int _rdk_get_status() 96 { 97 return 0; 115 98 } 116 99 -
soft/giet_vm/giet_drivers/rdk_driver.h
r298 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The rdk_driver.c and rdk_driver.h files are part ot the GIET-VM kernel. 8 // 9 // This driver supports a virtual disk implemented as a memory segment, 10 // in the physical address space. 11 // 12 // The _rdk_read() and _rdk_write() blocking functions use a software memcpy, 13 // whatever the selected mode. They return only when the transfer is completed. 14 // As the number of concurrent accesses is not bounded, these functions 15 // don't use the _ioc_lock variable. 16 // 17 // The SEG_RDK_BASE virtual address must be defined in the hard_config.h 18 // file when the USE_RAMDISK flag is set. 19 /////////////////////////////////////////////////////////////////////////////////// 7 20 8 21 #ifndef _GIET_RDK_DRIVERS_H_ 9 22 #define _GIET_RDK_DRIVERS_H_ 10 11 #include <mapping_info.h>12 23 13 24 /////////////////////////////////////////////////////////////////////////////////// … … 15 26 /////////////////////////////////////////////////////////////////////////////////// 16 27 28 /////////////////////////////////////////////////////////////////////////////// 29 // This function does nothing, but is required by the IOC API. 30 /////////////////////////////////////////////////////////////////////////////// 17 31 extern unsigned int _rdk_init(); 18 32 33 /////////////////////////////////////////////////////////////////////////////// 34 // Transfer data from a memory buffer to the RAMDISK. 35 // - mode : BOOT / KERNEL / USER (unused) 36 // - lba : first block index on the block device 37 // - buffer : virtual base address of the memory buffer 38 // - count : number of blocks to be transfered. 39 // Returns 0 if success, > 0 if error. 40 /////////////////////////////////////////////////////////////////////////////// 19 41 extern unsigned int _rdk_write( unsigned int lba, 20 42 unsigned int buffer, 21 43 unsigned int count ); 22 44 45 /////////////////////////////////////////////////////////////////////////////// 46 // Transfer data from the RAMDISK to a memory buffer. 47 // - mode : BOOT / KERNEL / USER (unused) 48 // - lba : first block index on the block device 49 // - buffer : virtual base address of the memory buffer 50 // - count : number of blocks to be transfered. 51 // Returns 0 if success, > 0 if error. 52 /////////////////////////////////////////////////////////////////////////////// 23 53 extern unsigned int _rdk_read( unsigned int lba, 24 54 unsigned int buffer, 25 55 unsigned int count ); 26 56 57 /////////////////////////////////////////////////////////////////////////////// 58 // This function returns the block size. 59 /////////////////////////////////////////////////////////////////////////////// 27 60 extern unsigned int _rdk_get_block_size(); 28 61 29 62 /////////////////////////////////////////////////////////////////////////////////// 63 // This function returns always 0, but is required by the IOC API. 64 /////////////////////////////////////////////////////////////////////////////// 65 extern unsigned int _rdk_get_status(); 30 66 31 67 #endif -
soft/giet_vm/giet_drivers/sdc_driver.c
r320 r437 18 18 19 19 /////////////////////////////////////////////////////////////////////////////// 20 // _sdc_enable()21 20 // This function enables SD Card select signal 22 21 /////////////////////////////////////////////////////////////////////////////// … … 27 26 28 27 /////////////////////////////////////////////////////////////////////////////// 29 // _sdc_enable()30 28 // This function disables SD Card select signal 31 29 /////////////////////////////////////////////////////////////////////////////// … … 36 34 37 35 /////////////////////////////////////////////////////////////////////////////// 38 // _sdc_gen_tick()39 36 // This function writes on the SPI tx register to generate SD card clock ticks 40 37 // - tick_count: number of ticks to generate (1 tick -> 8 clocks) … … 47 44 48 45 /////////////////////////////////////////////////////////////////////////////// 49 // _sdc_lseek()50 46 // This function changes the SD card access pointer position in terms of 51 47 // blocks … … 58 54 59 55 /////////////////////////////////////////////////////////////////////////////// 60 // _sdc_receive_char()61 56 // This function gets a byte from the SD card 62 57 /////////////////////////////////////////////////////////////////////////////// … … 69 64 70 65 /////////////////////////////////////////////////////////////////////////////// 71 // _sdc_wait_response()72 66 // This function returns when a valid response from the SD card is received or 73 67 // a timeout has been triggered … … 94 88 95 89 /////////////////////////////////////////////////////////////////////////////// 96 // _sdc_wait_data_block()97 90 // This function returns when a data block from the SD card is received (data 98 91 // block start marker received). … … 105 98 106 99 /////////////////////////////////////////////////////////////////////////////// 107 // _sdc_send_command()108 100 // This function sends a command to the SD card 109 101 // - index: CMD index … … 153 145 154 146 /////////////////////////////////////////////////////////////////////////////// 155 // _sdc_open()156 147 // This function initializes the SD card (reset procedure) 157 148 // - channel: channel index (only channel 0 is supported) … … 182 173 if ( sdcard_rsp != 0x01 ) 183 174 { 184 _p rintf("[SDC ERROR] card CMD0 failed\n");175 _puts("[SDC ERROR] card CMD0 failed\n"); 185 176 return sdcard_rsp; 186 177 } … … 198 189 if (!SDCARD_CHECK_R1_VALID(sdcard_rsp)) 199 190 { 200 _p rintf("[SDC ERROR] card CMD8 failed\n");191 _puts("[SDC ERROR] card CMD8 failed\n"); 201 192 return sdcard_rsp; 202 193 } … … 211 202 { 212 203 // voltage mismatch 213 _p rintf("[SDC ERROR] card CMD8 mismatch : ersp = %x\n");204 _puts("[SDC ERROR] card CMD8 mismatch : ersp = %x\n"); 214 205 return sdcard_rsp; 215 206 } 216 _p rintf("[SDC WARNING] v2 or later ");207 _puts("[SDC WARNING] v2 or later "); 217 208 sdcard.sdhc = 1; 218 209 } … … 220 211 { 221 212 // other error 222 _p rintf("[SDC ERROR] card CMD8 error\n");213 _puts("[SDC ERROR] card CMD8 error\n"); 223 214 return sdcard_rsp; 224 215 } … … 251 242 if (sdcard_rsp) 252 243 { 253 _p rintf("[SDC ERROR] ACMD41 failed\n");244 _puts("[SDC ERROR] ACMD41 failed\n"); 254 245 return sdcard_rsp; 255 246 } … … 265 256 if (sdcard_rsp) 266 257 { 267 _p rintf("[SDC ERROR] CMD58 failed\n");258 _puts("[SDC ERROR] CMD58 failed\n"); 268 259 return sdcard_rsp; 269 260 } … … 274 265 if (ersp & 0x40000000) 275 266 { 276 _p rintf(" SDHC ");267 _puts(" SDHC "); 277 268 } 278 269 else … … 282 273 _sdc_disable(); 283 274 } 284 _p rintf("card detected\n");275 _puts("card detected\n"); 285 276 return 0; 286 277 } 287 278 288 279 /////////////////////////////////////////////////////////////////////////////// 289 // _sdc_set_block_size() 290 // This function sets the block size in bytes of the SD card 280 // This function sets the block size in the SD card. 291 281 // - len: block size in bytes (only 512 bytes supported) 292 282 // Returns 0 if success, other value if failure … … 330 320 } 331 321 332 /////////////////////////////////////////////////////////////////////////////// 333 // _sdc_init() 334 // This function initializes the SPI controller and call sdc_open to 335 // initializes SD card 336 // - channel: channel to initialize (only channel 0 supported) 337 // Returns 0 if success, other value if failure 338 /////////////////////////////////////////////////////////////////////////////// 322 ///////////////////////////////////////////////////////////////////////////////// 323 // Extern functions 324 ///////////////////////////////////////////////////////////////////////////////// 325 326 //////////////////////// 339 327 unsigned int _sdc_init() 340 328 { … … 358 346 while(1) 359 347 { 360 _p rintf("[SDC WARNING] Trying to initialize SD card...\n");348 _puts("[SDC WARNING] Trying to initialize SD card...\n"); 361 349 362 350 sdcard_rsp = _sdc_open( 0 ); // only channel 0 363 351 if (sdcard_rsp == 0) 364 352 { 365 _p rintf("OK\n");353 _puts("OK\n"); 366 354 break; 367 355 } 368 356 369 _p rintf("KO\n");357 _puts("KO\n"); 370 358 371 359 for (i = 0; i < 1000; i++); … … 373 361 if (++iter >= SDCARD_RESET_ITER_MAX) 374 362 { 375 _printf("\n[SDC ERROR] During SD card reset to IDLE state " 376 "/ card response = %x\n", sdcard_rsp ); 363 _puts("\n[SDC ERROR] During SD card reset / card response = "); 364 _putx( sdcard_rsp ); 365 _puts("\n"); 377 366 _exit(); 378 367 } … … 383 372 if (sdcard_rsp) 384 373 { 385 _p rintf("[SDC ERROR] During SD card blocklen initialization\n");374 _puts("[SDC ERROR] During SD card blocklen initialization\n"); 386 375 _exit(); 387 376 } … … 397 386 ); 398 387 399 _p rintf("[SDC WARNING] Finish SD card initialization\n\r");388 _puts("[SDC WARNING] Finish SD card initialization\n\r"); 400 389 401 390 return 0; … … 403 392 404 393 405 /////////////////////////////////////////////////////////////////////////////// 406 // _sdc_read() 407 // Transfer data from the block device to a memory buffer. 408 // - mode : BOOT / KERNEL / USER 409 // - lba : first block index on the block device 410 // - buffer : base address of the memory buffer (must be word aligned) 411 // - count : number of blocks to be transfered. 412 // Returns 0 if success, > 0 if error. 413 /////////////////////////////////////////////////////////////////////////////// 394 ////////////////////////////////////////// 414 395 unsigned int _sdc_read( unsigned int mode, 415 396 unsigned int lba, … … 461 442 } 462 443 463 /////////////////////////////////////////////////////////////////////////////// 464 // _sdc_write() (not supported for now) 465 // Transfer data from memory buffer to SD card device. 466 // - mode : BOOT / KERNEL / USER 467 // - lba : destination first block index on the SD card 468 // - buffer : base address of the memory buffer (must be word aligned) 469 // - count : number of blocks to be transfered. 470 // Returns 0 if success, > 0 if error. 471 /////////////////////////////////////////////////////////////////////////////// 444 /////////////////////////////////////////// 472 445 unsigned int _sdc_write( unsigned int mode, 473 446 unsigned int lba, … … 475 448 unsigned int count ) 476 449 { 477 return 0; 478 } 479 480 /////////////////////////////////////////////////////////////////////////////// 481 // Transfer data from memory buffer to SD card device. 482 // - channel: channel index 483 // - status: this pointer is used to transmit the status value to caller. 484 // Returns 0 if success, > 0 if error. 485 /////////////////////////////////////////////////////////////////////////////// 450 _puts("[SDC ERROR] function _sdc_write() not iplemented yet\n"); 451 _exit(); 452 453 return 0; // to avoid a warning 454 } 455 456 ////////////////////////////// 486 457 unsigned int _sdc_get_status() 487 458 { 488 _p rintf("[SDC ERROR] function _sdc_get_status() should not be called\n");459 _puts("[SDC ERROR] function _sdc_get_status() should not be called\n"); 489 460 _exit(); 490 461 … … 492 463 } 493 464 494 /////////////////////////////////////////////////////////////////////////////// 495 // Returns the block size in bytes of the SD card 496 /////////////////////////////////////////////////////////////////////////////// 465 ////////////////////////////////// 497 466 unsigned int _sdc_get_block_size() 498 467 { -
soft/giet_vm/giet_drivers/sdc_driver.h
r295 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 8 #ifndef _GIET_SDC_DRIVER_H_ 8 9 #define _GIET_SDC_DRIVER_H_ … … 36 37 }; 37 38 39 /////////////////////////////////////////////////////////////////////////////// 40 // This function initializes the SPI controller and call sdc_open to 41 // initialize the SD card 42 // - channel: channel to initialize (only channel 0 supported) 43 // Returns 0 if success, other value if failure 44 /////////////////////////////////////////////////////////////////////////////// 38 45 unsigned int _sdc_init(); 39 46 47 /////////////////////////////////////////////////////////////////////////////// 48 // Transfer data from the block device to a memory buffer. 49 // - mode : BOOT / KERNEL / USER 50 // - lba : first block index on the block device 51 // - buffer : base address of the memory buffer (must be word aligned) 52 // - count : number of blocks to be transfered. 53 // Returns 0 if success, > 0 if error. 54 /////////////////////////////////////////////////////////////////////////////// 40 55 unsigned int _sdc_read( unsigned int mode, 41 56 unsigned int lba, … … 44 59 45 60 61 /////////////////////////////////////////////////////////////////////////////// 62 // Transfer data from memory buffer to SD card device. 63 // - mode : BOOT / KERNEL / USER 64 // - lba : destination first block index on the SD card 65 // - buffer : base address of the memory buffer (must be word aligned) 66 // - count : number of blocks to be transfered. 67 // Returns 0 if success, > 0 if error. 68 // WARNING: The _sdc_write() is not implemented yet. 69 /////////////////////////////////////////////////////////////////////////////// 46 70 unsigned int _sdc_write( unsigned int mode, 47 71 unsigned int lba, … … 49 73 unsigned int count); 50 74 75 /////////////////////////////////////////////////////////////////////////////// 76 // This function should not be called for the SDC card. 77 /////////////////////////////////////////////////////////////////////////////// 51 78 unsigned int _sdc_get_status(); 52 79 80 /////////////////////////////////////////////////////////////////////////////// 81 // Returns the block size in bytes of the SD card. 82 /////////////////////////////////////////////////////////////////////////////// 53 83 unsigned int _sdc_get_block_size(); 54 84 -
soft/giet_vm/giet_drivers/sim_driver.c
r345 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The sim_driver.c and sim_driver.h files are part ot the GIET-VM nano-kernel.8 // This driver supports the vci_sim_helper component.9 // There is at most one such component in the architecture.10 //11 // The SEG_SIM_BASE address must be defined in the hard_config.h file.12 ////////////////////////////////////////////////////////////////////////////////13 7 14 8 #include <hard_config.h> … … 20 14 #endif 21 15 22 //////////////////////////////////////////////////////////////////////////////// 23 // _sim_helper_access() 24 // Accesses the Simulation Helper Component. 25 // 26 // If the access is on a writable register (except SIMHELPER_PAUSE_SIM), 27 // the simulation will stop. 28 // If the access is on a readable register, value is written in retval buffer. 29 // Returns 0 on success, 1 on failure. 30 //////////////////////////////////////////////////////////////////////////////// 31 unsigned int _sim_helper_access( unsigned int register_index, 32 unsigned int value, 33 unsigned int * retval) 16 ///////////////////////////////////////////////////// 17 void _sim_helper_access( unsigned int register_index, 18 unsigned int value, 19 unsigned int * retval ) 34 20 { 35 21 volatile unsigned int* sim_helper_address = (unsigned int*)&seg_sim_base; 36 22 37 if (register_index == SIMHELPER_SC_STOP || 38 register_index == SIMHELPER_END_WITH_RETVAL || 39 register_index == SIMHELPER_EXCEPT_WITH_VAL || 40 register_index == SIMHELPER_PAUSE_SIM || 41 register_index == SIMHELPER_SIGINT) 23 if (register_index == SIMHELPER_SC_STOP) 42 24 { 43 25 sim_helper_address[register_index] = value; 44 return 0;45 26 } 46 27 else if (register_index == SIMHELPER_CYCLES) 47 28 { 48 29 *retval = sim_helper_address[register_index]; 49 return 0;50 30 } 51 31 else 52 32 { 53 33 _tty_get_lock( 0 ); 54 _puts("\n[GIET ERROR] in _sim_helper_access() : access to unmapped register\n");34 _puts("\n[GIET ERROR] in _sim_helper_access() : undefined register\n"); 55 35 _tty_release_lock( 0 ); 56 return 1;36 _exit(); 57 37 } 58 38 } -
soft/giet_vm/giet_drivers/sim_driver.h
r258 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The sim_driver.c and sim_driver.h files are part ot the GIET-VM nano-kernel. 8 // 9 // This driver supports the vci_sim_helper component, that is a pseudo hardware 10 // component available in the SoCLib library, and providing a monitoring service 11 // in a virtual prototyping environment. 12 // 13 // There is at most one such component in the architecture. 14 // 15 // The SEG_SIM_BASE address must be defined in the hard_config.h file. 16 //////////////////////////////////////////////////////////////////////////////// 7 17 8 18 #ifndef _GIET_SIM_DRIVERS_H_ … … 15 25 enum SoclibSimhelperRegisters 16 26 { 17 SIMHELPER_SC_STOP, 18 SIMHELPER_END_WITH_RETVAL, 19 SIMHELPER_EXCEPT_WITH_VAL, 20 SIMHELPER_PAUSE_SIM, 21 SIMHELPER_CYCLES, 22 SIMHELPER_SIGINT, 27 SIMHELPER_SC_STOP, // stop simulation 28 SIMHELPER_END_WITH_RETVAL, // Not supported 29 SIMHELPER_EXCEPT_WITH_VAL, // Not supported 30 SIMHELPER_PAUSE_SIM, // Not supported 31 SIMHELPER_CYCLES, // Return number of cycles 32 SIMHELPER_SIGINT, // Not supported 23 33 }; 24 34 25 /////////////////////////////////////////////////////////////////////////////////// 26 // SIM_HELPER access functions 27 /////////////////////////////////////////////////////////////////////////////////// 35 //////////////////////////////////////////////////////////////////////////////// 36 // Accesses the Simulation Helper Component. 37 // - If the access is on a write register, the simulation will stop. 38 // - If the access is on a read register, value is written in retval buffer. 39 //////////////////////////////////////////////////////////////////////////////// 40 extern void _sim_helper_access( unsigned int register_index, 41 unsigned int value, 42 unsigned int* retval ); 28 43 29 extern unsigned int _sim_helper_access( unsigned int register_index,30 unsigned int value,31 unsigned int* retval );32 33 ///////////////////////////////////////////////////////////////////////////////////34 44 35 45 #endif -
soft/giet_vm/giet_drivers/spi_driver.c
r320 r437 258 258 unsigned int channel ) 259 259 { 260 _p rintf("\n[GIET ERROR] _spi_isr() not implemented\n");260 _puts("\n[GIET ERROR] _spi_isr() not implemented\n"); 261 261 _exit(); 262 262 } -
soft/giet_vm/giet_drivers/tim_driver.c
r426 r437 1 1 ////////////////////////////////////////////////////////////////////////////////////// 2 // File : tim er_driver.c2 // File : tim_driver.c 3 3 // Date : 23/05/2013 4 4 // Author : alain greiner 5 5 // Copyright (c) UPMC-LIP6 6 6 ////////////////////////////////////////////////////////////////////////////////////// 7 // The timer_driver.c and timer_driver.h files are part ot the GIET-VM nano-kernel.8 // This driver supports the SoCLib vci_multi_timer component.9 //10 // It can exist several multi_timers in the architecture (at most one per cluster),11 // and each one can contain several timers (called channels).12 //13 // There is two types of timers:14 // - "system" timers : one per processor, used for context switch.15 // local_id in [0, NB_PROCS_MAX-1],16 // - "user" timers : requested by the task in the mapping_info data structure.17 // For each user timer, the timer_id is stored in the context of the task.18 // The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id19 //20 // The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file.21 //22 // The virtual base address of the segment associated to a channel is:23 // SEG_TIM_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + TIMER_SPAN * timer_id24 //25 // The SEG_TIM_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h.26 /////////////////////////////////////////////////////////////////////////////////////27 7 28 8 #include <giet_config.h> 9 #include <hard_config.h> 29 10 #include <tim_driver.h> 30 #include <xcu_driver.h>31 #include <tty_driver.h>32 11 #include <utils.h> 33 12 … … 68 47 #endif 69 48 70 /////////////////// Timer global variables //////////////////////////////////////// 49 ///////////////////////////////////////////////////////////////////////////////// 50 // global variables 51 ///////////////////////////////////////////////////////////////////////////////// 71 52 72 53 #define in_unckdata __attribute__((section (".unckdata"))) 73 54 74 55 #if (NB_TIM_CHANNELS > 0) 75 in_unckdata volatile unsigned char _user_timer_event[ (1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS]76 = { [0 ... (( (1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS) - 1)] = 0 };56 in_unckdata volatile unsigned char _user_timer_event[NB_TIM_CHANNELS] 57 = { [0 ... ((1<<NB_TIM_CHANNELS) - 1)] = 0 }; 77 58 #endif 78 59 79 //////////////////////////////////////////////////////////////////////////////////// 80 // This function activates a timer in the vci_timer component 81 // by writing in the proper register the period value. 82 // It can be used by both the kernel to initialise a "system" timer, 83 // or by a task (through a system call) to configure an "user" timer. 84 /////////////////////////////////////////////////////////////////////////////////// 85 void _timer_start( unsigned int cluster_xy, 86 unsigned int local_id, 87 unsigned int period) 60 ///////////////////////////////////////////////////////////////////////////////// 61 // access functions 62 ///////////////////////////////////////////////////////////////////////////////// 63 64 ////////////////////////////////////////////////////////////// 65 unsigned int _timer_get_register( unsigned int channel, 66 unsigned int index ) 67 { 68 unsigned int* vaddr = (unsigned int*)SEG_TIM_BASE + channel*TIMER_SPAN + index; 69 return _io_extended_read( vaddr ); 70 } 71 72 ////////////////////////////////////////////////////// 73 void _timer_set_register( unsigned int channel, 74 unsigned int index, 75 unsigned int value ) 76 { 77 unsigned int* vaddr = (unsigned int*)SEG_TIM_BASE + channel*TIMER_SPAN + index; 78 _io_extended_write( vaddr, value ); 79 } 80 81 /////////////////////////////////////// 82 int _timer_start( unsigned int channel, 83 unsigned int period ) 88 84 { 89 85 #if NB_TIM_CHANNELS 90 86 91 // parameters checking 92 unsigned int x = cluster_xy >> Y_WIDTH; 93 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 94 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 87 if ( channel >= NB_TIM_CHANNELS ) 95 88 { 96 _p rintf("[GIET ERROR] in _timer_start()\n");97 _exit();89 _puts("[GIET ERROR] in _timer_start()\n"); 90 return -1; 98 91 } 99 92 100 unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE + 101 (cluster_xy * PERI_CLUSTER_INCREMENT) ); 102 103 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; 104 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3; 93 _timer_set_register( channel, TIMER_PERIOD, period ); 94 _timer_set_register( channel, TIMER_MODE , 0x3 ); 95 96 return 0; 105 97 106 98 #else 107 _printf("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n"); 108 _exit(); 99 100 _puts("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n"); 101 return -1; 102 109 103 #endif 110 104 } 111 105 112 ////////////////////////////////////////////////////////////////////////////// 113 // This function desactivates a timer in the vci_timer component 114 // by writing in the proper register. 115 // Returns 0 if success, > 0 if error. 116 ////////////////////////////////////////////////////////////////////////////// 117 void _timer_stop( unsigned int cluster_xy, 118 unsigned int local_id) 106 /////////////////////////////////////// 107 int _timer_stop( unsigned int channel ) 119 108 { 120 109 #if NB_TIM_CHANNELS 121 110 122 // parameters checking 123 unsigned int x = cluster_xy >> Y_WIDTH; 124 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 125 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 111 if ( channel >= NB_TIM_CHANNELS ) 126 112 { 127 _p rintf("[GIET ERROR] in _timer_stop()\n");128 _exit();113 _puts("[GIET ERROR] in _timer_stop()\n"); 114 return -1; 129 115 } 130 116 131 unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE + 132 (cluster_xy * PERI_CLUSTER_INCREMENT) ); 117 _timer_set_register( channel, TIMER_MODE , 0 ); 133 118 134 timer_address[local_id * TIMER_SPAN + TIMER_MODE] =0;119 return 0; 135 120 136 121 #else 137 _printf("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n"); 138 _exit(); 122 123 _puts("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n"); 124 return -1; 125 139 126 #endif 140 127 } 141 128 142 ////////////////////////////////////////////////////////////////////////////// 143 // This function acknowlegge a timer interrupt in the vci_timer 144 // component by writing in the proper register. 145 // It can be used by both the isr_switch() for a "system" timer, 146 // or by the _isr_timer() for an "user" timer. 147 // Returns 0 if success, > 0 if error. 148 ////////////////////////////////////////////////////////////////////////////// 149 void _timer_reset_irq( unsigned int cluster_xy, 150 unsigned int local_id ) 129 //////////////////////////////////////////// 130 int _timer_reset_cpt( unsigned int channel ) 151 131 { 152 132 #if NB_TIM_CHANNELS 153 133 154 // parameters checking 155 unsigned int x = cluster_xy >> Y_WIDTH; 156 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 157 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 134 if ( channel >= NB_TIM_CHANNELS ) 158 135 { 159 _p rintf("[GIET ERROR] in _timer_reset_irq()\n");160 _exit();136 _puts("[GIET ERROR in _timer_reset_cpt()\n"); 137 return -1; 161 138 } 162 139 163 unsigned int * timer_address = (unsigned int *) ( SEG_TIM_BASE +164 (cluster_xy * PERI_CLUSTER_INCREMENT));140 unsigned int period = _timer_get_register( channel, TIMER_PERIOD ); 141 _timer_set_register( channel, TIMER_PERIOD, period ); 165 142 166 timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] =0;143 return 0; 167 144 168 145 #else 169 _printf("[GIET ERROR] _timer_reset_irq() should not be called when NB_TIM_CHANNELS is 0\n"); 170 _exit(); 146 147 _puts("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n"); 148 return -1; 149 171 150 #endif 172 151 } 173 152 174 ///////////////////////////////////////////////////////////////////////////// 175 // This function resets the timer counter. To do so, we re-write the period 176 // in the proper register, what causes the count to restart. 177 // The period value is read from the same (TIMER_PERIOD) register, 178 // this is why in appearance we do nothing useful (read a value 179 // from a register and write this value in the same register) 180 // This function is called during a context switch (user or preemptive) 181 //////////////////////////////////////////////////////////////////////i////// 182 void _timer_reset_cpt( unsigned int cluster_xy, 183 unsigned int local_id) 184 { 185 #if NB_TIM_CHANNELS 186 187 // parameters checking 188 unsigned int x = cluster_xy >> Y_WIDTH; 189 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 190 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 191 { 192 _printf("[GIET ERROR in _timer_reset_cpt()\n"); 193 _exit(); 194 } 195 196 // We suppose that the TIMER_MODE register value is 0x3 197 unsigned int* timer_address = (unsigned int *) ( SEG_TIM_BASE + 198 (cluster_xy * PERI_CLUSTER_INCREMENT) ); 199 200 unsigned int period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD]; 201 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; 202 203 #else 204 _printf("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n"); 205 _exit(); 206 #endif 207 } 208 209 /////////////////////////////////////////////////////////////////////////////////// 210 // This ISR handles the IRQs generated by the "user" timers that are 211 // replicated in all clusters. 212 // The IRQs generated by the "system" timers should be handled by _isr_switch(). 213 // It can be a HWI or a PTI. 214 // The channel argument is the user timer local index. 215 // timer_global_id = cluster_id*(NB_TIM_CHANNELS) + channel 216 // The ISR acknowledges the IRQ and registers the event in the proper entry 217 // of the _user_timer_event[] array, and a log message is displayed on TTY0. 218 /////////////////////////////////////////////////////////////////////////////////// 153 /////////////////////////////////////// 219 154 void _timer_isr( unsigned int irq_type, // HWI / PTI 220 155 unsigned int irq_id, // index returned by XCU … … 223 158 #if NB_TIM_CHANNELS 224 159 225 unsigned int cluster_xy = _get_procid() >> P_WIDTH; 226 227 // acknowledge IRQ depending on type 228 if ( irq_type == IRQ_TYPE_HWI ) _timer_reset_irq( cluster_xy, channel ); 229 else _xcu_timer_reset_irq( cluster_xy, irq_id ); 160 // acknowledge IRQ 161 _timer_set_register( channel, TIMER_RESETIRQ, 0 ); 230 162 231 163 // register the event 232 _user_timer_event[c luster_xy * NB_TIM_CHANNELS + channel] = 1;164 _user_timer_event[channel] = 1; 233 165 234 166 // display a message on TTY 0 235 _p rintf("\n[GIET WARNING] User Timer IRQ at cycle %d / cluster = %x /channel = %d\n",236 _get_proctime(), c luster_xy, channel );167 _puts("\n[GIET WARNING] User Timer IRQ at cycle %d for channel = %d\n", 168 _get_proctime(), channel ); 237 169 238 170 #else 239 _printf("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n"); 171 172 _puts("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n"); 240 173 _exit(); 174 241 175 #endif 242 176 } -
soft/giet_vm/giet_drivers/tim_driver.h
r295 r437 1 /////////////////////////////////////////////////////////////////////////////////// 1 ////////////////////////////////////////////////////////////////////////////////////// 2 2 // File : tim_driver.h 3 3 // Date : 01/11/2013 … … 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The tim_driver.c and tim_driver.h files are part ot the GIET-VM nano-kernel. 8 // This driver supports the SoCLib vci_multi_timer component. 9 // 10 // It can exist several multi_timers in the architecture (at most one per cluster), 11 // and each one can contain several timers (called channels). 12 // 13 // There is two types of timers: 14 // - "system" timers : one per processor, used for context switch. 15 // local_id in [0, NB_PROCS_MAX-1], 16 // - "user" timers : requested by the task in the mapping_info data structure. 17 // For each user timer, the timer_id is stored in the context of the task. 18 // The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id 19 // 20 // The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file. 21 // 22 // The virtual base address of the segment associated to a channel is: 23 // SEG_TIM_BASE + cluster_xy * PERI_CLUSTER_INCREMENT + TIMER_SPAN * timer_id 24 // 25 // The SEG_TIM_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h. 26 ///////////////////////////////////////////////////////////////////////////////////// 7 27 8 28 #ifndef _GIET_TIM_DRIVER_H_ … … 10 30 11 31 /////////////////////////////////////////////////////////////////////////////////// 12 // TIMER (vci_multi_timer)registers offsets32 // registers offsets 13 33 /////////////////////////////////////////////////////////////////////////////////// 14 34 … … 24 44 25 45 /////////////////////////////////////////////////////////////////////////////////// 26 // Timer access functions and global variables46 // access functions 27 47 /////////////////////////////////////////////////////////////////////////////////// 28 48 29 extern void _timer_start( unsigned int cluster_xy, 30 unsigned int local_id, 31 unsigned int period ); 49 /////////////////////////////////////////////////////////////////////////////////// 50 // This function activates a timer in the vci_timer external peripheral. 51 // - channel : Timer channel global index 52 // - period : interrupt period (cycles) 53 /////////////////////////////////////////////////////////////////////////////////// 54 extern int _timer_start( unsigned int channel, 55 unsigned int period ); 32 56 33 extern void _timer_stop( unsigned int cluster_xy, 34 unsigned int local_id ); 57 /////////////////////////////////////////////////////////////////////////////////// 58 // This function desactivates a timer in the vci_timer external component. 59 /////////////////////////////////////////////////////////////////////////////////// 60 extern int _timer_stop( unsigned int channel ); 35 61 36 extern void _timer_reset_irq( unsigned int cluster_xy, 37 unsigned int local_id ); 62 /////////////////////////////////////////////////////////////////////////////////// 63 // This function resets the timer counter. To do so, it read the period, 64 // and re-write it in the timer register, what causes the count to restart. 65 /////////////////////////////////////////////////////////////////////////////////// 66 extern int _timer_reset_cpt( unsigned int channel ); 38 67 39 extern void _timer_reset_cpt( unsigned int cluster_xy, 40 unsigned int local_id); 41 68 /////////////////////////////////////////////////////////////////////////////////// 69 // This Interrupt Service Routine handles the IRQs generated by the "user" timers. 70 // It can be a HWI or a PTI. 71 // The channel argument is the user timer global index. 72 // The ISR acknowledges the IRQ, registers the event in the proper entry 73 // of the _user_timer_event[] array, and a log message is displayed on TTY0. 74 /////////////////////////////////////////////////////////////////////////////////// 42 75 extern void _timer_isr( unsigned int irq_type, 43 76 unsigned int irq_id, 44 77 unsigned int channel ); 45 78 46 ///////////////////////////////////////////////////////////////////////////////////47 79 48 80 #endif -
soft/giet_vm/giet_drivers/tty_driver.c
r426 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The tty_driver.c and tty_drivers.h files are part ot the GIET-VM kernel.8 // This driver supports the SocLib vci_multi_tty component.9 //10 // The total number of TTY terminals must be defined by the configuration11 // parameter NB_TTY_CHANNELS in the hard_config.h file.12 //13 // The "system" terminal is TTY[0].14 // The "user" TTYs are allocated to applications by the GIET in the boot phase,15 // as defined in the mapping_info data structure. The corresponding tty_id must16 // be stored in the context of the task by the boot code.17 //18 // The SEG_TTY_BASE address must be defined in the hard_config.h file.19 ///////////////////////////////////////////////////////////////////////////////////20 // Implementation note:21 //22 // All physical accesses to device registers are done by the two23 // _tty_get_register(), _tty_set_register() low-level functions,24 // that are handling virtual / physical addressing.25 ///////////////////////////////////////////////////////////////////////////////////26 7 27 8 #include <giet_config.h> 9 #include <hard_config.h> 28 10 #include <tty_driver.h> 29 11 #include <xcu_driver.h> … … 48 30 49 31 ////////////////////////////////////////////////////////////////////////////// 50 // TTYglobal variables32 // global variables 51 33 ////////////////////////////////////////////////////////////////////////////// 52 34 … … 65 47 66 48 ////////////////////////////////////////////////////////////////////////////// 67 // This low level function returns the value of register (channel / index)49 // access functions 68 50 ////////////////////////////////////////////////////////////////////////////// 51 52 ///////////////////////////////////////////////////// 69 53 unsigned int _tty_get_register( unsigned int channel, 70 54 unsigned int index ) … … 74 58 } 75 59 76 ////////////////////////////////////////////////////////////////////////////// 77 // This low level function set a new value in register (channel / index) 78 ////////////////////////////////////////////////////////////////////////////// 60 ///////////////////////////////////////////// 79 61 void _tty_set_register( unsigned int channel, 80 62 unsigned int index, … … 85 67 } 86 68 87 /////////////////////////////////////////////////////////////////////////////////88 // This non-blocking function writes a character string from a fixed-length89 // buffer to a TTY terminal identified by the channel argument.90 // This function is intended to be used to handle a system call, and should91 // not be used by the kernel for log messages on TTY 0.92 // protecting exclusive access to the selected terminal.93 // If channel argument is 0xFFFFFFFF, the TTY index is found in the task context.94 // This is a non blocking call: it tests the TTY_STATUS register, and stops95 // the transfer as soon as the TTY_STATUS[WRITE] bit is set.96 /////////////////////////////////////////////////////////////////////////////////97 // Returns the number of characters that have been written.98 /////////////////////////////////////////////////////////////////////////////////99 unsigned int _tty_write( const char* buffer,100 unsigned int length, // number of characters101 unsigned int channel) // channel index102 {103 unsigned int nwritten;104 69 105 // compute and check tty channel 106 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 107 if( channel >= NB_TTY_CHANNELS ) return -1; 108 109 // write string to TTY channel 110 for (nwritten = 0; nwritten < length; nwritten++) 111 { 112 // check tty's status 113 if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 ) break; 114 115 // write one byte 116 if (buffer[nwritten] == '\n') { 117 _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' ); 118 } 119 _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] ); 120 } 121 122 return nwritten; 123 } 124 125 ////////////////////////////////////////////////////////////////////////////// 126 // This non-blocking function fetches one character from the 127 // terminal identified by the channel argument. If the channel argument 128 // is 0xFFFFFFFF, the channel index is obtained from the current task context. 129 // It uses the TTY_GET_IRQ[tty_id] interrupt and the buffer must have been 130 // filled by the TTY_ISR. 131 // It test the _tty_rx_full[tty_id] variable, read the _tty_rx_buf[tty_id] 132 // buffer, writes this character to the target buffer, and resets the 133 // _tty_rx_full[tty_id] register. 134 // The length argument is not used. 135 ////////////////////////////////////////////////////////////////////////////// 136 // Returns the number of characters that have been read (0/1). 137 ////////////////////////////////////////////////////////////////////////////// 138 unsigned int _tty_read( char* buffer, 139 unsigned int length, // unused 140 unsigned int channel) // channel index 141 { 142 // compute and check tty channel 143 if( channel == 0xFFFFFFFF ) channel = _get_context_slot(CTX_TTY_ID); 144 if( channel >= NB_TTY_CHANNELS ) return -1; 145 146 // read one character from TTY channel 147 if (_tty_rx_full[channel] == 0) 148 { 149 return 0; 150 } 151 else 152 { 153 *buffer = _tty_rx_buf[channel]; 154 _tty_rx_full[channel] = 0; 155 return 1; 156 } 157 } 158 159 ////////////////////////////////////////////////////////////////////////////// 160 // This function try to take the lock protecting 161 // exclusive access to TTY terminal identified by the "channel" argument. 162 // It enters a critical section before taking the lock, and save the SR value 163 // at address defined by the "save_sr_ptr" argument. 164 // It returns only when the lock has been successfully taken. 165 ////////////////////////////////////////////////////////////////////////////// 166 void _tty_get_lock( unsigned int channel, 167 unsigned int * save_sr_ptr ) 168 { 169 if( channel >= NB_TTY_CHANNELS ) _exit(); 170 _it_disable( save_sr_ptr ); 171 _get_lock( &_tty_lock[channel] ); 172 } 173 174 ////////////////////////////////////////////////////////////////////////////// 175 // This function releases the hardwired lock protecting 176 // exclusive access to TTY terminal identified by the channel argument. 177 // It exit the critical section after lock release, and restore SR value 178 // from address defined by the "save_sr_ptr" argument. 179 ////////////////////////////////////////////////////////////////////////////// 180 void _tty_release_lock( unsigned int channel, 181 unsigned int * save_sr_ptr ) 182 { 183 if( channel >= NB_TTY_CHANNELS ) _exit(); 184 _release_lock( &_tty_lock[channel] ); 185 _it_restore( save_sr_ptr ); 186 } 187 188 /////////////////////////////////////////////////////////////////////////////////// 189 // This ISR handles the IRQ signaling that the RX buffer is not empty. 190 // IT can be an HWI or an SWI. 191 // There is one communication buffer _tty_rx_buf[i] and one synchronisation 192 // variable _tty_rx_full[i] per channel. 193 // Does nothing if the TTY_RX buffer is empty, or if the kernel buffer is full 194 // when the ISR is called. 195 /////////////////////////////////////////////////////////////////////////////////// 70 //////////////////////////////////////// 196 71 void _tty_rx_isr( unsigned int irq_type, // HWI / WTI 197 72 unsigned int irq_id, // index returned by XCU … … 242 117 } 243 118 244 /////////////////////////////////////////////////////////////////////////////////// 245 // This ISR handles the IRQ signaling that the TX buffer is empty. 246 // IT can be an HWI or an SWI. 247 // There is one single multi_tty component controling all channels. 248 // There is one communication buffer _tty_rx_buf[i] and one synchronisation 249 // variable _tty_rx_full[i] per channel. 250 // A character is lost if the buffer is full when the ISR is executed. 251 /////////////////////////////////////////////////////////////////////////////////// 119 ///////////////////////////////////////// 252 120 void _tty_tx_isr( unsigned int irq_type, // HWI / WTI 253 121 unsigned int irq_id, // index returned by XCU -
soft/giet_vm/giet_drivers/tty_driver.h
r350 r437 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The tty_driver.c and tty_drivers.h files are part ot the GIET-VM kernel. 8 // This driver supports the SocLib vci_multi_tty component. 9 // 10 // The total number of TTY terminals must be defined by the configuration 11 // parameter NB_TTY_CHANNELS in the hard_config.h file. 12 // 13 // The "system" terminal is TTY[0]. 14 // The "user" TTYs are allocated to applications requesting it. 15 // 16 // The SEG_TTY_BASE address must be defined in the hard_config.h file. 17 // 18 // All physical accesses to device registers are done by the two 19 // _tty_get_register(), _tty_set_register() low-level functions, 20 // that are handling virtual / physical addressing. 21 /////////////////////////////////////////////////////////////////////////////////// 7 22 8 23 #ifndef _GIET_TTY_DRIVERS_H_ 9 24 #define _GIET_TTY_DRIVERS_H_ 10 25 11 #include "utils.h"26 #include <utils.h> 12 27 13 28 /////////////////////////////////////////////////////////////////////////////////// 14 // TTY (vci_multi_tty)registers offsets29 // registers offsets 15 30 /////////////////////////////////////////////////////////////////////////////////// 16 31 … … 26 41 27 42 /////////////////////////////////////////////////////////////////////////////////// 28 // TTYvariables43 // external variables 29 44 /////////////////////////////////////////////////////////////////////////////////// 30 45 … … 36 51 37 52 ////////////////////////////////////////////////////////////////////////////////// 38 // TTYaccess functions53 // access functions 39 54 ////////////////////////////////////////////////////////////////////////////////// 40 55 41 extern unsigned int _tty_write( const char* buffer, 42 unsigned int length, 43 unsigned int channel ); 56 extern unsigned int _tty_get_register( unsigned int channel, 57 unsigned int index ); 44 58 45 extern unsigned int _tty_read( char* buffer,46 unsigned int length,47 unsigned int channel );59 extern void _tty_set_register( unsigned int channel, 60 unsigned int index, 61 unsigned int value ); 48 62 49 extern void _tty_get_lock( unsigned int channel, 50 unsigned int* save_sr_ptr ); 51 52 extern void _tty_release_lock( unsigned int channel, 53 unsigned int* save_sr_ptr ); 63 /////////////////////////////////////////////////////////////////////////////////// 64 // Interrupt Service Routine 65 /////////////////////////////////////////////////////////////////////////////////// 54 66 55 67 extern void _tty_rx_isr( unsigned int irq_type, … … 61 73 unsigned int channel ); 62 74 63 ///////////////////////////////////////////////////////////////////////////////////64 // low-level access functions65 ///////////////////////////////////////////////////////////////////////////////////66 67 extern unsigned int _tty_get_register( unsigned int channel,68 unsigned int index );69 70 extern void _tty_set_register( unsigned int channel,71 unsigned int index,72 unsigned int value );73 75 74 76 #endif -
soft/giet_vm/giet_drivers/xcu_driver.c
r395 r437 4 4 // Author : alain greiner 5 5 // Copyright (c) UPMC-LIP6 6 ///////////////////////////////////////////////////////////////////////////////////7 // This peripheral is replicated in all clusters containing processors.8 //9 // SEG_XCU_BASE and PERI_CLUSTER_INCREMENT must be defined in hard_config.h file.10 6 /////////////////////////////////////////////////////////////////////////////////// 11 7 … … 85 81 } 86 82 87 //////////////////////////////////////////////////////////////////////////////// 88 // This function set the mask register for the IRQ type defined by "irq_type", 89 // and for the channel identified by the "cluster_xy" and "channel" arguments. 90 // All '1' bits are set / all '0' bits are not modified. 91 //////////////////////////////////////////////////////////////////////////////// 83 //////////////////////////////////////////// 92 84 void _xcu_set_mask( unsigned int cluster_xy, 93 85 unsigned int channel, … … 109 101 else 110 102 { 111 _p rintf("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n");103 _puts("[GIET ERROR] _xcu_set_mask() receives illegal IRQ type\n"); 112 104 _exit(); 113 105 } … … 116 108 117 109 #else 118 _printf("[GIET ERROR] _xcu_set_mask() should not be used if USE_XCU not set\n"); 119 _exit(); 120 #endif 121 } 122 123 //////////////////////////////////////////////////////////////////////////////// 124 // This function returns the index and the type of the highest priority 125 // - active PTI (Timer Interrupt), then 126 // - active HWI (Hardware Interrupt), then 127 // - active WTI (Software Interrupt) 128 // As the hardware can define more than one IRQ per processor, but the GIET 129 // use only one, channel = lpid * IRQ_PER_PROCESSOR. 130 //////////////////////////////////////////////////////////////////////////////// 110 _puts("[GIET ERROR] _xcu_set_mask() should not be used if USE_XCU not set\n"); 111 _exit(); 112 #endif 113 } 114 115 ///////////////////////////////////////////// 131 116 void _xcu_get_index( unsigned int cluster_xy, 132 117 unsigned int channel, … … 170 155 171 156 #else 172 _printf("[GIET ERROR] _xcu_get_index should not be used if USE_XCU is not set\n"); 173 _exit(); 174 #endif 175 } 176 177 //////////////////////////////////////////////////////////////////////////////// 178 // This function writes the "wdata" value in the mailbox defined 179 // by the "cluster_xy" and "wti_index" arguments. 180 //////////////////////////////////////////////////////////////////////////////// 157 _puts("[GIET ERROR] _xcu_get_index should not be used if USE_XCU is not set\n"); 158 _exit(); 159 #endif 160 } 161 162 //////////////////////////////////////////// 181 163 void _xcu_send_wti( unsigned int cluster_xy, 182 164 unsigned int wti_index, … … 194 176 195 177 #else 196 _p rintf("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");178 _puts("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n"); 197 179 _exit(); 198 180 #endif 199 181 } 200 182 201 //////////////////////////////////////////////////////////////////////////////// 202 // This function returns the value contained in a WTI mailbox defined by 203 // the cluster_xy and "wti_index" arguments. This value is written in 204 // the "value" argument, and the corresponding WTI is acknowledged. 205 // returns 0 if success, > 0 if error. 206 //////////////////////////////////////////////////////////////////////////////// 183 /////////////////////////////////////////////////// 207 184 void _xcu_get_wti_value( unsigned int cluster_xy, 208 185 unsigned int wti_index, … … 220 197 221 198 #else 222 _printf("[GIET ERROR] in _xcu_get_wti_value() USE_XCU is not set\n"); 223 _exit(); 224 #endif 225 } 226 227 //////////////////////////////////////////////////////////////////////////////// 228 // This function returns the address of a WTI mailbox defined by 229 // the "wti_index" argument, in the unsigned int "address" argument. 230 // It is used by the GIET to configurate the IOPIC component. 231 // There is no access to a specific XCU component in a specific cluster. 232 // returns 0 if success, > 0 if error. 233 //////////////////////////////////////////////////////////////////////////////// 199 _puts("[GIET ERROR] in _xcu_get_wti_value() USE_XCU is not set\n"); 200 _exit(); 201 #endif 202 } 203 204 //////////////////////////////////////////////////// 234 205 void _xcu_get_wti_address( unsigned int wti_index, 235 206 unsigned int * address ) … … 241 212 242 213 #else 243 _printf("[GIET ERROR] in _xcu_get_wti_address() USE_XCU is not set\n"); 244 _exit(); 245 #endif 246 } 247 248 //////////////////////////////////////////////////////////////////////////////// 249 // This function activates a timer contained in XCU by writing in the 250 // proper register the period value. 251 //////////////////////////////////////////////////////////////////////////////// 214 _puts("[GIET ERROR] in _xcu_get_wti_address() USE_XCU is not set\n"); 215 _exit(); 216 #endif 217 } 218 219 /////////////////////////////////////////////// 252 220 void _xcu_timer_start( unsigned int cluster_xy, 253 221 unsigned int pti_index, … … 264 232 265 233 #else 266 _printf("[GIET ERROR] in _xcu_timer_start() USE_XCU is not set\n"); 267 _exit(); 268 #endif 269 } 270 271 ////////////////////////////////////////////////////////////////////////////// 272 // This function desactivates a timer in XCU component 273 // by writing in the proper register. 274 ////////////////////////////////////////////////////////////////////////////// 234 _puts("[GIET ERROR] in _xcu_timer_start() USE_XCU is not set\n"); 235 _exit(); 236 #endif 237 } 238 239 ////////////////////////////////////////////// 275 240 void _xcu_timer_stop( unsigned int cluster_xy, 276 241 unsigned int pti_index) … … 286 251 287 252 #else 288 _printf("[GIET ERROR] in _xcu_timer_stop() USE_XCU is not set\n"); 289 _exit(); 290 #endif 291 } 292 293 ////////////////////////////////////////////////////////////////////////////// 294 // This function acknowlegge a timer interrupt in XCU 295 // component by reading in the proper XCU register. 296 // It can be used by both the isr_switch() for a "system" timer, 297 // or by the _isr_timer() for an "user" timer. 298 ////////////////////////////////////////////////////////////////////////////// 253 _puts("[GIET ERROR] in _xcu_timer_stop() USE_XCU is not set\n"); 254 _exit(); 255 #endif 256 } 257 258 /////////////////////////////////////////////////////////// 299 259 unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 300 260 unsigned int pti_index ) … … 311 271 312 272 #else 313 _p rintf("[GIET ERROR] in _xcu_timer_reset_irq() USE_XCU is not set\n");273 _puts("[GIET ERROR] in _xcu_timer_reset_irq() USE_XCU is not set\n"); 314 274 _exit(); 315 275 return 0; … … 317 277 } 318 278 319 ////////////////////////////////////////////////////////////////////////////// 320 // This function resets a timer counter. To do so, we re-write the period 321 // in the proper register, what causes the count to restart. 322 // The period value is read from the same (TIMER_PERIOD) register, 323 // this is why in appearance we do nothing useful (read a value 324 // from a register and write this value in the same register). 325 // This function is called during a context switch (user or preemptive) 326 ///////////////////////////////////////////////////////////////////////////// 279 /////////////////////////////////////////////////// 327 280 void _xcu_timer_reset_cpt( unsigned int cluster_xy, 328 281 unsigned int pti_index ) … … 343 296 344 297 #else 345 _p rintf("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XCU is not set\n");298 _puts("[GIET ERROR] in _xcu_timer_reset_cpt() USE_XCU is not set\n"); 346 299 _exit(); 347 300 #endif -
soft/giet_vm/giet_drivers/xcu_driver.h
r320 r437 7 7 // The xcu_driver.c and xcu_driver.h files are part ot the GIET-VM nano-kernel. 8 8 // This driver supports the SoCLib vci_xicu, that is a vectorised interrupt 9 // controler supporting IPI (Inter Processor Interrupts) and integrated timers. 9 // controler supporting three types of interrupts: 10 // 11 // - HWI : HardWare Interrupts (from hardware peripherals) 12 // - PTI : Programmable Timer Interrupts (contained in the XCU component) 13 // - WTI : Write Trigered Interrupts (from software, or from a PIC controller) 10 14 // 11 15 // It can exist several interrupt controller unit in the architecture 12 // (one per cluster), and each one can contain several channels .16 // (one per cluster), and each one can contain several channels: 13 17 // The number of XICU channels is equal to NB_PROCS_MAX, because there is 14 18 // one private XICU channel per processor in a cluster. 15 // //////////////////////////////////////////////////////////////////////////////19 // 16 20 // The virtual base address of the segment associated to the component is: 17 21 // 18 // seg_xcu_base + cluster_xy * vseg_cluster_increment22 // vbase = SEG_XCU_BASE + cluster_xy * PERI_CLUSTER_INCREMENT 19 23 // 20 // The seg_xcu_base and vseg_cluster_incrementvalues must be defined21 // in giet_vsegs.ldfile.24 // The SEG_XCU_BSE and PERI_CLUSTER_INCREMENT values must be defined 25 // in the hard_config.h file. 22 26 //////////////////////////////////////////////////////////////////////////////// 23 27 … … 56 60 #define XCU_REG(func, index) (((func)<<5)|(index)) 57 61 58 //////////////////////////////////////////////////////////////////////////////// ///59 // XICUaccess functions60 //////////////////////////////////////////////////////////////////////////////// ///62 //////////////////////////////////////////////////////////////////////////////// 63 // access functions 64 //////////////////////////////////////////////////////////////////////////////// 61 65 66 //////////////////////////////////////////////////////////////////////////////// 67 // This function set the mask register for the IRQ type defined by "irq_type", 68 // and for the channel identified by the "cluster_xy" and "channel" arguments. 69 // All '1' bits are set / all '0' bits are not modified. 70 //////////////////////////////////////////////////////////////////////////////// 62 71 extern void _xcu_set_mask( unsigned int cluster_xy, 63 72 unsigned int channel, … … 65 74 unsigned int irq_type ); 66 75 76 //////////////////////////////////////////////////////////////////////////////// 77 // This function returns the index and the type of the highest priority 78 // - active PTI (Timer Interrupt), then 79 // - active HWI (Hardware Interrupt), then 80 // - active WTI (Software Interrupt) 81 //////////////////////////////////////////////////////////////////////////////// 67 82 extern void _xcu_get_index( unsigned int cluster_xy, 68 83 unsigned int channel, … … 70 85 unsigned int * irq_type ); 71 86 87 //////////////////////////////////////////////////////////////////////////////// 88 // This function writes the "wdata" value in the mailbox defined 89 // by the "cluster_xy" and "wti_index" arguments. 90 //////////////////////////////////////////////////////////////////////////////// 72 91 extern void _xcu_send_wti( unsigned int cluster_xy, 73 92 unsigned int wti_index, 74 93 unsigned int wdata ); 75 94 95 //////////////////////////////////////////////////////////////////////////////// 96 // This function returns the value contained in a WTI mailbox defined by 97 // the cluster_xy and "wti_index" arguments. This value is written in 98 // the "value" argument, and the corresponding WTI is acknowledged. 99 //////////////////////////////////////////////////////////////////////////////// 76 100 extern void _xcu_get_wti_value( unsigned int cluster_xy, 77 101 unsigned int wti_index, 78 102 unsigned int * value ); 79 103 104 //////////////////////////////////////////////////////////////////////////////// 105 // This function returns the address of a WTI mailbox defined by 106 // the "wti_index" argument, in the unsigned int "address" argument. 107 // It is used by the GIET to configurate the IOPIC component. 108 // There is no access to a specific XCU component in a specific cluster. 109 //////////////////////////////////////////////////////////////////////////////// 80 110 extern void _xcu_get_wti_address( unsigned int wti_index, 81 111 unsigned int * address ); 82 112 113 //////////////////////////////////////////////////////////////////////////////// 114 // This function activates a timer contained in XCU by writing in the 115 // proper register the period value. 116 //////////////////////////////////////////////////////////////////////////////// 83 117 extern void _xcu_timer_start( unsigned int cluster_xy, 84 118 unsigned int pti_index, 85 119 unsigned int period ); 86 120 121 ////////////////////////////////////////////////////////////////////////////// 122 // This function desactivates a timer in XCU component 123 // by writing in the proper register. 124 ////////////////////////////////////////////////////////////////////////////// 87 125 extern void _xcu_timer_stop( unsigned int cluster_xy, 88 126 unsigned int pti_index ); 89 127 128 ////////////////////////////////////////////////////////////////////////////// 129 // This function acknowlegge a timer interrupt in XCU 130 // component by reading in the proper XCU register. 131 // It can be used by both the isr_switch() for a "system" timer, 132 // or by the _isr_timer() for an "user" timer. 133 ////////////////////////////////////////////////////////////////////////////// 90 134 extern unsigned int _xcu_timer_reset_irq( unsigned int cluster_xy, 91 135 unsigned int pti_index ); 92 136 137 ////////////////////////////////////////////////////////////////////////////// 138 // This function resets a timer counter. To do so, we re-write the period 139 // in the proper register, what causes the count to restart. 140 // The period value is read from the same (TIMER_PERIOD) register, 141 // this is why in appearance we do nothing useful (read a value 142 // from a register and write this value in the same register). 143 // This function is called during a context switch (user or preemptive) 144 ///////////////////////////////////////////////////////////////////////////// 93 145 extern void _xcu_timer_reset_cpt( unsigned int cluster_xy, 94 146 unsigned int pti_index ); 95 96 ///////////////////////////////////////////////////////////////////////////////////97 147 98 148 #endif
Note: See TracChangeset
for help on using the changeset viewer.