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(); tn_arch_sr_restore(tn_save_status_reg)
212 # define TN_INT_DIS_SAVE() __asm__ __volatile__("di %0; ehb" : "=d" (tn_save_status_reg))
213 # define TN_INT_RESTORE() _TN_PIC32_INTSAVE_CHECK(); __builtin_mtc0(12, 0, tn_save_status_reg)
223 #define TN_INT_IDIS_SAVE() TN_INT_DIS_SAVE()
232 #define TN_INT_IRESTORE() TN_INT_RESTORE()
237 #define TN_IS_INT_DISABLED() ((__builtin_mfc0(12, 0) & 1) == 0)
240 #endif //-- DOXYGEN_SHOULD_SKIP_THIS
269 #define tn_soft_isr(vec) \
270 __attribute__((__noinline__)) void _func##vec(void); \
271 void __attribute__((naked, nomips16)) \
272 __attribute__((vector(vec))) \
275 asm volatile(".set push"); \
276 asm volatile(".set mips32r2"); \
277 asm volatile(".set nomips16"); \
278 asm volatile(".set noreorder"); \
279 asm volatile(".set noat"); \
281 asm volatile("rdpgpr $sp, $sp"); \
284 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
285 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
286 asm volatile("addiu $k1, $k1, 1"); \
287 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
288 asm volatile("ori $k0, $zero, 1"); \
289 asm volatile("bne $k1, $k0, 1f"); \
292 asm volatile("lui $k0, %hi(tn_user_sp)"); \
293 asm volatile("sw $sp, %lo(tn_user_sp)($k0)"); \
294 asm volatile("lui $k0, %hi(tn_int_sp)"); \
295 asm volatile("lw $sp, %lo(tn_int_sp)($k0)"); \
297 asm volatile("1:"); \
299 asm volatile("addiu $sp, $sp, -92"); \
300 asm volatile("mfc0 $k1, $14"); \
301 asm volatile("mfc0 $k0, $12, 2"); \
302 asm volatile("sw $k1, 84($sp)"); \
303 asm volatile("sw $k0, 80($sp)"); \
304 asm volatile("mfc0 $k1, $12"); \
305 asm volatile("sw $k1, 88($sp)"); \
308 asm volatile("mfc0 $k0, $13"); \
309 asm volatile("ins $k1, $zero, 1, 15"); \
310 asm volatile("ext $k0, $k0, 10, 6"); \
311 asm volatile("ins $k1, $k0, 10, 6"); \
312 asm volatile("mtc0 $k1, $12"); \
315 asm volatile("sw $ra, 76($sp)"); \
316 asm volatile("sw $t9, 72($sp)"); \
317 asm volatile("sw $t8, 68($sp)"); \
318 asm volatile("sw $t7, 64($sp)"); \
319 asm volatile("sw $t6, 60($sp)"); \
320 asm volatile("sw $t5, 56($sp)"); \
321 asm volatile("sw $t4, 52($sp)"); \
322 asm volatile("sw $t3, 48($sp)"); \
323 asm volatile("sw $t2, 44($sp)"); \
324 asm volatile("sw $t1, 40($sp)"); \
325 asm volatile("sw $t0, 36($sp)"); \
326 asm volatile("sw $a3, 32($sp)"); \
327 asm volatile("sw $a2, 28($sp)"); \
328 asm volatile("sw $a1, 24($sp)"); \
329 asm volatile("sw $a0, 20($sp)"); \
330 asm volatile("sw $v1, 16($sp)"); \
331 asm volatile("sw $v0, 12($sp)"); \
332 asm volatile("sw $at, 8($sp)"); \
333 asm volatile("mfhi $v0"); \
334 asm volatile("mflo $v1"); \
335 asm volatile("sw $v0, 4($sp)"); \
338 asm volatile("la $t0, _func"#vec); \
339 asm volatile("jalr $t0"); \
340 asm volatile("sw $v1, 0($sp)"); \
343 asm volatile("lw $t0, tn_curr_run_task"); \
344 asm volatile("lw $t1, tn_next_task_to_run"); \
345 asm volatile("lw $t0, 0($t0)"); \
346 asm volatile("lw $t1, 0($t1)"); \
347 asm volatile("lui $t2, %hi(IFS0SET)"); \
348 asm volatile("beq $t0, $t1, 1f"); \
349 asm volatile("ori $t1, $zero, 2"); \
350 asm volatile("sw $t1, %lo(IFS0SET)($t2)"); \
352 asm volatile("1:"); \
354 asm volatile("lw $v1, 0($sp)"); \
355 asm volatile("lw $v0, 4($sp)"); \
356 asm volatile("mtlo $v1"); \
357 asm volatile("mthi $v0"); \
358 asm volatile("lw $at, 8($sp)"); \
359 asm volatile("lw $v0, 12($sp)"); \
360 asm volatile("lw $v1, 16($sp)"); \
361 asm volatile("lw $a0, 20($sp)"); \
362 asm volatile("lw $a1, 24($sp)"); \
363 asm volatile("lw $a2, 28($sp)"); \
364 asm volatile("lw $a3, 32($sp)"); \
365 asm volatile("lw $t0, 36($sp)"); \
366 asm volatile("lw $t1, 40($sp)"); \
367 asm volatile("lw $t2, 44($sp)"); \
368 asm volatile("lw $t3, 48($sp)"); \
369 asm volatile("lw $t4, 52($sp)"); \
370 asm volatile("lw $t5, 56($sp)"); \
371 asm volatile("lw $t6, 60($sp)"); \
372 asm volatile("lw $t7, 64($sp)"); \
373 asm volatile("lw $t8, 68($sp)"); \
374 asm volatile("lw $t9, 72($sp)"); \
375 asm volatile("lw $ra, 76($sp)"); \
377 asm volatile("di"); \
378 asm volatile("ehb"); \
381 asm volatile("lw $k0, 84($sp)"); \
382 asm volatile("mtc0 $k0, $14"); \
383 asm volatile("lw $k0, 80($sp)"); \
384 asm volatile("mtc0 $k0, $12, 2"); \
385 asm volatile("addiu $sp, $sp, 92"); \
388 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
389 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
390 asm volatile("addiu $k1, $k1, -1"); \
391 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
392 asm volatile("bne $k1, $zero, 1f"); \
393 asm volatile("lw $k1, -4($sp)"); \
396 asm volatile("lui $k0, %hi(tn_int_sp)"); \
397 asm volatile("sw $sp, %lo(tn_int_sp)($k0)"); \
398 asm volatile("lui $k0, %hi(tn_user_sp)"); \
399 asm volatile("lw $sp, %lo(tn_user_sp)($k0)"); \
401 asm volatile("1:"); \
402 asm volatile("wrpgpr $sp, $sp"); \
403 asm volatile("mtc0 $k1, $12"); \
404 asm volatile("eret"); \
406 asm volatile(".set pop"); \
408 } __attribute((__noinline__)) void _func##vec(void)
429 #define tn_srs_isr(vec) \
430 __attribute__((__noinline__)) void _func##vec(void); \
431 void __attribute__((naked, nomips16)) \
432 __attribute__((vector(vec))) \
435 asm volatile(".set push"); \
436 asm volatile(".set mips32r2"); \
437 asm volatile(".set nomips16"); \
438 asm volatile(".set noreorder"); \
439 asm volatile(".set noat"); \
441 asm volatile("rdpgpr $sp, $sp"); \
444 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
445 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
446 asm volatile("addiu $k1, $k1, 1"); \
447 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
448 asm volatile("ori $k0, $zero, 1"); \
449 asm volatile("bne $k1, $k0, 1f"); \
452 asm volatile("lui $k0, %hi(tn_user_sp)"); \
453 asm volatile("sw $sp, %lo(tn_user_sp)($k0)"); \
454 asm volatile("lui $k0, %hi(tn_int_sp)"); \
455 asm volatile("lw $sp, %lo(tn_int_sp)($k0)"); \
457 asm volatile("1:"); \
459 asm volatile("addiu $sp, $sp, -20"); \
460 asm volatile("mfc0 $k1, $14"); \
461 asm volatile("mfc0 $k0, $12, 2"); \
462 asm volatile("sw $k1, 12($sp)"); \
463 asm volatile("sw $k0, 8($sp)"); \
464 asm volatile("mfc0 $k1, $12"); \
465 asm volatile("sw $k1, 16($sp)"); \
468 asm volatile("mfc0 $k0, $13"); \
469 asm volatile("ins $k1, $zero, 1, 15"); \
470 asm volatile("ext $k0, $k0, 10, 6"); \
471 asm volatile("ins $k1, $k0, 10, 6"); \
472 asm volatile("mtc0 $k1, $12"); \
475 asm volatile("mfhi $v0"); \
476 asm volatile("mflo $v1"); \
477 asm volatile("sw $v0, 4($sp)"); \
480 asm volatile("la $t0, _func"#vec); \
481 asm volatile("jalr $t0"); \
482 asm volatile("sw $v1, 0($sp)"); \
485 asm volatile("lw $t0, tn_curr_run_task"); \
486 asm volatile("lw $t1, tn_next_task_to_run"); \
487 asm volatile("lw $t0, 0($t0)"); \
488 asm volatile("lw $t1, 0($t1)"); \
489 asm volatile("lui $t2, %hi(IFS0SET)"); \
490 asm volatile("beq $t0, $t1, 1f"); \
491 asm volatile("ori $t1, $zero, 2"); \
492 asm volatile("sw $t1, %lo(IFS0SET)($t2)"); \
494 asm volatile("1:"); \
496 asm volatile("lw $v1, 0($sp)"); \
497 asm volatile("lw $v0, 4($sp)"); \
498 asm volatile("mtlo $v1"); \
499 asm volatile("mthi $v0"); \
501 asm volatile("di"); \
502 asm volatile("ehb"); \
505 asm volatile("lw $k0, 12($sp)"); \
506 asm volatile("mtc0 $k0, $14"); \
507 asm volatile("lw $k0, 8($sp)"); \
508 asm volatile("mtc0 $k0, $12, 2"); \
509 asm volatile("addiu $sp, $sp, 20"); \
512 asm volatile("lui $k0, %hi(tn_int_nest_count)"); \
513 asm volatile("lw $k1, %lo(tn_int_nest_count)($k0)"); \
514 asm volatile("addiu $k1, $k1, -1"); \
515 asm volatile("sw $k1, %lo(tn_int_nest_count)($k0)"); \
516 asm volatile("bne $k1, $zero, 1f"); \
517 asm volatile("lw $k1, -4($sp)"); \
520 asm volatile("lui $k0, %hi(tn_int_sp)"); \
521 asm volatile("sw $sp, %lo(tn_int_sp)($k0)"); \
522 asm volatile("lui $k0, %hi(tn_user_sp)"); \
523 asm volatile("lw $sp, %lo(tn_user_sp)($k0)"); \
525 asm volatile("1:"); \
526 asm volatile("wrpgpr $sp, $sp"); \
527 asm volatile("mtc0 $k1, $12"); \
528 asm volatile("eret"); \
530 asm volatile(".set pop"); \
532 } __attribute((__noinline__)) void _func##vec(void)
539 #endif // _TN_ARCH_PIC32_H
unsigned int TN_UWord
Unsigned integer type whose size is equal to the size of CPU register.