45 #ifndef _TN_ARCH_PIC32_H
46 #define _TN_ARCH_PIC32_H
50 #include "../../core/tn_common.h"
57 #ifndef DOXYGEN_SHOULD_SKIP_THIS
59 #define _TN_PIC32_INTSAVE_DATA_INVALID 0xffffffff
62 # define _TN_PIC32_INTSAVE_CHECK() \
64 if (tn_save_status_reg == _TN_PIC32_INTSAVE_DATA_INVALID){ \
65 _TN_FATAL_ERROR(""); \
69 # define _TN_PIC32_INTSAVE_CHECK()
78 #define _TN_FFS(x) (32 - __builtin_clz((x) & (0 - (x))))
87 #define _TN_FATAL_ERROR(error_msg, ...) \
88 {__asm__ volatile(" sdbbp 0"); __asm__ volatile ("nop");}
115 # define TN_ARCH_STK_ATTR_BEFORE
116 # define TN_ARCH_STK_ATTR_AFTER __attribute__((aligned(0x8)))
118 # error "Unknown compiler"
125 #define TN_MIN_STACK_SIZE 36
130 #define TN_INT_WIDTH 32
145 #define TN_PRIORITIES_MAX_CNT TN_INT_WIDTH
150 #define TN_WAIT_INFINITE 0xFFFFFFFF
155 #define TN_FILL_STACK_VAL 0xFEEDFACE
172 #define TN_INTSAVE_DATA \
173 int tn_save_status_reg = _TN_PIC32_INTSAVE_DATA_INVALID;
182 #define TN_INTSAVE_DATA_INT TN_INTSAVE_DATA
211 # define TN_INT_DIS_SAVE() tn_save_status_reg = tn_arch_sr_save_int_dis()
212 # define TN_INT_RESTORE() _TN_PIC32_INTSAVE_CHECK(); \
213 tn_arch_sr_restore(tn_save_status_reg)
215 # define TN_INT_DIS_SAVE() __asm__ __volatile__( \
217 : "=d" (tn_save_status_reg) \
219 # define TN_INT_RESTORE() _TN_PIC32_INTSAVE_CHECK(); \
220 __builtin_mtc0(12, 0, tn_save_status_reg)
230 #define TN_INT_IDIS_SAVE() TN_INT_DIS_SAVE()
239 #define TN_INT_IRESTORE() TN_INT_RESTORE()
244 #define TN_IS_INT_DISABLED() ((__builtin_mfc0(12, 0) & 1) == 0)
249 #define _TN_CONTEXT_SWITCH_IPEND_IF_NEEDED() \
250 _tn_context_switch_pend_if_needed()
254 #endif //-- DOXYGEN_SHOULD_SKIP_THIS
283 #define tn_soft_isr(vec) \
284 __attribute__((__noinline__)) void _func##vec(void); \
285 void __attribute__((naked, nomips16)) \
286 __attribute__((vector(vec))) \
289 asm volatile(".set push"); \
290 asm volatile(".set mips32r2"); \
291 asm volatile(".set nomips16"); \
292 asm volatile(".set noreorder"); \
293 asm volatile(".set noat"); \
295 asm volatile("rdpgpr $sp, $sp"); \
298 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
299 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
300 asm volatile("addiu $k1, $k1, 1"); \
301 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
302 asm volatile("ori $k0, $zero, 1"); \
303 asm volatile("bne $k1, $k0, 1f"); \
306 asm volatile("lui $k0, %hi(tn_user_sp)"); \
307 asm volatile("sw $sp, %lo(tn_user_sp)($k0)"); \
308 asm volatile("lui $k0, %hi(tn_int_sp)"); \
309 asm volatile("lw $sp, %lo(tn_int_sp)($k0)"); \
311 asm volatile("1:"); \
313 asm volatile("addiu $sp, $sp, -92"); \
314 asm volatile("mfc0 $k1, $14"); \
315 asm volatile("mfc0 $k0, $12, 2"); \
316 asm volatile("sw $k1, 84($sp)"); \
317 asm volatile("sw $k0, 80($sp)"); \
318 asm volatile("mfc0 $k1, $12"); \
319 asm volatile("sw $k1, 88($sp)"); \
322 asm volatile("mfc0 $k0, $13"); \
323 asm volatile("ins $k1, $zero, 1, 15"); \
324 asm volatile("ext $k0, $k0, 10, 6"); \
325 asm volatile("ins $k1, $k0, 10, 6"); \
326 asm volatile("mtc0 $k1, $12"); \
329 asm volatile("sw $ra, 76($sp)"); \
330 asm volatile("sw $t9, 72($sp)"); \
331 asm volatile("sw $t8, 68($sp)"); \
332 asm volatile("sw $t7, 64($sp)"); \
333 asm volatile("sw $t6, 60($sp)"); \
334 asm volatile("sw $t5, 56($sp)"); \
335 asm volatile("sw $t4, 52($sp)"); \
336 asm volatile("sw $t3, 48($sp)"); \
337 asm volatile("sw $t2, 44($sp)"); \
338 asm volatile("sw $t1, 40($sp)"); \
339 asm volatile("sw $t0, 36($sp)"); \
340 asm volatile("sw $a3, 32($sp)"); \
341 asm volatile("sw $a2, 28($sp)"); \
342 asm volatile("sw $a1, 24($sp)"); \
343 asm volatile("sw $a0, 20($sp)"); \
344 asm volatile("sw $v1, 16($sp)"); \
345 asm volatile("sw $v0, 12($sp)"); \
346 asm volatile("sw $at, 8($sp)"); \
347 asm volatile("mfhi $v0"); \
348 asm volatile("mflo $v1"); \
349 asm volatile("sw $v0, 4($sp)"); \
352 asm volatile("la $t0, _func"#vec); \
353 asm volatile("jalr $t0"); \
354 asm volatile("sw $v1, 0($sp)"); \
357 asm volatile("lw $v1, 0($sp)"); \
358 asm volatile("lw $v0, 4($sp)"); \
359 asm volatile("mtlo $v1"); \
360 asm volatile("mthi $v0"); \
361 asm volatile("lw $at, 8($sp)"); \
362 asm volatile("lw $v0, 12($sp)"); \
363 asm volatile("lw $v1, 16($sp)"); \
364 asm volatile("lw $a0, 20($sp)"); \
365 asm volatile("lw $a1, 24($sp)"); \
366 asm volatile("lw $a2, 28($sp)"); \
367 asm volatile("lw $a3, 32($sp)"); \
368 asm volatile("lw $t0, 36($sp)"); \
369 asm volatile("lw $t1, 40($sp)"); \
370 asm volatile("lw $t2, 44($sp)"); \
371 asm volatile("lw $t3, 48($sp)"); \
372 asm volatile("lw $t4, 52($sp)"); \
373 asm volatile("lw $t5, 56($sp)"); \
374 asm volatile("lw $t6, 60($sp)"); \
375 asm volatile("lw $t7, 64($sp)"); \
376 asm volatile("lw $t8, 68($sp)"); \
377 asm volatile("lw $t9, 72($sp)"); \
378 asm volatile("lw $ra, 76($sp)"); \
380 asm volatile("di"); \
381 asm volatile("ehb"); \
384 asm volatile("lw $k0, 84($sp)"); \
385 asm volatile("mtc0 $k0, $14"); \
386 asm volatile("lw $k0, 80($sp)"); \
387 asm volatile("mtc0 $k0, $12, 2"); \
388 asm volatile("addiu $sp, $sp, 92"); \
391 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
392 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
393 asm volatile("addiu $k1, $k1, -1"); \
394 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
395 asm volatile("bne $k1, $zero, 1f"); \
396 asm volatile("lw $k1, -4($sp)"); \
399 asm volatile("lui $k0, %hi(tn_int_sp)"); \
400 asm volatile("sw $sp, %lo(tn_int_sp)($k0)"); \
401 asm volatile("lui $k0, %hi(tn_user_sp)"); \
402 asm volatile("lw $sp, %lo(tn_user_sp)($k0)"); \
404 asm volatile("1:"); \
405 asm volatile("wrpgpr $sp, $sp"); \
406 asm volatile("mtc0 $k1, $12"); \
407 asm volatile("eret"); \
409 asm volatile(".set pop"); \
411 } __attribute((__noinline__)) void _func##vec(void)
432 #define tn_srs_isr(vec) \
433 __attribute__((__noinline__)) void _func##vec(void); \
434 void __attribute__((naked, nomips16)) \
435 __attribute__((vector(vec))) \
438 asm volatile(".set push"); \
439 asm volatile(".set mips32r2"); \
440 asm volatile(".set nomips16"); \
441 asm volatile(".set noreorder"); \
442 asm volatile(".set noat"); \
444 asm volatile("rdpgpr $sp, $sp"); \
447 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
448 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
449 asm volatile("addiu $k1, $k1, 1"); \
450 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
451 asm volatile("ori $k0, $zero, 1"); \
452 asm volatile("bne $k1, $k0, 1f"); \
455 asm volatile("lui $k0, %hi(tn_user_sp)"); \
456 asm volatile("sw $sp, %lo(tn_user_sp)($k0)"); \
457 asm volatile("lui $k0, %hi(tn_int_sp)"); \
458 asm volatile("lw $sp, %lo(tn_int_sp)($k0)"); \
460 asm volatile("1:"); \
462 asm volatile("addiu $sp, $sp, -20"); \
463 asm volatile("mfc0 $k1, $14"); \
464 asm volatile("mfc0 $k0, $12, 2"); \
465 asm volatile("sw $k1, 12($sp)"); \
466 asm volatile("sw $k0, 8($sp)"); \
467 asm volatile("mfc0 $k1, $12"); \
468 asm volatile("sw $k1, 16($sp)"); \
471 asm volatile("mfc0 $k0, $13"); \
472 asm volatile("ins $k1, $zero, 1, 15"); \
473 asm volatile("ext $k0, $k0, 10, 6"); \
474 asm volatile("ins $k1, $k0, 10, 6"); \
475 asm volatile("mtc0 $k1, $12"); \
478 asm volatile("mfhi $v0"); \
479 asm volatile("mflo $v1"); \
480 asm volatile("sw $v0, 4($sp)"); \
483 asm volatile("la $t0, _func"#vec); \
484 asm volatile("jalr $t0"); \
485 asm volatile("sw $v1, 0($sp)"); \
488 asm volatile("lw $v1, 0($sp)"); \
489 asm volatile("lw $v0, 4($sp)"); \
490 asm volatile("mtlo $v1"); \
491 asm volatile("mthi $v0"); \
493 asm volatile("di"); \
494 asm volatile("ehb"); \
497 asm volatile("lw $k0, 12($sp)"); \
498 asm volatile("mtc0 $k0, $14"); \
499 asm volatile("lw $k0, 8($sp)"); \
500 asm volatile("mtc0 $k0, $12, 2"); \
501 asm volatile("addiu $sp, $sp, 20"); \
504 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
505 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
506 asm volatile("addiu $k1, $k1, -1"); \
507 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
508 asm volatile("bne $k1, $zero, 1f"); \
509 asm volatile("lw $k1, -4($sp)"); \
512 asm volatile("lui $k0, %hi(tn_int_sp)"); \
513 asm volatile("sw $sp, %lo(tn_int_sp)($k0)"); \
514 asm volatile("lui $k0, %hi(tn_user_sp)"); \
515 asm volatile("lw $sp, %lo(tn_user_sp)($k0)"); \
517 asm volatile("1:"); \
518 asm volatile("wrpgpr $sp, $sp"); \
519 asm volatile("mtc0 $k1, $12"); \
520 asm volatile("eret"); \
522 asm volatile(".set pop"); \
524 } __attribute((__noinline__)) void _func##vec(void)
531 #endif // _TN_ARCH_PIC32_H
unsigned int TN_UWord
Unsigned integer type whose size is equal to the size of CPU register.