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()
77 #define _TN_FFS(x) (32 - __builtin_clz((x) & (0 - (x))))
86 #define _TN_FATAL_ERROR(error_msg, ...) \
87 {__asm__ volatile(" sdbbp 0"); __asm__ volatile ("nop");}
114 # define TN_ARCH_STK_ATTR_BEFORE
115 # define TN_ARCH_STK_ATTR_AFTER __attribute__((aligned(0x8)))
117 # error "Unknown compiler"
124 #define TN_MIN_STACK_SIZE 36
129 #define TN_INT_WIDTH 32
143 #define TN_PRIORITIES_CNT TN_INT_WIDTH
148 #define TN_WAIT_INFINITE 0xFFFFFFFF
153 #define TN_FILL_STACK_VAL 0xFEEDFACE
170 #define TN_INTSAVE_DATA \
171 int tn_save_status_reg = _TN_PIC32_INTSAVE_DATA_INVALID;
180 #define TN_INTSAVE_DATA_INT TN_INTSAVE_DATA
209 # define TN_INT_DIS_SAVE() tn_save_status_reg = tn_arch_sr_save_int_dis()
210 # define TN_INT_RESTORE() _TN_PIC32_INTSAVE_CHECK(); \
211 tn_arch_sr_restore(tn_save_status_reg)
213 # define TN_INT_DIS_SAVE() __asm__ __volatile__( \
215 : "=d" (tn_save_status_reg) \
217 # define TN_INT_RESTORE() _TN_PIC32_INTSAVE_CHECK(); \
218 __builtin_mtc0(12, 0, tn_save_status_reg)
228 #define TN_INT_IDIS_SAVE() TN_INT_DIS_SAVE()
237 #define TN_INT_IRESTORE() TN_INT_RESTORE()
242 #define TN_IS_INT_DISABLED() ((__builtin_mfc0(12, 0) & 1) == 0)
245 #endif //-- DOXYGEN_SHOULD_SKIP_THIS
274 #define tn_soft_isr(vec) \
275 __attribute__((__noinline__)) void _func##vec(void); \
276 void __attribute__((naked, nomips16)) \
277 __attribute__((vector(vec))) \
280 asm volatile(".set push"); \
281 asm volatile(".set mips32r2"); \
282 asm volatile(".set nomips16"); \
283 asm volatile(".set noreorder"); \
284 asm volatile(".set noat"); \
286 asm volatile("rdpgpr $sp, $sp"); \
289 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
290 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
291 asm volatile("addiu $k1, $k1, 1"); \
292 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
293 asm volatile("ori $k0, $zero, 1"); \
294 asm volatile("bne $k1, $k0, 1f"); \
297 asm volatile("lui $k0, %hi(tn_user_sp)"); \
298 asm volatile("sw $sp, %lo(tn_user_sp)($k0)"); \
299 asm volatile("lui $k0, %hi(tn_int_sp)"); \
300 asm volatile("lw $sp, %lo(tn_int_sp)($k0)"); \
302 asm volatile("1:"); \
304 asm volatile("addiu $sp, $sp, -92"); \
305 asm volatile("mfc0 $k1, $14"); \
306 asm volatile("mfc0 $k0, $12, 2"); \
307 asm volatile("sw $k1, 84($sp)"); \
308 asm volatile("sw $k0, 80($sp)"); \
309 asm volatile("mfc0 $k1, $12"); \
310 asm volatile("sw $k1, 88($sp)"); \
313 asm volatile("mfc0 $k0, $13"); \
314 asm volatile("ins $k1, $zero, 1, 15"); \
315 asm volatile("ext $k0, $k0, 10, 6"); \
316 asm volatile("ins $k1, $k0, 10, 6"); \
317 asm volatile("mtc0 $k1, $12"); \
320 asm volatile("sw $ra, 76($sp)"); \
321 asm volatile("sw $t9, 72($sp)"); \
322 asm volatile("sw $t8, 68($sp)"); \
323 asm volatile("sw $t7, 64($sp)"); \
324 asm volatile("sw $t6, 60($sp)"); \
325 asm volatile("sw $t5, 56($sp)"); \
326 asm volatile("sw $t4, 52($sp)"); \
327 asm volatile("sw $t3, 48($sp)"); \
328 asm volatile("sw $t2, 44($sp)"); \
329 asm volatile("sw $t1, 40($sp)"); \
330 asm volatile("sw $t0, 36($sp)"); \
331 asm volatile("sw $a3, 32($sp)"); \
332 asm volatile("sw $a2, 28($sp)"); \
333 asm volatile("sw $a1, 24($sp)"); \
334 asm volatile("sw $a0, 20($sp)"); \
335 asm volatile("sw $v1, 16($sp)"); \
336 asm volatile("sw $v0, 12($sp)"); \
337 asm volatile("sw $at, 8($sp)"); \
338 asm volatile("mfhi $v0"); \
339 asm volatile("mflo $v1"); \
340 asm volatile("sw $v0, 4($sp)"); \
343 asm volatile("la $t0, _func"#vec); \
344 asm volatile("jalr $t0"); \
345 asm volatile("sw $v1, 0($sp)"); \
348 asm volatile("lw $t0, tn_curr_run_task"); \
349 asm volatile("lw $t1, tn_next_task_to_run"); \
350 asm volatile("lw $t0, 0($t0)"); \
351 asm volatile("lw $t1, 0($t1)"); \
352 asm volatile("lui $t2, %hi(IFS0SET)"); \
353 asm volatile("beq $t0, $t1, 1f"); \
354 asm volatile("ori $t1, $zero, 2"); \
355 asm volatile("sw $t1, %lo(IFS0SET)($t2)"); \
357 asm volatile("1:"); \
359 asm volatile("lw $v1, 0($sp)"); \
360 asm volatile("lw $v0, 4($sp)"); \
361 asm volatile("mtlo $v1"); \
362 asm volatile("mthi $v0"); \
363 asm volatile("lw $at, 8($sp)"); \
364 asm volatile("lw $v0, 12($sp)"); \
365 asm volatile("lw $v1, 16($sp)"); \
366 asm volatile("lw $a0, 20($sp)"); \
367 asm volatile("lw $a1, 24($sp)"); \
368 asm volatile("lw $a2, 28($sp)"); \
369 asm volatile("lw $a3, 32($sp)"); \
370 asm volatile("lw $t0, 36($sp)"); \
371 asm volatile("lw $t1, 40($sp)"); \
372 asm volatile("lw $t2, 44($sp)"); \
373 asm volatile("lw $t3, 48($sp)"); \
374 asm volatile("lw $t4, 52($sp)"); \
375 asm volatile("lw $t5, 56($sp)"); \
376 asm volatile("lw $t6, 60($sp)"); \
377 asm volatile("lw $t7, 64($sp)"); \
378 asm volatile("lw $t8, 68($sp)"); \
379 asm volatile("lw $t9, 72($sp)"); \
380 asm volatile("lw $ra, 76($sp)"); \
382 asm volatile("di"); \
383 asm volatile("ehb"); \
386 asm volatile("lw $k0, 84($sp)"); \
387 asm volatile("mtc0 $k0, $14"); \
388 asm volatile("lw $k0, 80($sp)"); \
389 asm volatile("mtc0 $k0, $12, 2"); \
390 asm volatile("addiu $sp, $sp, 92"); \
393 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
394 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
395 asm volatile("addiu $k1, $k1, -1"); \
396 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
397 asm volatile("bne $k1, $zero, 1f"); \
398 asm volatile("lw $k1, -4($sp)"); \
401 asm volatile("lui $k0, %hi(tn_int_sp)"); \
402 asm volatile("sw $sp, %lo(tn_int_sp)($k0)"); \
403 asm volatile("lui $k0, %hi(tn_user_sp)"); \
404 asm volatile("lw $sp, %lo(tn_user_sp)($k0)"); \
406 asm volatile("1:"); \
407 asm volatile("wrpgpr $sp, $sp"); \
408 asm volatile("mtc0 $k1, $12"); \
409 asm volatile("eret"); \
411 asm volatile(".set pop"); \
413 } __attribute((__noinline__)) void _func##vec(void)
434 #define tn_srs_isr(vec) \
435 __attribute__((__noinline__)) void _func##vec(void); \
436 void __attribute__((naked, nomips16)) \
437 __attribute__((vector(vec))) \
440 asm volatile(".set push"); \
441 asm volatile(".set mips32r2"); \
442 asm volatile(".set nomips16"); \
443 asm volatile(".set noreorder"); \
444 asm volatile(".set noat"); \
446 asm volatile("rdpgpr $sp, $sp"); \
449 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
450 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
451 asm volatile("addiu $k1, $k1, 1"); \
452 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
453 asm volatile("ori $k0, $zero, 1"); \
454 asm volatile("bne $k1, $k0, 1f"); \
457 asm volatile("lui $k0, %hi(tn_user_sp)"); \
458 asm volatile("sw $sp, %lo(tn_user_sp)($k0)"); \
459 asm volatile("lui $k0, %hi(tn_int_sp)"); \
460 asm volatile("lw $sp, %lo(tn_int_sp)($k0)"); \
462 asm volatile("1:"); \
464 asm volatile("addiu $sp, $sp, -20"); \
465 asm volatile("mfc0 $k1, $14"); \
466 asm volatile("mfc0 $k0, $12, 2"); \
467 asm volatile("sw $k1, 12($sp)"); \
468 asm volatile("sw $k0, 8($sp)"); \
469 asm volatile("mfc0 $k1, $12"); \
470 asm volatile("sw $k1, 16($sp)"); \
473 asm volatile("mfc0 $k0, $13"); \
474 asm volatile("ins $k1, $zero, 1, 15"); \
475 asm volatile("ext $k0, $k0, 10, 6"); \
476 asm volatile("ins $k1, $k0, 10, 6"); \
477 asm volatile("mtc0 $k1, $12"); \
480 asm volatile("mfhi $v0"); \
481 asm volatile("mflo $v1"); \
482 asm volatile("sw $v0, 4($sp)"); \
485 asm volatile("la $t0, _func"#vec); \
486 asm volatile("jalr $t0"); \
487 asm volatile("sw $v1, 0($sp)"); \
490 asm volatile("lw $t0, tn_curr_run_task"); \
491 asm volatile("lw $t1, tn_next_task_to_run"); \
492 asm volatile("lw $t0, 0($t0)"); \
493 asm volatile("lw $t1, 0($t1)"); \
494 asm volatile("lui $t2, %hi(IFS0SET)"); \
495 asm volatile("beq $t0, $t1, 1f"); \
496 asm volatile("ori $t1, $zero, 2"); \
497 asm volatile("sw $t1, %lo(IFS0SET)($t2)"); \
499 asm volatile("1:"); \
501 asm volatile("lw $v1, 0($sp)"); \
502 asm volatile("lw $v0, 4($sp)"); \
503 asm volatile("mtlo $v1"); \
504 asm volatile("mthi $v0"); \
506 asm volatile("di"); \
507 asm volatile("ehb"); \
510 asm volatile("lw $k0, 12($sp)"); \
511 asm volatile("mtc0 $k0, $14"); \
512 asm volatile("lw $k0, 8($sp)"); \
513 asm volatile("mtc0 $k0, $12, 2"); \
514 asm volatile("addiu $sp, $sp, 20"); \
517 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
518 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
519 asm volatile("addiu $k1, $k1, -1"); \
520 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
521 asm volatile("bne $k1, $zero, 1f"); \
522 asm volatile("lw $k1, -4($sp)"); \
525 asm volatile("lui $k0, %hi(tn_int_sp)"); \
526 asm volatile("sw $sp, %lo(tn_int_sp)($k0)"); \
527 asm volatile("lui $k0, %hi(tn_user_sp)"); \
528 asm volatile("lw $sp, %lo(tn_user_sp)($k0)"); \
530 asm volatile("1:"); \
531 asm volatile("wrpgpr $sp, $sp"); \
532 asm volatile("mtc0 $k1, $12"); \
533 asm volatile("eret"); \
535 asm volatile(".set pop"); \
537 } __attribute((__noinline__)) void _func##vec(void)
544 #endif // _TN_ARCH_PIC32_H
unsigned int TN_UWord
Unsigned integer type whose size is equal to the size of CPU register.