45 #ifndef _TN_ARCH_PIC32_H
46 #define _TN_ARCH_PIC32_H
53 #include "../../core/tn_cfg_dispatch.h"
89 #ifndef DOXYGEN_SHOULD_SKIP_THIS
91 #define _TN_PIC32_INTSAVE_DATA_INVALID 0xffffffff
94 # define _TN_PIC32_INTSAVE_CHECK() \
96 if (tn_save_status_reg == _TN_PIC32_INTSAVE_DATA_INVALID){ \
97 _TN_FATAL_ERROR(""); \
101 # define _TN_PIC32_INTSAVE_CHECK()
110 #define _TN_FFS(x) (32 - __builtin_clz((x) & (0 - (x))))
119 #define _TN_FATAL_ERROR(error_msg, ...) \
120 {__asm__ volatile(" sdbbp 0"); __asm__ volatile ("nop");}
145 # define TN_ARCH_STK_ATTR_BEFORE
146 # define TN_ARCH_STK_ATTR_AFTER __attribute__((aligned(0x8)))
148 # error "Unknown compiler"
155 #define TN_MIN_STACK_SIZE (36 + _TN_STACK_OVERFLOW_SIZE_ADD)
160 #define TN_INT_WIDTH 32
181 #define TN_PRIORITIES_MAX_CNT TN_INT_WIDTH
187 #define TN_WAIT_INFINITE (TN_TickCnt)0xFFFFFFFF
192 #define TN_FILL_STACK_VAL 0xFEEDFACE
209 #define TN_INTSAVE_DATA \
210 int tn_save_status_reg = _TN_PIC32_INTSAVE_DATA_INVALID;
219 #define TN_INTSAVE_DATA_INT TN_INTSAVE_DATA
248 # define TN_INT_DIS_SAVE() tn_save_status_reg = tn_arch_sr_save_int_dis()
249 # define TN_INT_RESTORE() _TN_PIC32_INTSAVE_CHECK(); \
250 tn_arch_sr_restore(tn_save_status_reg)
252 # define TN_INT_DIS_SAVE() __asm__ __volatile__( \
254 : "=d" (tn_save_status_reg) \
256 # define TN_INT_RESTORE() _TN_PIC32_INTSAVE_CHECK(); \
257 __builtin_mtc0(12, 0, tn_save_status_reg)
267 #define TN_INT_IDIS_SAVE() TN_INT_DIS_SAVE()
276 #define TN_INT_IRESTORE() TN_INT_RESTORE()
281 #define TN_IS_INT_DISABLED() ((__builtin_mfc0(12, 0) & 1) == 0)
286 #define _TN_CONTEXT_SWITCH_IPEND_IF_NEEDED() \
287 _tn_context_switch_pend_if_needed()
294 #define _TN_SIZE_BYTES_TO_UWORDS(size_in_bytes) ((size_in_bytes) >> 2)
296 #define _TN_INLINE inline
298 #define _TN_VOLATILE_WORKAROUND
300 #define _TN_ARCH_STACK_PT_TYPE _TN_ARCH_STACK_PT_TYPE__FULL
301 #define _TN_ARCH_STACK_DIR _TN_ARCH_STACK_DIR__DESC
303 #endif //-- DOXYGEN_SHOULD_SKIP_THIS
332 #define tn_p32_soft_isr(vec) \
333 __attribute__((__noinline__)) void _func##vec(void); \
334 void __attribute__((naked, nomips16)) \
335 __attribute__((vector(vec))) \
338 asm volatile(".set push"); \
339 asm volatile(".set mips32r2"); \
340 asm volatile(".set nomips16"); \
341 asm volatile(".set noreorder"); \
342 asm volatile(".set noat"); \
344 asm volatile("rdpgpr $sp, $sp"); \
347 asm volatile("lui $k0, %hi(tn_p32_int_nest_count)"); \
348 asm volatile("lw $k1, %lo(tn_p32_int_nest_count)($k0)"); \
349 asm volatile("addiu $k1, $k1, 1"); \
350 asm volatile("sw $k1, %lo(tn_p32_int_nest_count)($k0)"); \
351 asm volatile("ori $k0, $zero, 1"); \
352 asm volatile("bne $k1, $k0, 1f"); \
355 asm volatile("lui $k0, %hi(tn_p32_user_sp)"); \
356 asm volatile("sw $sp, %lo(tn_p32_user_sp)($k0)"); \
357 asm volatile("lui $k0, %hi(tn_p32_int_sp)"); \
358 asm volatile("lw $sp, %lo(tn_p32_int_sp)($k0)"); \
360 asm volatile("1:"); \
362 asm volatile("addiu $sp, $sp, -92"); \
363 asm volatile("mfc0 $k1, $14"); \
364 asm volatile("mfc0 $k0, $12, 2"); \
365 asm volatile("sw $k1, 84($sp)"); \
366 asm volatile("sw $k0, 80($sp)"); \
367 asm volatile("mfc0 $k1, $12"); \
368 asm volatile("sw $k1, 88($sp)"); \
371 asm volatile("mfc0 $k0, $13"); \
372 asm volatile("ins $k1, $zero, 1, 15"); \
373 asm volatile("ext $k0, $k0, 10, 6"); \
374 asm volatile("ins $k1, $k0, 10, 6"); \
375 asm volatile("mtc0 $k1, $12"); \
378 asm volatile("sw $ra, 76($sp)"); \
379 asm volatile("sw $t9, 72($sp)"); \
380 asm volatile("sw $t8, 68($sp)"); \
381 asm volatile("sw $t7, 64($sp)"); \
382 asm volatile("sw $t6, 60($sp)"); \
383 asm volatile("sw $t5, 56($sp)"); \
384 asm volatile("sw $t4, 52($sp)"); \
385 asm volatile("sw $t3, 48($sp)"); \
386 asm volatile("sw $t2, 44($sp)"); \
387 asm volatile("sw $t1, 40($sp)"); \
388 asm volatile("sw $t0, 36($sp)"); \
389 asm volatile("sw $a3, 32($sp)"); \
390 asm volatile("sw $a2, 28($sp)"); \
391 asm volatile("sw $a1, 24($sp)"); \
392 asm volatile("sw $a0, 20($sp)"); \
393 asm volatile("sw $v1, 16($sp)"); \
394 asm volatile("sw $v0, 12($sp)"); \
395 asm volatile("sw $at, 8($sp)"); \
396 asm volatile("mfhi $v0"); \
397 asm volatile("mflo $v1"); \
398 asm volatile("sw $v0, 4($sp)"); \
401 asm volatile("la $t0, _func"#vec); \
402 asm volatile("jalr $t0"); \
403 asm volatile("sw $v1, 0($sp)"); \
406 asm volatile("lw $v1, 0($sp)"); \
407 asm volatile("lw $v0, 4($sp)"); \
408 asm volatile("mtlo $v1"); \
409 asm volatile("mthi $v0"); \
410 asm volatile("lw $at, 8($sp)"); \
411 asm volatile("lw $v0, 12($sp)"); \
412 asm volatile("lw $v1, 16($sp)"); \
413 asm volatile("lw $a0, 20($sp)"); \
414 asm volatile("lw $a1, 24($sp)"); \
415 asm volatile("lw $a2, 28($sp)"); \
416 asm volatile("lw $a3, 32($sp)"); \
417 asm volatile("lw $t0, 36($sp)"); \
418 asm volatile("lw $t1, 40($sp)"); \
419 asm volatile("lw $t2, 44($sp)"); \
420 asm volatile("lw $t3, 48($sp)"); \
421 asm volatile("lw $t4, 52($sp)"); \
422 asm volatile("lw $t5, 56($sp)"); \
423 asm volatile("lw $t6, 60($sp)"); \
424 asm volatile("lw $t7, 64($sp)"); \
425 asm volatile("lw $t8, 68($sp)"); \
426 asm volatile("lw $t9, 72($sp)"); \
427 asm volatile("lw $ra, 76($sp)"); \
429 asm volatile("di"); \
430 asm volatile("ehb"); \
433 asm volatile("lw $k0, 84($sp)"); \
434 asm volatile("mtc0 $k0, $14"); \
435 asm volatile("lw $k0, 80($sp)"); \
436 asm volatile("mtc0 $k0, $12, 2"); \
437 asm volatile("addiu $sp, $sp, 92"); \
440 asm volatile("lui $k0, %hi(tn_p32_int_nest_count)"); \
441 asm volatile("lw $k1, %lo(tn_p32_int_nest_count)($k0)"); \
442 asm volatile("addiu $k1, $k1, -1"); \
443 asm volatile("sw $k1, %lo(tn_p32_int_nest_count)($k0)"); \
444 asm volatile("bne $k1, $zero, 1f"); \
445 asm volatile("lw $k1, -4($sp)"); \
448 asm volatile("lui $k0, %hi(tn_p32_int_sp)"); \
449 asm volatile("sw $sp, %lo(tn_p32_int_sp)($k0)"); \
450 asm volatile("lui $k0, %hi(tn_p32_user_sp)"); \
451 asm volatile("lw $sp, %lo(tn_p32_user_sp)($k0)"); \
453 asm volatile("1:"); \
454 asm volatile("wrpgpr $sp, $sp"); \
455 asm volatile("mtc0 $k1, $12"); \
456 asm volatile("eret"); \
458 asm volatile(".set pop"); \
460 } __attribute((__noinline__)) void _func##vec(void)
481 #define tn_p32_srs_isr(vec) \
482 __attribute__((__noinline__)) void _func##vec(void); \
483 void __attribute__((naked, nomips16)) \
484 __attribute__((vector(vec))) \
487 asm volatile(".set push"); \
488 asm volatile(".set mips32r2"); \
489 asm volatile(".set nomips16"); \
490 asm volatile(".set noreorder"); \
491 asm volatile(".set noat"); \
493 asm volatile("rdpgpr $sp, $sp"); \
496 asm volatile("lui $k0, %hi(tn_p32_int_nest_count)"); \
497 asm volatile("lw $k1, %lo(tn_p32_int_nest_count)($k0)"); \
498 asm volatile("addiu $k1, $k1, 1"); \
499 asm volatile("sw $k1, %lo(tn_p32_int_nest_count)($k0)"); \
500 asm volatile("ori $k0, $zero, 1"); \
501 asm volatile("bne $k1, $k0, 1f"); \
504 asm volatile("lui $k0, %hi(tn_p32_user_sp)"); \
505 asm volatile("sw $sp, %lo(tn_p32_user_sp)($k0)"); \
506 asm volatile("lui $k0, %hi(tn_p32_int_sp)"); \
507 asm volatile("lw $sp, %lo(tn_p32_int_sp)($k0)"); \
509 asm volatile("1:"); \
511 asm volatile("addiu $sp, $sp, -20"); \
512 asm volatile("mfc0 $k1, $14"); \
513 asm volatile("mfc0 $k0, $12, 2"); \
514 asm volatile("sw $k1, 12($sp)"); \
515 asm volatile("sw $k0, 8($sp)"); \
516 asm volatile("mfc0 $k1, $12"); \
517 asm volatile("sw $k1, 16($sp)"); \
520 asm volatile("mfc0 $k0, $13"); \
521 asm volatile("ins $k1, $zero, 1, 15"); \
522 asm volatile("ext $k0, $k0, 10, 6"); \
523 asm volatile("ins $k1, $k0, 10, 6"); \
524 asm volatile("mtc0 $k1, $12"); \
527 asm volatile("mfhi $v0"); \
528 asm volatile("mflo $v1"); \
529 asm volatile("sw $v0, 4($sp)"); \
532 asm volatile("la $t0, _func"#vec); \
533 asm volatile("jalr $t0"); \
534 asm volatile("sw $v1, 0($sp)"); \
537 asm volatile("lw $v1, 0($sp)"); \
538 asm volatile("lw $v0, 4($sp)"); \
539 asm volatile("mtlo $v1"); \
540 asm volatile("mthi $v0"); \
542 asm volatile("di"); \
543 asm volatile("ehb"); \
546 asm volatile("lw $k0, 12($sp)"); \
547 asm volatile("mtc0 $k0, $14"); \
548 asm volatile("lw $k0, 8($sp)"); \
549 asm volatile("mtc0 $k0, $12, 2"); \
550 asm volatile("addiu $sp, $sp, 20"); \
553 asm volatile("lui $k0, %hi(tn_p32_int_nest_count)"); \
554 asm volatile("lw $k1, %lo(tn_p32_int_nest_count)($k0)"); \
555 asm volatile("addiu $k1, $k1, -1"); \
556 asm volatile("sw $k1, %lo(tn_p32_int_nest_count)($k0)"); \
557 asm volatile("bne $k1, $zero, 1f"); \
558 asm volatile("lw $k1, -4($sp)"); \
561 asm volatile("lui $k0, %hi(tn_p32_int_sp)"); \
562 asm volatile("sw $sp, %lo(tn_p32_int_sp)($k0)"); \
563 asm volatile("lui $k0, %hi(tn_p32_user_sp)"); \
564 asm volatile("lw $sp, %lo(tn_p32_user_sp)($k0)"); \
566 asm volatile("1:"); \
567 asm volatile("wrpgpr $sp, $sp"); \
568 asm volatile("mtc0 $k1, $12"); \
569 asm volatile("eret"); \
571 asm volatile(".set pop"); \
573 } __attribute((__noinline__)) void _func##vec(void)
580 #define tn_soft_isr tn_p32_soft_isr
586 #define tn_srs_isr tn_p32_srs_isr
592 #endif // _TN_ARCH_PIC32_H
void * tn_p32_user_sp
saved task stack pointer.
volatile int tn_p32_int_nest_count
current interrupt nesting count.
void * tn_p32_int_sp
saved ISR stack pointer.
unsigned int TN_UIntPtr
Unsigned integer type that is able to store pointers.
Atomic bit-field access macros for PIC24/dsPIC.
unsigned int TN_UWord
Unsigned integer type whose size is equal to the size of CPU register.