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_INTSAVE_VAR == _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 201 #define TN_INTSAVE_VAR tn_save_status_reg 215 #define TN_INTSAVE_DATA \ 216 TN_UWord TN_INTSAVE_VAR = _TN_PIC32_INTSAVE_DATA_INVALID; 225 #define TN_INTSAVE_DATA_INT TN_INTSAVE_DATA 254 # define TN_INT_DIS_SAVE() TN_INTSAVE_VAR = tn_arch_sr_save_int_dis() 255 # define TN_INT_RESTORE() _TN_PIC32_INTSAVE_CHECK(); \ 256 tn_arch_sr_restore(TN_INTSAVE_VAR) 258 # define TN_INT_DIS_SAVE() __asm__ __volatile__( \ 260 : "=d" (TN_INTSAVE_VAR) \ 262 # define TN_INT_RESTORE() _TN_PIC32_INTSAVE_CHECK(); \ 263 __builtin_mtc0(12, 0, TN_INTSAVE_VAR) 273 #define TN_INT_IDIS_SAVE() TN_INT_DIS_SAVE() 282 #define TN_INT_IRESTORE() TN_INT_RESTORE() 287 #define TN_IS_INT_DISABLED() ((__builtin_mfc0(12, 0) & 1) == 0) 292 #define _TN_CONTEXT_SWITCH_IPEND_IF_NEEDED() \ 293 _tn_context_switch_pend_if_needed() 300 #define _TN_SIZE_BYTES_TO_UWORDS(size_in_bytes) ((size_in_bytes) >> 2) 303 # define _TN_INLINE inline __attribute__ ((always_inline)) 305 # define _TN_INLINE inline 308 #define _TN_STATIC_INLINE static _TN_INLINE 310 #define _TN_VOLATILE_WORKAROUND 312 #define _TN_ARCH_STACK_PT_TYPE _TN_ARCH_STACK_PT_TYPE__FULL 313 #define _TN_ARCH_STACK_DIR _TN_ARCH_STACK_DIR__DESC 315 #endif //-- DOXYGEN_SHOULD_SKIP_THIS 344 #define tn_p32_soft_isr(vec) \ 345 __attribute__((__noinline__)) void _func##vec(void); \ 346 void __attribute__((naked, nomips16)) \ 347 __attribute__((vector(vec))) \ 350 asm volatile(".set push"); \ 351 asm volatile(".set mips32r2"); \ 352 asm volatile(".set nomips16"); \ 353 asm volatile(".set noreorder"); \ 354 asm volatile(".set noat"); \ 356 asm volatile("rdpgpr $sp, $sp"); \ 359 asm volatile("lui $k0, %hi(tn_p32_int_nest_count)"); \ 360 asm volatile("lw $k1, %lo(tn_p32_int_nest_count)($k0)"); \ 361 asm volatile("addiu $k1, $k1, 1"); \ 362 asm volatile("sw $k1, %lo(tn_p32_int_nest_count)($k0)"); \ 363 asm volatile("ori $k0, $zero, 1"); \ 364 asm volatile("bne $k1, $k0, 1f"); \ 367 asm volatile("lui $k0, %hi(tn_p32_user_sp)"); \ 368 asm volatile("sw $sp, %lo(tn_p32_user_sp)($k0)"); \ 369 asm volatile("lui $k0, %hi(tn_p32_int_sp)"); \ 370 asm volatile("lw $sp, %lo(tn_p32_int_sp)($k0)"); \ 372 asm volatile("1:"); \ 374 asm volatile("addiu $sp, $sp, -92"); \ 375 asm volatile("mfc0 $k1, $14"); \ 376 asm volatile("mfc0 $k0, $12, 2"); \ 377 asm volatile("sw $k1, 84($sp)"); \ 378 asm volatile("sw $k0, 80($sp)"); \ 379 asm volatile("mfc0 $k1, $12"); \ 380 asm volatile("sw $k1, 88($sp)"); \ 383 asm volatile("mfc0 $k0, $13"); \ 384 asm volatile("ins $k1, $zero, 1, 15"); \ 385 asm volatile("ext $k0, $k0, 10, 6"); \ 386 asm volatile("ins $k1, $k0, 10, 6"); \ 387 asm volatile("mtc0 $k1, $12"); \ 390 asm volatile("sw $ra, 76($sp)"); \ 391 asm volatile("sw $t9, 72($sp)"); \ 392 asm volatile("sw $t8, 68($sp)"); \ 393 asm volatile("sw $t7, 64($sp)"); \ 394 asm volatile("sw $t6, 60($sp)"); \ 395 asm volatile("sw $t5, 56($sp)"); \ 396 asm volatile("sw $t4, 52($sp)"); \ 397 asm volatile("sw $t3, 48($sp)"); \ 398 asm volatile("sw $t2, 44($sp)"); \ 399 asm volatile("sw $t1, 40($sp)"); \ 400 asm volatile("sw $t0, 36($sp)"); \ 401 asm volatile("sw $a3, 32($sp)"); \ 402 asm volatile("sw $a2, 28($sp)"); \ 403 asm volatile("sw $a1, 24($sp)"); \ 404 asm volatile("sw $a0, 20($sp)"); \ 405 asm volatile("sw $v1, 16($sp)"); \ 406 asm volatile("sw $v0, 12($sp)"); \ 407 asm volatile("sw $at, 8($sp)"); \ 408 asm volatile("mfhi $v0"); \ 409 asm volatile("mflo $v1"); \ 410 asm volatile("sw $v0, 4($sp)"); \ 413 asm volatile("la $t0, _func"#vec); \ 414 asm volatile("jalr $t0"); \ 415 asm volatile("sw $v1, 0($sp)"); \ 418 asm volatile("lw $v1, 0($sp)"); \ 419 asm volatile("lw $v0, 4($sp)"); \ 420 asm volatile("mtlo $v1"); \ 421 asm volatile("mthi $v0"); \ 422 asm volatile("lw $at, 8($sp)"); \ 423 asm volatile("lw $v0, 12($sp)"); \ 424 asm volatile("lw $v1, 16($sp)"); \ 425 asm volatile("lw $a0, 20($sp)"); \ 426 asm volatile("lw $a1, 24($sp)"); \ 427 asm volatile("lw $a2, 28($sp)"); \ 428 asm volatile("lw $a3, 32($sp)"); \ 429 asm volatile("lw $t0, 36($sp)"); \ 430 asm volatile("lw $t1, 40($sp)"); \ 431 asm volatile("lw $t2, 44($sp)"); \ 432 asm volatile("lw $t3, 48($sp)"); \ 433 asm volatile("lw $t4, 52($sp)"); \ 434 asm volatile("lw $t5, 56($sp)"); \ 435 asm volatile("lw $t6, 60($sp)"); \ 436 asm volatile("lw $t7, 64($sp)"); \ 437 asm volatile("lw $t8, 68($sp)"); \ 438 asm volatile("lw $t9, 72($sp)"); \ 439 asm volatile("lw $ra, 76($sp)"); \ 441 asm volatile("di"); \ 442 asm volatile("ehb"); \ 445 asm volatile("lw $k0, 84($sp)"); \ 446 asm volatile("mtc0 $k0, $14"); \ 447 asm volatile("lw $k0, 80($sp)"); \ 448 asm volatile("mtc0 $k0, $12, 2"); \ 449 asm volatile("addiu $sp, $sp, 92"); \ 452 asm volatile("lui $k0, %hi(tn_p32_int_nest_count)"); \ 453 asm volatile("lw $k1, %lo(tn_p32_int_nest_count)($k0)"); \ 454 asm volatile("addiu $k1, $k1, -1"); \ 455 asm volatile("sw $k1, %lo(tn_p32_int_nest_count)($k0)"); \ 456 asm volatile("bne $k1, $zero, 1f"); \ 457 asm volatile("lw $k1, -4($sp)"); \ 460 asm volatile("lui $k0, %hi(tn_p32_int_sp)"); \ 461 asm volatile("sw $sp, %lo(tn_p32_int_sp)($k0)"); \ 462 asm volatile("lui $k0, %hi(tn_p32_user_sp)"); \ 463 asm volatile("lw $sp, %lo(tn_p32_user_sp)($k0)"); \ 465 asm volatile("1:"); \ 466 asm volatile("wrpgpr $sp, $sp"); \ 467 asm volatile("mtc0 $k1, $12"); \ 468 asm volatile("eret"); \ 470 asm volatile(".set pop"); \ 472 } __attribute((__noinline__)) void _func##vec(void) 493 #define tn_p32_srs_isr(vec) \ 494 __attribute__((__noinline__)) void _func##vec(void); \ 495 void __attribute__((naked, nomips16)) \ 496 __attribute__((vector(vec))) \ 499 asm volatile(".set push"); \ 500 asm volatile(".set mips32r2"); \ 501 asm volatile(".set nomips16"); \ 502 asm volatile(".set noreorder"); \ 503 asm volatile(".set noat"); \ 505 asm volatile("rdpgpr $sp, $sp"); \ 508 asm volatile("lui $k0, %hi(tn_p32_int_nest_count)"); \ 509 asm volatile("lw $k1, %lo(tn_p32_int_nest_count)($k0)"); \ 510 asm volatile("addiu $k1, $k1, 1"); \ 511 asm volatile("sw $k1, %lo(tn_p32_int_nest_count)($k0)"); \ 512 asm volatile("ori $k0, $zero, 1"); \ 513 asm volatile("bne $k1, $k0, 1f"); \ 516 asm volatile("lui $k0, %hi(tn_p32_user_sp)"); \ 517 asm volatile("sw $sp, %lo(tn_p32_user_sp)($k0)"); \ 518 asm volatile("lui $k0, %hi(tn_p32_int_sp)"); \ 519 asm volatile("lw $sp, %lo(tn_p32_int_sp)($k0)"); \ 521 asm volatile("1:"); \ 523 asm volatile("addiu $sp, $sp, -20"); \ 524 asm volatile("mfc0 $k1, $14"); \ 525 asm volatile("mfc0 $k0, $12, 2"); \ 526 asm volatile("sw $k1, 12($sp)"); \ 527 asm volatile("sw $k0, 8($sp)"); \ 528 asm volatile("mfc0 $k1, $12"); \ 529 asm volatile("sw $k1, 16($sp)"); \ 532 asm volatile("mfc0 $k0, $13"); \ 533 asm volatile("ins $k1, $zero, 1, 15"); \ 534 asm volatile("ext $k0, $k0, 10, 6"); \ 535 asm volatile("ins $k1, $k0, 10, 6"); \ 536 asm volatile("mtc0 $k1, $12"); \ 539 asm volatile("mfhi $v0"); \ 540 asm volatile("mflo $v1"); \ 541 asm volatile("sw $v0, 4($sp)"); \ 544 asm volatile("la $t0, _func"#vec); \ 545 asm volatile("jalr $t0"); \ 546 asm volatile("sw $v1, 0($sp)"); \ 549 asm volatile("lw $v1, 0($sp)"); \ 550 asm volatile("lw $v0, 4($sp)"); \ 551 asm volatile("mtlo $v1"); \ 552 asm volatile("mthi $v0"); \ 554 asm volatile("di"); \ 555 asm volatile("ehb"); \ 558 asm volatile("lw $k0, 12($sp)"); \ 559 asm volatile("mtc0 $k0, $14"); \ 560 asm volatile("lw $k0, 8($sp)"); \ 561 asm volatile("mtc0 $k0, $12, 2"); \ 562 asm volatile("addiu $sp, $sp, 20"); \ 565 asm volatile("lui $k0, %hi(tn_p32_int_nest_count)"); \ 566 asm volatile("lw $k1, %lo(tn_p32_int_nest_count)($k0)"); \ 567 asm volatile("addiu $k1, $k1, -1"); \ 568 asm volatile("sw $k1, %lo(tn_p32_int_nest_count)($k0)"); \ 569 asm volatile("bne $k1, $zero, 1f"); \ 570 asm volatile("lw $k1, -4($sp)"); \ 573 asm volatile("lui $k0, %hi(tn_p32_int_sp)"); \ 574 asm volatile("sw $sp, %lo(tn_p32_int_sp)($k0)"); \ 575 asm volatile("lui $k0, %hi(tn_p32_user_sp)"); \ 576 asm volatile("lw $sp, %lo(tn_p32_user_sp)($k0)"); \ 578 asm volatile("1:"); \ 579 asm volatile("wrpgpr $sp, $sp"); \ 580 asm volatile("mtc0 $k1, $12"); \ 581 asm volatile("eret"); \ 583 asm volatile(".set pop"); \ 585 } __attribute((__noinline__)) void _func##vec(void) 592 #define tn_soft_isr tn_p32_soft_isr 598 #define tn_srs_isr tn_p32_srs_isr 604 #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.