| 180 | PUBLIC(_ISR_PER_CPU) |
| 181 | SYM(_ISR_PER_CPU): |
| 182 | |
| 183 | #if defined(RTEMS_SMP) |
| 184 | sethi %hi(_Per_CPU_Information_p), %l5 |
| 185 | add %l5, %lo(_Per_CPU_Information_p), %l5 |
| 186 | #if BSP_LEON3_SMP |
| 187 | /* LEON3 SMP support */ |
| 188 | rd %asr17, %l7 |
| 189 | srl %l7, 28, %l7 /* CPU number is upper 4 bits so shift */ |
| 190 | sll %l7, 2, %l7 /* l7 = offset */ |
| 191 | add %l5, %l7, %l5 |
| 192 | #endif |
| 193 | ld [%l5], %l5 /* l5 = pointer to per CPU */ |
| 194 | |
| 195 | /* |
| 196 | * On multi-core system, we need to use SMP safe versions |
| 197 | * of ISR and Thread Dispatch critical sections. |
| 198 | * |
| 199 | * _ISR_SMP_Enter returns the interrupt nest level. If we are |
| 200 | * outermost interrupt, then we need to switch stacks. |
| 201 | */ |
| 202 | call SYM(_ISR_SMP_Enter), 0 |
| 203 | mov %sp, %fp ! delay slot |
| 204 | cmp %o0, 0 |
| 205 | #else |
| 206 | /* |
| 207 | * On single core system, we can directly use variables. |
| 208 | * |
| 209 | * Increment ISR nest level and Thread dispatch disable level. |
| 210 | * |
| 211 | * Register usage for this section: |
| 212 | * |
| 213 | * l4 = _Thread_Dispatch_disable_level pointer |
| 214 | * l5 = _ISR_Nest_level pointer |
| 215 | * l6 = _Thread_Dispatch_disable_level value |
| 216 | * l7 = _ISR_Nest_level value |
| 217 | * |
| 218 | * NOTE: It is assumed that l4 - l7 will be preserved until the ISR |
| 219 | * nest and thread dispatch disable levels are unnested. |
| 220 | */ |
| 221 | sethi %hi(SYM(_Thread_Dispatch_disable_level)), %l4 |
| 222 | ld [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))], %l6 |
| 223 | |
| 224 | sethi %hi(_Per_CPU_Information), %l5 |
| 225 | add %l5, %lo(_Per_CPU_Information), %l5 |
| 226 | |
| 227 | ld [%l5 + PER_CPU_ISR_NEST_LEVEL], %l7 |
| 228 | |
| 229 | add %l6, 1, %l6 |
| 230 | st %l6, [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))] |
| 231 | |
| 232 | add %l7, 1, %l7 |
| 233 | st %l7, [%l5 + PER_CPU_ISR_NEST_LEVEL] |
| 234 | |
| 235 | /* |
| 236 | * If ISR nest level was zero (now 1), then switch stack. |
| 237 | */ |
| 238 | mov %sp, %fp |
| 239 | subcc %l7, 1, %l7 ! outermost interrupt handler? |
| 240 | #endif |
| 241 | |
| 242 | /* |
| 243 | * Do we need to switch to the interrupt stack? |
| 244 | */ |
| 245 | beq,a dont_switch_stacks ! No, then do not switch stacks |
| 246 | ld [%l5 + PER_CPU_INTERRUPT_STACK_HIGH], %sp |
| 247 | |
| 248 | dont_switch_stacks: |
| 249 | /* |
| 250 | * Make sure we have a place on the stack for the window overflow |
| 251 | * trap handler to write into. At this point it is safe to |
| 252 | * enable traps again. |
| 253 | */ |
| 254 | |
| 255 | sub %sp, CPU_MINIMUM_STACK_FRAME_SIZE, %sp |
| 256 | |
| 257 | |
270 | | PUBLIC(_ISR_PER_CPU) |
271 | | SYM(_ISR_PER_CPU): |
272 | | |
273 | | #if defined(RTEMS_SMP) |
274 | | sethi %hi(_Per_CPU_Information_p), %l5 |
275 | | add %l5, %lo(_Per_CPU_Information_p), %l5 |
276 | | #if BSP_LEON3_SMP |
277 | | /* LEON3 SMP support */ |
278 | | rd %asr17, %l7 |
279 | | srl %l7, 28, %l7 /* CPU number is upper 4 bits so shift */ |
280 | | sll %l7, 2, %l7 /* l7 = offset */ |
281 | | add %l5, %l7, %l5 |
282 | | #endif |
283 | | ld [%l5], %l5 /* l5 = pointer to per CPU */ |
284 | | |
285 | | /* |
286 | | * On multi-core system, we need to use SMP safe versions |
287 | | * of ISR and Thread Dispatch critical sections. |
288 | | * |
289 | | * _ISR_SMP_Enter returns the interrupt nest level. If we are |
290 | | * outermost interrupt, then we need to switch stacks. |
291 | | */ |
292 | | call SYM(_ISR_SMP_Enter), 0 |
293 | | mov %sp, %fp ! delay slot |
294 | | cmp %o0, 0 |
295 | | #else |
296 | | /* |
297 | | * On single core system, we can directly use variables. |
298 | | * |
299 | | * Increment ISR nest level and Thread dispatch disable level. |
300 | | * |
301 | | * Register usage for this section: |
302 | | * |
303 | | * l4 = _Thread_Dispatch_disable_level pointer |
304 | | * l5 = _ISR_Nest_level pointer |
305 | | * l6 = _Thread_Dispatch_disable_level value |
306 | | * l7 = _ISR_Nest_level value |
307 | | * |
308 | | * NOTE: It is assumed that l4 - l7 will be preserved until the ISR |
309 | | * nest and thread dispatch disable levels are unnested. |
310 | | */ |
311 | | sethi %hi(SYM(_Thread_Dispatch_disable_level)), %l4 |
312 | | ld [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))], %l6 |
313 | | |
314 | | sethi %hi(_Per_CPU_Information), %l5 |
315 | | add %l5, %lo(_Per_CPU_Information), %l5 |
316 | | |
317 | | ld [%l5 + PER_CPU_ISR_NEST_LEVEL], %l7 |
318 | | |
319 | | add %l6, 1, %l6 |
320 | | st %l6, [%l4 + %lo(SYM(_Thread_Dispatch_disable_level))] |
321 | | |
322 | | add %l7, 1, %l7 |
323 | | st %l7, [%l5 + PER_CPU_ISR_NEST_LEVEL] |
324 | | |
325 | | /* |
326 | | * If ISR nest level was zero (now 1), then switch stack. |
327 | | */ |
328 | | mov %sp, %fp |
329 | | subcc %l7, 1, %l7 ! outermost interrupt handler? |
330 | | #endif |
331 | | |
332 | | /* |
333 | | * Do we need to switch to the interrupt stack? |
334 | | */ |
335 | | beq,a dont_switch_stacks ! No, then do not switch stacks |
336 | | ld [%l5 + PER_CPU_INTERRUPT_STACK_HIGH], %sp |
337 | | |
338 | | dont_switch_stacks: |
339 | | /* |
340 | | * Make sure we have a place on the stack for the window overflow |
341 | | * trap handler to write into. At this point it is safe to |
342 | | * enable traps again. |
343 | | */ |
344 | | |
345 | | sub %sp, CPU_MINIMUM_STACK_FRAME_SIZE, %sp |
346 | | |