Changeset 188 for trunk/kernel/devices
- Timestamp:
- Jul 12, 2017, 8:12:41 PM (7 years ago)
- Location:
- trunk/kernel/devices
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/devices/dev_dma.c
r23 r188 40 40 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 41 41 42 extern chdev_icu_input_t chdev_icu_input; // allocated in kernel_init.c43 44 42 //////////////////////////////////// 45 43 void dev_dma_init( chdev_t * chdev ) … … 64 62 } 65 63 66 // get DMA HWI IRQ index67 uint32_t hwi_id = chdev_icu_input.dma[channel];64 // bind IRQ to the core defined by the DMA channel 65 dev_pic_bind_irq( channel , chdev ); 68 66 69 // enable HWI IRQ in local ICU, and update interrupt vector 70 // the selected core is defined by the DMA channel index 71 dev_icu_enable_irq( channel , HWI_TYPE , hwi_id , chdev ); 67 // enable IRQ 68 dev_pic_enable_irq( channel, chdev ); 72 69 73 70 // create server thread … … 90 87 // start server thread 91 88 thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL ); 92 89 93 90 } // dev_dma_init() 94 91 -
trunk/kernel/devices/dev_fbf.c
r65 r188 41 41 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 42 42 43 extern chdev_pic_input_t chdev_input_irq; // allocated in kernel_init.c44 45 43 //////////////////////////////////// 46 void dev_fbf_init( chdev_t * chdev, 47 uint32_t width, 48 uint32_t height ) 44 void dev_fbf_init( chdev_t * chdev ) 49 45 { 50 46 // set FBF chdev extension fields 51 // TODO for the "width" and "height", fields,this should be done in the impementation47 // TODO this should be done in the impementation 52 48 // TODO specific part, as these parameters must be obtained from the hardware. 53 chdev->ext.fbf.width = width;54 chdev->ext.fbf.height = height;49 chdev->ext.fbf.width = CONFIG_FBF_WIDTH; 50 chdev->ext.fbf.height = CONFIG_FBF_HEIGHT; 55 51 56 52 // get implementation … … 59 55 // set chdev name 60 56 strcpy( chdev->name, "fbf" ); 57 61 58 // call driver init function 62 59 if( impl == IMPL_FBF_SCL ) -
trunk/kernel/devices/dev_fbf.h
r3 r188 90 90 91 91 /****************************************************************************************** 92 * This function completes the FBF chdev descriptor initialisation, 93 * namely the width and height parameters. 94 * TODO : these parameters should be provided by the hardware through a dedicated 95 * software API ... 92 * This function completes the FBF chdev descriptor initialisation. 96 93 * It calls the specific driver initialisation function, to initialise the hardware 97 94 * device and the specific data structures when required by the implementation. 98 95 * It must be called by a local thread. 96 * 97 * TODO In this first approach, the "width" and "height" parameters are defined 98 * by the CONFIG_FBF_WIDTH & CONFIG_FBF_HEIGHT in the kernel_config.h file. 99 * These parameters should be provided by the driver, accessing dedicated 100 * adressable registers in the FBF controler. 99 101 ****************************************************************************************** 100 102 * @ chdev : pointer on FBF chdev descriptor. 101 * @ width : number of pixels (bytes) per line.102 * @ height : total number of lines.103 103 *****************************************************************************************/ 104 void dev_fbf_init( struct chdev_s * chdev, 105 uint32_t width, 106 uint32_t height ); 104 void dev_fbf_init( struct chdev_s * chdev ); 107 105 108 106 /****************************************************************************************** -
trunk/kernel/devices/dev_ioc.c
r101 r188 39 39 ///////////////////////////////////////////////////////////////////////////////////////// 40 40 41 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 42 43 extern chdev_pic_input_t chdev_pic_input; // allocated in kernel_init.c 44 45 //////////////////////////////////// 46 void dev_ioc_init( chdev_t * chdev ) 47 { 48 // the local ICU chdev must be initialized before the IOC chdev, because 49 // the IOC chdev initialisation requires allocation of a WTI from local ICU 50 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 51 assert( (icu_xp != XPTR_NULL) , __FUNCTION__ , "ICU not initialised before IOC" ); 41 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 42 43 ////////////////////////////////// 44 void dev_ioc_init( chdev_t * ioc ) 45 { 46 // the PIC chdev must be initialized before the IOC chdev, because 47 // the IOC chdev initialisation requires the routing of an external IRQ 48 xptr_t pic_xp = chdev_dir.pic; 49 50 assert( (pic_xp != XPTR_NULL) , __FUNCTION__ , "PIC not initialised before IOC" ); 52 51 53 52 // get implementation and channel from chdev descriptor 54 uint32_t impl = chdev->impl;55 uint32_t channel = chdev->channel;53 uint32_t impl = ioc->impl; 54 uint32_t channel = ioc->channel; 56 55 57 56 // set chdev name 58 s trcpy( chdev->name , "ioc");57 snprintf( ioc->name , 16 , "ioc_%d" , channel ); 59 58 60 59 // set driver specific fields in chdev descriptor and call driver init function 61 60 if( impl == IMPL_IOC_BDV ) 62 61 { 63 chdev->cmd = &soclib_bdv_cmd;64 chdev->isr = &soclib_bdv_isr;65 soclib_bdv_init( chdev);62 ioc->cmd = &soclib_bdv_cmd; 63 ioc->isr = &soclib_bdv_isr; 64 soclib_bdv_init( ioc ); 66 65 } 67 66 else if( impl == IMPL_IOC_HBA ) 68 67 { 69 chdev->cmd = &soclib_hba_cmd;70 chdev->isr = &soclib_hba_isr;71 soclib_hba_init( chdev);68 ioc->cmd = &soclib_hba_cmd; 69 ioc->isr = &soclib_hba_isr; 70 soclib_hba_init( ioc ); 72 71 } 73 72 else … … 76 75 } 77 76 78 // get a WTI mailbox from local ICU 79 uint32_t wti_id = dev_icu_wti_alloc(); 80 81 assert( (wti_id != -1) , __FUNCTION__ , "cannot allocate WTI mailbox" ); 82 83 // select a core 77 // select a core to execute the IOC server thread 84 78 lid_t lid = cluster_select_local_core(); 85 79 86 // enable WTI IRQ and update WTI interrupt vector 87 dev_icu_enable_irq( lid , WTI_TYPE , wti_id , chdev ); 88 89 // link IOC IRQ to WTI mailbox in PIC component 90 uint32_t irq_id = chdev_pic_input.ioc[channel]; 91 dev_pic_bind_irq( irq_id , local_cxy , wti_id ); 80 // bind the IOC IRQ to the selected core 81 dev_pic_bind_irq( lid , ioc ); 82 83 // enable IRQ 84 dev_pic_enable_irq( lid ,ioc ); 92 85 93 86 // create server thread … … 98 91 THREAD_DEV, 99 92 &chdev_sequencial_server, 100 chdev,93 ioc, 101 94 lid ); 95 102 96 assert( (error == 0) , __FUNCTION__ , "cannot create server thread" ); 103 97 104 // set "server" field in chdevdescriptor105 chdev->server = new_thread;98 // set "server" field in ioc descriptor 99 ioc->server = new_thread; 106 100 107 101 // start server thread -
trunk/kernel/devices/dev_ioc.h
r23 r188 108 108 typedef struct ioc_command_s 109 109 { 110 xptr_t dev_xp; /*! extended pointer on device descriptor*/110 xptr_t dev_xp; /*! extended pointer on IOC device descriptor */ 111 111 uint32_t type; /*! IOC_READ / IOC_WRITE / IOC_SYNC_READ */ 112 112 uint32_t lba; /*! first block index */ -
trunk/kernel/devices/dev_mmc.c
r23 r188 35 35 36 36 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 37 38 extern chdev_icu_input_t chdev_icu_input; // allocated in kernel_init.c39 37 40 38 //////////////////////////////////// … … 59 57 } 60 58 61 // get MMC HWI IRQ index 62 uint32_t hwi_id = chdev_icu_input.mmc; 63 64 // enable HWI IRQ to CP0 in local ICU, and update interrupt vector 65 dev_icu_enable_irq( 0 , HWI_TYPE , hwi_id , chdev ); 59 // bind IRQ to CP0 60 dev_pic_bind_irq( 0 , chdev ); 66 61 62 // enable IRQ 63 dev_pic_enable_irq( 0 , chdev ); 64 67 65 } // end dev_mmc_init() 68 66 -
trunk/kernel/devices/dev_nic.c
r23 r188 2 2 * dev_nic.c - NIC (Network Controler) generic device API implementation. 3 3 * 4 * Author Alain Greiner (2016 )4 * Author Alain Greiner (2016,2017) 5 5 * 6 6 * Copyright (c) UPMC Sorbonne Universites … … 36 36 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 37 37 38 extern chdev_pic_input_t chdev_pic_input; // allocated in kernel_init.c 39 40 //////////////////////////////////// 41 void dev_nic_init( chdev_t * chdev ) 38 ////////////////////////////////// 39 void dev_nic_init( chdev_t * nic ) 42 40 { 43 // the local ICU chdev must be initialized before the NIC chdev, because 44 // the NIC chdevs initialisation requires allocation of a WTI from local ICU 45 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 46 assert( (icu_xp != XPTR_NULL) , __FUNCTION__ , "ICU not initialised before NIC" ); 41 // the PIC chdev must be initialized before the NIC chdev, because 42 // the NIC chdev initialisation requires the routing of an external IRQ. 43 xptr_t pic_xp = chdev_dir.pic; 44 45 assert( (pic_xp != XPTR_NULL) , __FUNCTION__ , "ICU not initialised before NIC" ); 47 46 48 47 // get "impl" , "channel" , "is_rx" fields from chdev descriptor 49 uint32_t impl = chdev->impl;50 uint32_t is_rx = chdev->is_rx;51 uint32_t channel = chdev->channel;48 uint32_t impl = nic->impl; 49 uint32_t channel = nic->channel; 50 bool_t is_rx = nic->is_rx; 52 51 53 52 // set chdev name 54 snprintf( chdev->name , 16 , "nic_%d" , chdev->channel ); 53 if( is_rx ) snprintf( nic->name , 16 , "nic_rx_%d" , channel ); 54 else snprintf( nic->name , 16 , "nic_tx_%d" , channel ); 55 55 56 56 // set driver specific fields in chdev descriptor and call driver init function 57 57 if( impl == IMPL_NIC_SOC ) 58 58 { 59 chdev->cmd = &soclib_nic_cmd;60 chdev->isr = &soclib_nic_isr;61 soclib_nic_init( chdev);59 nic->cmd = &soclib_nic_cmd; 60 nic->isr = &soclib_nic_isr; 61 soclib_nic_init( nic ); 62 62 } 63 63 else … … 66 66 } 67 67 68 // get a WTI mailbox from local ICU 69 uint32_t wti_id = dev_icu_wti_alloc(); 70 71 assert( (wti_id != -1) , __FUNCTION__ , "cannot allocate WTI mailbox" ); 72 73 // select a core 68 // select a core to execute the NIC server thread 74 69 lid_t lid = cluster_select_local_core(); 75 70 76 // enable WTI IRQ and update WTI interrupt vector 77 dev_icu_enable_irq( lid , WTI_TYPE , wti_id , chdev ); 78 79 // link NIC IRQ to WTI mailbox in PIC component 80 uint32_t irq_id; 81 if( is_rx ) irq_id = chdev_pic_input.nic_rx[channel]; 82 else irq_id = chdev_pic_input.nic_tx[channel]; 83 dev_pic_bind_irq( irq_id , local_cxy , wti_id ); 71 // bind the NIC IRQ to the selected core 72 // but does NOT enable it 73 dev_pic_bind_irq( lid , nic ); 84 74 85 75 // create server thread … … 90 80 THREAD_DEV, 91 81 &chdev_sequencial_server, 92 chdev,82 nic, 93 83 lid ); 94 84 … … 96 86 97 87 // set "server" field in chdev descriptor 98 chdev->server = new_thread;88 nic->server = new_thread; 99 89 100 90 // start server thread … … 142 132 if( thread_ptr->command.nic.status == false ) 143 133 { 144 // get NIC-RX IRQ index and type145 uint32_t irq_type = dev_ptr->irq_type;146 uint32_t irq_id = dev_ptr->irq_id;147 148 134 // enable NIC-RX IRQ 149 dev_ icu_enable_irq( core->lid , irq_type , irq_id , dev_ptr );150 151 // block on THREAD_BLOCKED I/O condition and deschedule135 dev_pic_enable_irq( core->lid , dev_ptr ); 136 137 // block on THREAD_BLOCKED_IO condition and deschedule 152 138 thread_block( thread_ptr , THREAD_BLOCKED_IO ); 153 139 sched_yield(); 154 140 155 // disable NIC-RX channelIRQ156 dev_ icu_disable_irq( core->lid , irq_type , irq_id);141 // disable NIC-RX IRQ 142 dev_pic_disable_irq( core->lid , dev_ptr ); 157 143 } 158 144 … … 206 192 207 193 // call driver to test writable 208 thread_ptr->command.nic.cmd 194 thread_ptr->command.nic.cmd = NIC_CMD_WRITABLE; 209 195 dev_ptr->cmd( thread_xp ); 210 196 … … 216 202 if( thread_ptr->command.nic.status == false ) 217 203 { 218 // get NIC-TX IRQ index and type219 uint32_t irq_type = dev_ptr->irq_type;220 uint32_t irq_id = dev_ptr->irq_id;221 222 204 // enable NIC-TX IRQ 223 dev_ icu_enable_irq( core->lid , irq_type , irq_id ,dev_ptr );205 dev_pic_enable_irq( core->lid ,dev_ptr ); 224 206 225 207 // block on THREAD_BLOCKED I/O condition and deschedule … … 228 210 229 211 // disable NIC-TX IRQ 230 dev_ icu_disable_irq( core->lid , irq_type , irq_id);212 dev_pic_disable_irq( core->lid , dev_ptr ); 231 213 } 232 214 -
trunk/kernel/devices/dev_pic.c
r23 r188 24 24 #include <hal_types.h> 25 25 #include <hal_special.h> 26 #include <dev_icu.h>27 26 #include <chdev.h> 28 #include <memcpy.h>29 27 #include <printk.h> 30 28 #include <soclib_pic.h> 31 29 #include <dev_pic.h> 30 #include <cluster.h> 32 31 33 32 ///////////////////////////////////////////////////////////////////////////////////////// … … 37 36 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 38 37 39 extern chdev_pic_input_t chdev_pic_input; // allocated in kernel_init.c40 41 38 /////////////////////////////////// 42 void dev_pic_init( chdev_t * chdev, 43 uint32_t irq_nr ) 39 void dev_pic_init( chdev_t * pic ) 44 40 { 45 // set PIC chdev extension field46 chdev->ext.pic.irq_nr = irq_nr;47 48 41 // get implementation 49 uint32_t impl = chdev->impl;42 uint32_t impl = pic->impl; 50 43 51 44 // set chdev name 52 strcpy( chdev->name , "pic" ); 53 54 // call the relevant driver init function 55 if( impl == IMPL_PIC_SOC ) 45 strcpy( pic->name , "pic" ); 46 47 // call the relevant driver init function, 48 // and register commands in PIC device extension 49 if( impl == IMPL_PIC_SCL ) 56 50 { 57 soclib_pic_init( chdev ); 51 // call the PIC SOCLIB driver 52 soclib_pic_init( pic ); 53 54 // update the PIC chdev extension 55 pic->ext.pic.enable_timer = &soclib_pic_enable_timer; 56 pic->ext.pic.enable_irq = &soclib_pic_enable_irq; 57 pic->ext.pic.disable_irq = &soclib_pic_disable_irq; 58 pic->ext.pic.bind_irq = &soclib_pic_bind_irq; 59 pic->ext.pic.send_ipi = &soclib_pic_send_ipi; 60 pic->ext.pic.extend_init = &soclib_pic_extend_init; 61 } 62 else if( impl == IMPL_PIC_I86 ) 63 { 64 assert( false , __FUNCTION__ , "missing implementation for X86\n" ); 58 65 } 59 66 else 60 67 { 61 assert( false , __FUNCTION__ , " illegalPIC device implementation" );68 assert( false , __FUNCTION__ , "undefined PIC device implementation" ); 62 69 } 63 70 } // end dev_pic_init() 64 71 65 ///////////////////////////////////////// 66 void dev_pic_bind_irq( uint32_t irq_id, 67 cxy_t cxy, 68 uint32_t wti_id ) 72 ///////////////////////////////////////////////// 73 void dev_pic_extend_init( uint32_t * lapic_base ) 69 74 { 70 // get extended pointer on WTI mailbox71 xptr_t wti_xp = XPTR( cxy , dev_icu_wti_ptr( wti_id ));75 // get pointer on PIC chdev 76 chdev_t * pic = (chdev_t *)GET_PTR( chdev_dir.pic ); 72 77 73 // get extended pointer on PIC chdev from directory 74 xptr_t dev_xp = chdev_dir.pic; 78 // call relevant driver function 79 pic->ext.pic.extend_init( lapic_base ); 80 } 75 81 76 // get PIC chdev cluster and local pointer 77 cxy_t dev_cxy = GET_CXY( dev_xp ); 78 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp ); 82 ///////////////////////////////////// 83 void dev_pic_bind_irq( lid_t lid, 84 chdev_t * src_chdev ) 85 { 86 // get pointer on PIC chdev 87 chdev_t * pic = (chdev_t *)GET_PTR( chdev_dir.pic ); 79 88 80 // get implementation index and segment base 81 uint32_t impl = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->impl ) ); 89 // call relevant driver function 90 pic->ext.pic.bind_irq( lid , src_chdev ); 91 } 82 92 83 // call the implementation specific driver function 84 if( impl == IMPL_PIC_SOC ) 85 {86 soclib_pic_bind_irq( dev_xp , irq_id , wti_xp ); 87 }88 } // end dev_pic_link_wti() 93 /////////////////////////////////////// 94 void dev_pic_enable_irq( lid_t lid, 95 chdev_t * src_chdev ) 96 { 97 // get pointer on PIC chdev 98 chdev_t * pic = (chdev_t *)GET_PTR( chdev_dir.pic ); 89 99 90 ////////////////////////////////////////// 91 void dev_pic_unbind_irq( uint32_t irq_id ) 100 // call relevant driver function 101 pic->ext.pic.enable_irq( src_chdev ); 102 } 103 104 //////////////////////////////////////// 105 void dev_pic_disable_irq( lid_t lid, 106 chdev_t * src_chdev ) 92 107 { 93 // get extended pointer on PIC chdev from directory94 xptr_t dev_xp = chdev_dir.pic;108 // get pointer on PIC chdev 109 chdev_t * pic = (chdev_t *)GET_PTR( chdev_dir.pic ); 95 110 96 // get PIC chdev cluster and local pointer97 cxy_t dev_cxy = GET_CXY( dev_xp);98 chdev_t * dev_ptr = (chdev_t *)GET_PTR( dev_xp ); 111 // call relevant driver function 112 pic->ext.pic.disable_irq( src_chdev ); 113 } 99 114 100 // get implementation index 101 uint32_t impl = hal_remote_lw( XPTR( dev_cxy , &dev_ptr->impl ) ); 115 //////////////////////////////////////////// 116 void dev_pic_enable_timer( uint32_t period ) 117 { 118 // get pointer on PIC chdev 119 chdev_t * pic = (chdev_t *)GET_PTR( chdev_dir.pic ); 102 120 103 // call the implementation specific driver function 104 if( impl == IMPL_PIC_SOC ) 105 { 106 soclib_pic_unbind_irq( dev_xp , irq_id ); 107 } 108 } // end dev_pic_disable_irq() 121 // call relevant driver function 122 pic->ext.pic.enable_timer( period ); 123 } 124 125 ////////////////////////////////// 126 void dev_pic_send_ipi( cxy_t cxy, 127 lid_t lid ) 128 { 129 // get pointer on PIC chdev 130 chdev_t * pic = (chdev_t *)GET_PTR( chdev_dir.pic ); 131 132 // call relevant driver function 133 pic->ext.pic.send_ipi( cxy , lid ); 134 } 109 135 110 136 -
trunk/kernel/devices/dev_pic.h
r14 r188 1 1 /* 2 * dev_pic.h - PIC ( ExternalInterrupt Controler) generic device API definition.2 * dev_pic.h - PIC (Programmable Interrupt Controler) generic device API definition. 3 3 * 4 4 * Authors Alain Greiner (2016) … … 29 29 30 30 /***************************************************************************************** 31 * Generic External Interrupt Controler definition 32 * 33 * The PIC generic device describes an external interrupt Controler, that translates 34 * N input IRQs generated by external peripherals to N WTI IRQs, that will be routed 35 * to a dynamically allocated WTI mailbox in a given cluster. 36 * 37 * The max number of input IRQs is defined by the CONFIG_MAX_IRQS_PER_PIC parameter. 38 * The actual number of connected IRQs is defined in the ''arch_info'' file, and stored 39 * in the PIC device extension. 40 * The "source" device for each input IRQ is also defined in the ''arch_info'' file, 41 * and are stored in the ''chdev_input_irq'' global variable in kernel initialization. 42 * 43 * This external peripheral does not execute I/O operations, but is just acting as a 44 * dynamically configurable interrupt router for another I/O operation. Therefore, 45 * ALMOS-MKH does not use the PIC device waiting queue, but call directly the relevant 46 * driver blocking functions to dynamically "bind" or "unbind" an external IRQ to a 47 * WTI mailbox. 31 * Generic Programmable Interrupt Controler definition 32 * 33 * The PIC generic device describes the the programmable hardware infrastructure used 34 * to route a given IRQ to a given core, in a given cluster, and to help the interrupt 35 * handler to select and execute the relevant ISR (Interrupt Service Routine). 36 * It handles the following type of interrupts: 37 * - External IRQs generated by the external (shared) peripherals. 38 * - Internal IRQs generated by the internal (replicated) peripherals. 39 * - Timer IRQs generated by the timers (one timer per core). 40 * - Inter Processor IRQs (IPI) generated by software. 41 * 42 * In most supported manycores architectures, the PIC device contains two types 43 * of hardware components: 44 * - the IOPIC is an external component, handling all external peripherals IRQs. 45 * - The LAPIC is an internal component, replicated in each cluster, handling local 46 * peripherals IRQS, Timer IRQs and IPIs (inter-processor-interupts). 47 * 48 * The "source" device for each input IRQ to the external IOPIC component, is defined 49 * in the "arch_info" file, and registered in the "iopic_input" global variable 50 * at kernel initialization. 51 * 52 * The "source" device for each input IRQ to the replicated LAPIC components, is defined 53 * in the "arch_info" file, and stored in the "lapic_input" global variable 54 * at kernel initialization. 55 * 56 * The PIC device defines 4 generic commands that can be used by each kernel instance, 57 * - to create in local cluster the PIC implementation specific interupt vector(s), 58 * - to bind a given IRQ (internal or external IRQ to a given core in the local cluster, 59 * - to configure and activate the TICK timer for a given core in the local cluster, 60 * - to allows the software to send an IPI to any core in any cluster. 61 * This API is detailed below, and must be implemented by all PIC implementations. 62 * 63 * In each cluster, a PIC implementation specific structure can be linked to the 64 * cluster manager or to the core descriptors to register the interrupt vectors 65 * used by the kernel to select the relevant ISR when an interrupt is received 66 * by a given core in agiven cluster. 67 68 * This PIC device does not execute itself I/O operations. It is just acting as a 69 * configurable interrupt router for I/O operation executed by other peripherals. 70 * Therefore, ALMOS-MKH does not use the PIC device waiting queue, does not creates 71 * a server thread for the PIC device, and does not register the command in the calling 72 * thread descriptor, but call directly the relevant driver function. 48 73 ****************************************************************************************/ 49 74 … … 53 78 54 79 /***************************************************************************************** 55 * This defines the (implementation independant) extension for the PIC device. 56 ****************************************************************************************/ 57 80 * This defines the specific extension for the PIC chdev descriptor. 81 * It contains four function pointers on the four PIC command types, 82 * that must be implemented by all drivers. 83 ****************************************************************************************/ 84 85 typedef void (pic_bind_t) ( lid_t lid , struct chdev_s * src_chdev ); 86 typedef void (pic_enable_t) ( struct chdev_s * src_chdev ); 87 typedef void (pic_disable_t) ( struct chdev_s * src_chdev ); 88 typedef void (pic_timer_t) ( uint32_t period ); 89 typedef void (pic_ipi_t) ( cxy_t cxy , lid_t lid ); 90 typedef void (pic_init_t) ( uint32_t * lapic_base ); 91 58 92 typedef struct pic_extend_s 59 93 { 60 uint32_t irq_nr; /*! actual number of input IRQs to the PIC device */ 94 pic_bind_t * bind_irq; /*! pointer on the driver "bind_irq" function */ 95 pic_enable_t * enable_irq; /*! pointer on the driver "enable_irq" function */ 96 pic_disable_t * disable_irq; /*! pointer on the driver "disable_irq" function */ 97 pic_timer_t * enable_timer; /*! pointer on the driver "enable_timer" function */ 98 pic_ipi_t * send_ipi; /*! pointer on the driver "send_ipi" function */ 99 pic_init_t * extend_init; /*! pointer on the driver "init_extend" function */ 61 100 } 62 101 pic_extend_t; 63 102 64 /***************************************************************************************** 65 * This enum defines the various implementations of the PIC external interrupt controller. 103 /****************************************************************************************** 104 * This structure defines the input IRQS for the external IOPIC controller, that is used 105 * by external peripherals (IOC, NIC, TXT, etc.) to signal completion of an I/O operation. 106 * It describes the hardware wiring of IRQs between external peripherals and the IOPIC, 107 * as each entry contains the input IRQ index in IOPIC. 108 * For a multi-channels peripheral, there is one chdev and one IRQ per channel. 109 * This structure is replicated in each cluster. It is allocated as a global variable 110 * in the kernel_init.c file. 111 *****************************************************************************************/ 112 113 typedef struct iopic_input_s 114 { 115 uint32_t txt[CONFIG_MAX_TXT_CHANNELS]; 116 uint32_t ioc[CONFIG_MAX_IOC_CHANNELS]; 117 uint32_t nic_rx[CONFIG_MAX_NIC_CHANNELS]; 118 uint32_t nic_tx[CONFIG_MAX_NIC_CHANNELS]; 119 uint32_t iob; 120 } 121 iopic_input_t; 122 123 /****************************************************************************************** 124 * This structure defines the input IRQS for the internal LAPIC controllers, that are used 125 * by internal peripherals IRQS (DMA, MMC) to signal completion of an I/O operation. 126 * It describes the hardware wiring of IRQs between internal peripherals and ICU, 127 * as each entry contains the input IRQ index in the LAPIC component. 128 * For a multi-channels peripheral, there is one chdev and one IRQ per channel. 129 * This structure is replicated in each cluster. It is allocated as a global variable 130 * in the kernel_init.c file. 131 *****************************************************************************************/ 132 133 typedef struct lapic_input_s 134 { 135 uint32_t dma[CONFIG_MAX_DMA_CHANNELS]; 136 uint32_t mmc; // MMC is single channel 137 } 138 lapic_input_t; 139 140 /***************************************************************************************** 141 * This enum defines the various implementations of the PIC device. 66 142 * This array must be kept consistent with the define in arch_info.h file 67 143 ****************************************************************************************/ … … 69 145 enum pic_impl_e 70 146 { 71 IMPL_PIC_S OC= 0,147 IMPL_PIC_SCL = 0, 72 148 IMPL_PIC_I86 = 1, 73 149 } … … 75 151 76 152 /***************************************************************************************** 77 * This function makes two initialisations :153 * This function makes two initialisations : 78 154 * - It initializes the PIC specific fields of the chdev descriptor. 79 * - it initializes the implementation specific PIC hardware device. 80 * It must be executed once in the kernel initialisation phase. 81 ***************************************************************************************** 82 * @ xp_dev : extended pointer on PIC device descriptor. 83 * @ uint32_t : actual number of input IRQs. 84 ****************************************************************************************/ 85 void dev_pic_init( struct chdev_s * chdev, 86 uint32_t irq_nr ); 87 88 /***************************************************************************************** 89 * This function link a WTI mailbox to the PIC input IRQ identified by its index, 90 * and unmask the selected input IRQ, calling the relevant driver. 91 ***************************************************************************************** 92 * @ irq_id : input IRQ index. 93 * @ cxy : WTI mailbox cluster. 94 * @ wti_id : WTI mailbox index in cluster. 95 ****************************************************************************************/ 96 void dev_pic_bind_irq( uint32_t irq_id, 97 cxy_t cxy, 98 uint32_t wti_id ); 99 100 /***************************************************************************************** 101 * This function mask a PIC input IRQ identified by its index, calling te relevant driver. 102 ***************************************************************************************** 103 * @ irq_id : input IRQ index. 104 ****************************************************************************************/ 105 void dev_pic_unbind_irq( uint32_t irq_id ); 106 155 * - it initializes the implementation specific PIC hardware registers. 156 * It is executed once in cluster containing the PIC chdev, during kernel initialisation. 157 * The calling core goes to sleep in case of failure. 158 ***************************************************************************************** 159 * @ pic : local pointer on PIC device descriptor. 160 ****************************************************************************************/ 161 void dev_pic_init( struct chdev_s * pic ); 162 163 /***************************************************************************************** 164 * This function completes the PIC infrastructure initialisation in each cluster. 165 * It allocates memory for the local PIC extensions in the core descriptors and/or 166 * in the cluster manager, as required by the specific PIC implementation. 167 * This function is called by CPO in all clusters, during kernel initialisation phase. 168 * The calling core goes to sleep in case of failure. 169 ***************************************************************************************** 170 * @ lapic_base : local pointer on LAPIC component segment base. 171 ****************************************************************************************/ 172 void dev_pic_extend_init( uint32_t * lapic_base ); 173 174 /***************************************************************************************** 175 * This function configure the PIC device to route the IRQ generated by a local chdev, 176 * defined by the <src_chdev> argument, to a local core identified by the <lid> argument. 177 * This is a static binding, defined during kernel init: IRQ can be enabled/disabled, 178 * but the binding cannot be released. It can be used for both internal & external IRQs. 179 * WARNING : the IRQ must be explicitely enabled by the dev_pic_enable_irq() function. 180 ***************************************************************************************** 181 * @ lid : target core local index. 182 * @ src_chdev : local pointer on source chdev descriptor. 183 ****************************************************************************************/ 184 void dev_pic_bind_irq( lid_t lid, 185 struct chdev_s * src_chdev ); 186 187 /***************************************************************************************** 188 * This function disables the IRQ generated by a local chdev, defined by the <src_chdev> 189 * argument. It can be used for both internal & external IRQs. 190 ***************************************************************************************** 191 * @ lid : target core local index. 192 * @ src_chdev : local pointer on source chdev descriptor. 193 ****************************************************************************************/ 194 void dev_pic_disable_irq( lid_t lid, 195 struct chdev_s * src_chdev ); 196 197 /***************************************************************************************** 198 * This function enables the IRQ generated by a local chdev, defined by the <src_chdev> 199 * argument. It can be used for both internal & external IRQs. 200 ***************************************************************************************** 201 * @ lid : target core local index. 202 * @ src_chdev : local pointer on source chdev descriptor. 203 ****************************************************************************************/ 204 void dev_pic_enable_irq( lid_t lid, 205 struct chdev_s * src_chdev ); 206 207 /***************************************************************************************** 208 * This function activates the TICK timer for the calling core. 209 * The <period> argument define the number of cycles between IRQs. 210 ***************************************************************************************** 211 * @ period : number of cycles between IRQs. 212 ****************************************************************************************/ 213 void dev_pic_enable_timer( uint32_t period ); 214 215 /***************************************************************************************** 216 * This function allows the calling thread to send an IPI to any core in any cluster. 217 * The target core is identified by the <cxy> & <lid> arguments. 218 ***************************************************************************************** 219 * @ cxy : target core cluster. 220 * @ lid : target core local index. 221 ****************************************************************************************/ 222 void dev_pic_send_ipi( cxy_t cxy, 223 lid_t lid ); 224 107 225 108 226 #endif /* _DEV_PIC_H_ */ -
trunk/kernel/devices/dev_txt.c
r101 r188 38 38 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 39 39 40 extern chdev_pic_input_t chdev_pic_input; // allocated in kernel_init.c 40 ////////////////////////////////// 41 void dev_txt_init( chdev_t * txt ) 42 { 43 // For all TXT channels other than the TXT0 (kernel terminal), 44 // the PIC chdev must be initialized before the TXT chdev, because 45 // the TXT chdev initialization requires the routing of an external IRQ 41 46 42 //////////////////////////////////// 43 void dev_txt_init( chdev_t * chdev ) 44 { 45 // the local ICU chdev must be initialized before the TXT chdev, because 46 // the TXT chdev initialization requires allocation of a WTI from local ICU 47 xptr_t icu_xp = chdev_dir.icu[local_cxy]; 48 assert( (icu_xp != XPTR_NULL) , __FUNCTION__ , "ICU not initialised before TXT" ); 47 xptr_t pic_xp = chdev_dir.pic; 48 uint32_t channel = txt->channel; 49 uint32_t impl = txt->impl; 49 50 50 // get implementation and channel index 51 uint32_t impl = chdev->impl; 52 uint32_t channel = chdev->channel; 51 assert( (pic_xp != XPTR_NULL) || (channel == 0) , __FUNCTION__ , 52 "PIC not initialised before TXT" ); 53 53 54 54 // set chdev name 55 snprintf( chdev->name , 16 , "txt_%d" , chdev->channel );55 snprintf( txt->name , 16 , "txt_%d" , channel ); 56 56 57 57 // set fields "cmd", "isr", and call driver init function 58 58 if( impl == IMPL_TXT_TTY ) 59 59 { 60 chdev->cmd = &soclib_tty_cmd;61 chdev->isr = &soclib_tty_isr;62 soclib_tty_init( chdev);60 txt->cmd = &soclib_tty_cmd; 61 txt->isr = &soclib_tty_isr; 62 soclib_tty_init( txt ); 63 63 } 64 64 else … … 67 67 } 68 68 69 // get a WTI mailbox from local ICU 70 uint32_t wti_id = dev_icu_wti_alloc(); 69 // no server thread and no IRQ routing for TXT0 70 if( channel != 0 ) 71 { 72 // select a core to execute the TXT server thread 73 lid_t lid = cluster_select_local_core(); 71 74 72 assert( (wti_id != -1) , __FUNCTION__ , "cannot allocate WTI mailbox" ); 75 // bind TXT IRQ to the selected core 76 dev_pic_bind_irq( lid , txt ); 73 77 74 // select a core75 lid_t lid = cluster_select_local_core();78 // enable TXT IRQ 79 dev_pic_enable_irq( lid , txt ); 76 80 77 // enable WTI IRQ and update WTI interrupt vector 78 dev_icu_enable_irq( lid , WTI_TYPE , wti_id , chdev ); 81 // create server thread 82 thread_t * new_thread; 83 error_t error; 79 84 80 // link IOC IRQ to WTI mailbox in PIC component 81 uint32_t irq_id = chdev_pic_input.txt[channel]; 82 dev_pic_bind_irq( irq_id , local_cxy , wti_id ); 85 error = thread_kernel_create( &new_thread, 86 THREAD_DEV, 87 &chdev_sequencial_server, 88 txt, 89 lid ); 83 90 84 // create server thread 85 thread_t * new_thread; 86 error_t error; 91 assert( (error == 0) , __FUNCTION__ , "cannot create server thread" ); 87 92 88 error = thread_kernel_create( &new_thread, 89 THREAD_DEV, 90 &chdev_sequencial_server, 91 chdev, 92 lid ); 93 assert( (error == 0) , __FUNCTION__ , "cannot create server thread" ); 93 // set "server" field in chdev descriptor 94 txt->server = new_thread; 94 95 95 // set "server" field in chdev descriptor 96 chdev->server = new_thread; 97 98 // start server thread 99 thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL ); 96 // start server thread 97 thread_unblock( XPTR( local_cxy , new_thread ) , THREAD_BLOCKED_GLOBAL ); 98 } 100 99 } 101 100
Note: See TracChangeset
for help on using the changeset viewer.