Changeset 295 for soft/giet_vm/giet_drivers/tim_driver.c
- Timestamp:
- Mar 26, 2014, 6:44:44 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_drivers/tim_driver.c
r263 r295 18 18 // The global index is cluster_xy * (NB_PROCS_MAX + NB_TIM_CHANNELS) + local_id 19 19 // 20 // The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in the 21 // hard_config.h file. 22 // 23 // The register offsets must be defined in the hwr_mapping.h file. 20 // The NB_PROCS_MAX and NB_TIM_CHANNELS values must be defined in hard_config.h file. 24 21 ///////////////////////////////////////////////////////////////////////////////////// 25 22 // The virtual base address of the segment associated to a channel is: … … 33 30 #include <giet_config.h> 34 31 #include <tim_driver.h> 32 #include <xcu_driver.h> 33 #include <tty_driver.h> 35 34 #include <utils.h> 36 35 … … 68 67 69 68 #if (NB_TIM_CHANNELS > 0) 70 in_unckdata volatile unsigned char _user_timer_event[ X_SIZE*Y_SIZE*NB_TIM_CHANNELS]71 = { [0 ... ((X_SIZE*Y_SIZE*NB_TIM_CHANNELS) - 1)] = 0 };69 in_unckdata volatile unsigned char _user_timer_event[(1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS] 70 = { [0 ... (((1<<X_WIDTH)*(1<<Y_WIDTH)*NB_TIM_CHANNELS) - 1)] = 0 }; 72 71 #endif 73 72 74 73 //////////////////////////////////////////////////////////////////////////////////// 75 // _timer_start()76 74 // This function activates a timer in the vci_timer component 77 75 // by writing in the proper register the period value. 78 76 // It can be used by both the kernel to initialise a "system" timer, 79 77 // or by a task (through a system call) to configure an "user" timer. 80 // Returns 0 if success, > 0 if error. 81 ////////////////////////////////////////////////////////////////////////////// 82 unsigned int _timer_start( unsigned int cluster_xy, 83 unsigned int local_id, 84 unsigned int period) 85 { 86 // parameters checking 87 unsigned int x = cluster_xy >> Y_WIDTH; 88 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 89 if (x >= X_SIZE) return 1; 90 if (y >= Y_SIZE) return 1; 91 if (local_id >= NB_TIM_CHANNELS) return 1; 78 /////////////////////////////////////////////////////////////////////////////////// 79 void _timer_start( unsigned int cluster_xy, 80 unsigned int local_id, 81 unsigned int period) 82 { 83 #if NB_TIM_CHANNELS 84 85 // parameters checking 86 unsigned int x = cluster_xy >> Y_WIDTH; 87 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 88 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 89 { 90 _printf("[GIET ERROR] in _timer_start()\n"); 91 _exit(); 92 } 92 93 93 94 unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + … … 96 97 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; 97 98 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3; 98 return 0; 99 } 100 101 ////////////////////////////////////////////////////////////////////////////// 102 // _timer_stop() 99 100 #else 101 _printf("[GIET ERROR] _timer_start() should not be called when NB_TIM_CHANNELS is 0\n"); 102 _exit(); 103 #endif 104 } 105 106 ////////////////////////////////////////////////////////////////////////////// 103 107 // This function desactivates a timer in the vci_timer component 104 108 // by writing in the proper register. 105 109 // Returns 0 if success, > 0 if error. 106 110 ////////////////////////////////////////////////////////////////////////////// 107 unsigned int _timer_stop( unsigned int cluster_xy, 108 unsigned int local_id) 109 { 110 // parameters checking 111 unsigned int x = cluster_xy >> Y_WIDTH; 112 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 113 if (x >= X_SIZE) return 1; 114 if (y >= Y_SIZE) return 1; 115 if (local_id >= NB_TIM_CHANNELS) return 1; 111 void _timer_stop( unsigned int cluster_xy, 112 unsigned int local_id) 113 { 114 #if NB_TIM_CHANNELS 115 116 // parameters checking 117 unsigned int x = cluster_xy >> Y_WIDTH; 118 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 119 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 120 { 121 _printf("[GIET ERROR] in _timer_stop()\n"); 122 _exit(); 123 } 116 124 117 125 unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + … … 119 127 120 128 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0; 121 return 0; 122 } 123 124 ////////////////////////////////////////////////////////////////////////////// 125 // _timer_reset_irq() 129 130 #else 131 _printf("[GIET ERROR] _timer_stop() should not be called when NB_TIM_CHANNELS is 0\n"); 132 _exit(); 133 #endif 134 } 135 136 ////////////////////////////////////////////////////////////////////////////// 126 137 // This function acknowlegge a timer interrupt in the vci_timer 127 138 // component by writing in the proper register. … … 130 141 // Returns 0 if success, > 0 if error. 131 142 ////////////////////////////////////////////////////////////////////////////// 132 unsigned int _timer_reset_irq( unsigned int cluster_xy, 133 unsigned int local_id ) 134 { 135 // parameters checking 136 unsigned int x = cluster_xy >> Y_WIDTH; 137 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 138 if (x >= X_SIZE) return 1; 139 if (y >= Y_SIZE) return 1; 140 if (local_id >= NB_TIM_CHANNELS) return 1; 143 void _timer_reset_irq( unsigned int cluster_xy, 144 unsigned int local_id ) 145 { 146 #if NB_TIM_CHANNELS 147 148 // parameters checking 149 unsigned int x = cluster_xy >> Y_WIDTH; 150 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 151 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 152 { 153 _printf("[GIET ERROR] in _timer_reset_irq()\n"); 154 _exit(); 155 } 141 156 142 157 unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + … … 144 159 145 160 timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0; 146 return 0; 161 162 #else 163 _printf("[GIET ERROR] _timer_reset_irq() should not be called when NB_TIM_CHANNELS is 0\n"); 164 _exit(); 165 #endif 147 166 } 148 167 149 168 ///////////////////////////////////////////////////////////////////////////// 150 // _timer_reset_cpt()151 169 // This function resets the timer counter. To do so, we re-write the period 152 170 // in the proper register, what causes the count to restart. … … 156 174 // This function is called during a context switch (user or preemptive) 157 175 //////////////////////////////////////////////////////////////////////i////// 158 unsigned int _timer_reset_cpt( unsigned int cluster_xy, 159 unsigned int local_id) 160 { 161 // parameters checking 162 unsigned int x = cluster_xy >> Y_WIDTH; 163 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 164 if (x >= X_SIZE) return 1; 165 if (y >= Y_SIZE) return 1; 166 if (local_id >= NB_TIM_CHANNELS) return 1; 176 void _timer_reset_cpt( unsigned int cluster_xy, 177 unsigned int local_id) 178 { 179 #if NB_TIM_CHANNELS 180 181 // parameters checking 182 unsigned int x = cluster_xy >> Y_WIDTH; 183 unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1); 184 if ( (x >= X_SIZE) || (y >= Y_SIZE) || (local_id >= NB_TIM_CHANNELS) ) 185 { 186 _printf("[GIET ERROR in _timer_reset_cpt()\n"); 187 _exit(); 188 } 167 189 168 190 // We suppose that the TIMER_MODE register value is 0x3 … … 172 194 unsigned int period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD]; 173 195 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; 174 return 0; 175 } 196 197 #else 198 _printf("[GIET ERROR] _timer_reset_cpt should not be called when NB_TIM_CHANNELS is 0\n"); 199 _exit(); 200 #endif 201 } 202 203 /////////////////////////////////////////////////////////////////////////////////// 204 // This ISR handles the IRQs generated by the "user" timers that are 205 // replicated in all clusters. 206 // The IRQs generated by the "system" timers should be handled by _isr_switch(). 207 // It can be a HWI or a PTI. 208 // The channel argument is the user timer local index. 209 // timer_global_id = cluster_id*(NB_TIM_CHANNELS) + channel 210 // The ISR acknowledges the IRQ and registers the event in the proper entry 211 // of the _user_timer_event[] array, and a log message is displayed on TTY0. 212 /////////////////////////////////////////////////////////////////////////////////// 213 void _timer_isr( unsigned int irq_type, // HWI / PTI 214 unsigned int irq_id, // index returned by XCU 215 unsigned int channel ) // user timer index 216 { 217 #if NB_TIM_CHANNELS 218 219 unsigned int cluster_xy = _get_procid() / NB_PROCS_MAX; 220 221 // acknowledge IRQ depending on type 222 if ( irq_type == IRQ_TYPE_HWI ) _timer_reset_irq( cluster_xy, channel ); 223 else _xcu_timer_reset_irq( cluster_xy, irq_id ); 224 225 // register the event 226 _user_timer_event[cluster_xy * NB_TIM_CHANNELS + channel] = 1; 227 228 // display a message on TTY 0 229 _printf("\n[GIET WARNING] User Timer IRQ at cycle %d / cluster = %x / channel = %d\n", 230 _get_proctime(), cluster_xy, channel ); 231 232 #else 233 _printf("[GIET ERROR] _timer_isr() should not be called when NB_TIM_CHANNELS == 0\n"); 234 _exit(); 235 #endif 236 } 237 176 238 177 239
Note: See TracChangeset
for help on using the changeset viewer.