forked from PAWPAW-Mirror/lib_xua
199 lines
6.5 KiB
C
199 lines
6.5 KiB
C
#ifndef __interrupt_h__
|
|
#define __interrupt_h__
|
|
|
|
#define store_args0(c) \
|
|
asm("kentsp 19; stw %0, sp[1]; krestsp 19"::"r"(c));
|
|
|
|
#define store_args1(c,x) \
|
|
asm("kentsp 20; stw %0, sp[1]; stw %1, sp[2]; krestsp 20"::"r"(c),"r"(x));
|
|
|
|
#define store_args2(c,x0,x1) \
|
|
asm("kentsp 21; stw %0, sp[1];" \
|
|
"stw %1, sp[2];" \
|
|
"stw %2, sp[3];" \
|
|
" krestsp 21"::"r"(c),"r"(x0),"r"(x1));
|
|
|
|
#define store_args3(c,x0,x1,x2) \
|
|
asm("kentsp 22; stw %0, sp[1];" \
|
|
"stw %1, sp[2];" \
|
|
"stw %2, sp[3];" \
|
|
"stw %3, sp[4];" \
|
|
" krestsp 22"::"r"(c),"r"(x0),"r"(x1),"r"(x2));
|
|
|
|
#define store_args4(c,x0,x1,x2,x3) \
|
|
asm("kentsp 23; stw %4, sp[1];" \
|
|
"stw %0, sp[2];" \
|
|
"stw %1, sp[3];" \
|
|
"stw %2, sp[4];" \
|
|
"stw %3, sp[5];" \
|
|
" krestsp 23"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3));
|
|
|
|
#define store_args5(c,x0,x1,x2,x3,x4) \
|
|
asm("kentsp 24;" \
|
|
"stw %4, sp[1];" \
|
|
"stw %5, sp[2];" \
|
|
"stw %0, sp[3];" \
|
|
"stw %1, sp[4];" \
|
|
"stw %2, sp[5];" \
|
|
"stw %3, sp[6];" \
|
|
" krestsp 24"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4));
|
|
|
|
#define store_args6(c,x0,x1,x2,x3,x4,x5) \
|
|
asm("kentsp 25;" \
|
|
"stw %4, sp[1];" \
|
|
"stw %5, sp[2];" \
|
|
"stw %6, sp[3];" \
|
|
"stw %0, sp[4];" \
|
|
"stw %1, sp[5];" \
|
|
"stw %2, sp[6];" \
|
|
"stw %3, sp[7];" \
|
|
" krestsp 25"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4),"r"(x5));
|
|
|
|
#define store_args7(c,x0,x1,x2,x3,x4,x5,x6) \
|
|
asm("kentsp 26;" \
|
|
"stw %4, sp[1];" \
|
|
"stw %5, sp[2];" \
|
|
"stw %6, sp[3];" \
|
|
"stw %7, sp[4];" \
|
|
"stw %0, sp[5];" \
|
|
"stw %1, sp[6];" \
|
|
"stw %2, sp[7];" \
|
|
"stw %3, sp[8];" \
|
|
" krestsp 26"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4),"r"(x5),"r"(x6));
|
|
|
|
#define store_args8(c,x0,x1,x2,x3,x4,x5,x6,x7) \
|
|
asm("kentsp 27;" \
|
|
"stw %4, sp[1];" \
|
|
"stw %5, sp[2];" \
|
|
"stw %6, sp[3];" \
|
|
"stw %7, sp[4];" \
|
|
"stw %8, sp[5];" \
|
|
"stw %0, sp[6];" \
|
|
"stw %1, sp[7];" \
|
|
"stw %2, sp[8];" \
|
|
"stw %3, sp[9];" \
|
|
" krestsp 27"::"r"(c),"r"(x0),"r"(x1),"r"(x2),"r"(x3),"r"(x4),"r"(x5),"r"(x6),"r"(x7));
|
|
|
|
|
|
|
|
|
|
#define load_args0(f) \
|
|
"ldw r0, sp[1]\n"
|
|
|
|
#define load_args1(f)\
|
|
"ldw r0, sp[1]\n" \
|
|
"ldw r1, sp[2]\n"
|
|
|
|
#define load_args2(f)\
|
|
"ldw r0, sp[1]\n" \
|
|
"ldw r1, sp[2]\n" \
|
|
"ldw r2, sp[3]\n"
|
|
|
|
#define load_args3(f)\
|
|
"ldw r0, sp[1]\n" \
|
|
"ldw r1, sp[2]\n" \
|
|
"ldw r2, sp[3]\n" \
|
|
"ldw r3, sp[4]\n"
|
|
|
|
#define load_argsn(f, args) \
|
|
".linkset __"#f"_handler_arg0, "#args"-2\n"\
|
|
"ldw r0, sp[" "__"#f"_handler_arg0" "]\n" \
|
|
".linkset __"#f"_handler_arg1, "#args"-1\n"\
|
|
"ldw r1, sp[" "__"#f"_handler_arg1" "]\n" \
|
|
".linkset __"#f"_handler_arg2, "#args"-0\n"\
|
|
"ldw r2, sp[" "__"#f"_handler_arg2" "]\n" \
|
|
".linkset __"#f"_handler_arg3, "#args"+1\n"\
|
|
"ldw r3, sp[" "__"#f"_handler_arg3" "]\n"
|
|
|
|
#define load_args4(f) load_argsn(f,4)
|
|
#define load_args5(f) load_argsn(f,5)
|
|
#define load_args6(f) load_argsn(f,6)
|
|
#define load_args7(f) load_argsn(f,7)
|
|
#define load_args8(f) load_argsn(f,8)
|
|
|
|
#define save_state(f,args) \
|
|
".linkset __"#f"_handler_r0_save, "#args"+12\n" \
|
|
"stw r0, sp[" "__"#f"_handler_r0_save" "]\n" \
|
|
".linkset __"#f"_handler_r1_save, "#args"+13\n" \
|
|
"stw r1, sp[" "__"#f"_handler_r1_save" "]\n" \
|
|
".linkset __"#f"_handler_r2_save, "#args"+2\n" \
|
|
"stw r2, sp[" "__"#f"_handler_r2_save" "]\n" \
|
|
".linkset __"#f"_handler_r3_save, "#args"+3\n" \
|
|
"stw r3, sp[" "__"#f"_handler_r3_save" "]\n" \
|
|
".linkset __"#f"_handler_r4_save, "#args"+4\n" \
|
|
"stw r4, sp[" "__"#f"_handler_r4_save" "]\n" \
|
|
".linkset __"#f"_handler_r5_save, "#args"+5\n" \
|
|
"stw r5, sp[" "__"#f"_handler_r5_save" "]\n" \
|
|
".linkset __"#f"_handler_r6_save, "#args"+6\n" \
|
|
"stw r6, sp[" "__"#f"_handler_r6_save" "]\n" \
|
|
".linkset __"#f"_handler_r7_save, "#args"+7\n" \
|
|
"stw r7, sp[" "__"#f"_handler_r7_save" "]\n" \
|
|
".linkset __"#f"_handler_r8_save, "#args"+8\n" \
|
|
"stw r8, sp[" "__"#f"_handler_r8_save" "]\n" \
|
|
".linkset __"#f"_handler_r9_save, "#args"+9\n" \
|
|
"stw r9, sp[" "__"#f"_handler_r9_save" "]\n" \
|
|
".linkset __"#f"_handler_r10_save, "#args"+10\n" \
|
|
"stw r10, sp[" "__"#f"_handler_r10_save" "]\n" \
|
|
".linkset __"#f"_handler_r11_save, "#args"+11\n" \
|
|
"stw r11, sp[" "__"#f"_handler_r11_save" "]\n" \
|
|
".linkset __"#f"_handler_lr_save, "#args"+14\n" \
|
|
"stw lr, sp[" "__"#f"_handler_lr_save" "]\n"
|
|
|
|
#define restore_state(f,args) \
|
|
"ldw r0, sp[" "__"#f"_handler_r0_save" "]\n" \
|
|
"ldw r1, sp[" "__"#f"_handler_r1_save" "]\n" \
|
|
"ldw r2, sp[" "__"#f"_handler_r2_save" "]\n" \
|
|
"ldw r3, sp[" "__"#f"_handler_r3_save" "]\n" \
|
|
"ldw r4, sp[" "__"#f"_handler_r4_save" "]\n" \
|
|
"ldw r5, sp[" "__"#f"_handler_r5_save" "]\n" \
|
|
"ldw r6, sp[" "__"#f"_handler_r6_save" "]\n" \
|
|
"ldw r7, sp[" "__"#f"_handler_r7_save" "]\n" \
|
|
"ldw r8, sp[" "__"#f"_handler_r8_save" "]\n" \
|
|
"ldw r9, sp[" "__"#f"_handler_r9_save" "]\n" \
|
|
"ldw r10, sp[" "__"#f"_handler_r10_save" "]\n" \
|
|
"ldw r11, sp[" "__"#f"_handler_r11_save" "]\n" \
|
|
"ldw lr, sp[" "__"#f"_handler_lr_save" "]\n"
|
|
|
|
|
|
#define STRINGIFY0(x) #x
|
|
#define STRINGIFY(x) STRINGIFY0(x)
|
|
|
|
#define ENABLE_INTERRUPTS() asm("setsr " STRINGIFY(XS1_SR_IEBLE_SET(0, 1)))
|
|
|
|
#define DISABLE_INTERRUPTS() asm("clrsr " STRINGIFY(XS1_SR_IEBLE_SET(0, 1)))
|
|
|
|
//int ksp_enter, ksp_exit, r11_store;
|
|
|
|
#define do_interrupt_handler(f,args) \
|
|
asm("bu .L__" #f "_handler_skip;\n" \
|
|
"__" #f "_handler:\n" \
|
|
"kentsp " #args " + 19\n" \
|
|
"__kent:" \
|
|
save_state(f,args) \
|
|
load_args ## args (f) \
|
|
"bl " #f "\n" \
|
|
restore_state(f,args) \
|
|
"krestsp " #args " + 19 \n" \
|
|
"__kret:\n" \
|
|
"kret\n" \
|
|
".L__" #f "_handler_skip:\n");
|
|
|
|
#define set_interrupt_handler(f, nstackwords, args, c, ...) \
|
|
asm (" .section .dp.data, \"adw\", @progbits\n" \
|
|
" .align 4\n" \
|
|
"__" #f "_kernel_stack:\n" \
|
|
" .space " #nstackwords ", 0\n" \
|
|
" .text\n"); \
|
|
asm("mov r10, %0; ldaw r11, dp[__" #f "_kernel_stack];add r11, r11, r10;ldaw r10, sp[0]; "\
|
|
"set sp,r11;stw r10, sp[0]; krestsp 0"::"r"(nstackwords-8):"r10","r11"); \
|
|
store_args ## args(c, __VA_ARGS__) \
|
|
do_interrupt_handler(f, args) \
|
|
asm("ldap r11, __" #f "_handler; setv res[%0],r11"::"r"(c):"r11"); \
|
|
asm("setc res[%0], 0xa; eeu res[%0]"::"r"(c)); \
|
|
asm("setsr (((0) & ~(((1 << 0x1) - 1) << 0x1)) | (((1) << 0x1) & (((1 << 0x1) - 1) << 0x1)))");
|
|
|
|
|
|
|
|
#endif
|
|
|