From 395250b5a9dea16f9303363509036b976bc2e272 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sat, 13 Jul 2024 10:10:38 +0200 Subject: [PATCH] exch: add trapa #31 handler --- CMakeLists.txt | 1 + include/gint/intc.h | 7 +++---- src/kernel/exch.s | 35 ++++++++++++++++++++++++++++++++++- src/kernel/syscall.c | 13 +++++++++++++ src/tmu/inth-tmu.s | 3 +-- 5 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 src/kernel/syscall.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 94c7fcf..eafed97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -125,6 +125,7 @@ set(SOURCES src/kernel/osmenu.c src/kernel/start.c src/kernel/start.S + src/kernel/syscall.c src/kernel/syscalls.S src/kernel/tlbh.S src/kernel/world.c diff --git a/include/gint/intc.h b/include/gint/intc.h index 7af58aa..1f43ae2 100644 --- a/include/gint/intc.h +++ b/include/gint/intc.h @@ -132,10 +132,9 @@ void *intc_handler(int event_code, void const *handler, size_t size); the numerous constraints of intc_handler(), at the cost of always going back to userspace and a small time overhead. - Since gint_inth_callback is used to do the heavy lifting of setting up a sane - context for C code, the gint_call_t object can be built with GINT_CALL_FLAG - if the called function expects a gint_inth_callback_context_t structure as its - first argument. + gint_inth_callback does the heavy lifting of setting up a sane context for C + code. If the gint_call_t object is built with GINT_CALL_FLAG, the function + is called with a gint_inth_callback_context_t * as its first argument. @event_code Identifier of the interrupt block @function Function to use as a handler diff --git a/src/kernel/exch.s b/src/kernel/exch.s index ccd97d5..70d876c 100644 --- a/src/kernel/exch.s +++ b/src/kernel/exch.s @@ -16,8 +16,31 @@ _gint_exch: mov.l @r0, r0 tst #1, r0 mov.l .expevt_sh4, r8 - bt catch + mov.l .tra_sh4, r9 + bt syscall mov.l .expevt_sh3, r8 + mov.l .tra_sh3, r9 + +syscall: + /* If this is trapa #31, save context and run the syscall interface. */ + mov.l @r8, r4 + mov.w .expevt_trapa, r5 + mov.l @r9, r0 + cmp/eq r4, r5 + bf catch + cmp/eq #31*4, r0 + bf catch + + add #-20, r15 + mov.l .syscall_entry_plus1, r0 + mov r15, r4 + mov.l .callback, r1 + mov.l @r1, r1 + jsr @r1 + mov.l r0, @r4 + + bra end + add #20, r15 catch: /* Panic if the catcher is NULL */ @@ -89,3 +112,13 @@ end: .long (0xf << 4) .SR_clear_BL: .long ~(1 << 28) +.callback: + .long _gint_inth_callback +.syscall_entry_plus1: + .long _syscall_entry + 1 +.tra_sh3: + .long 0xffffffd0 +.tra_sh4: + .long 0xff000020 +.expevt_trapa: + .word 0x160 diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c new file mode 100644 index 0000000..2929cef --- /dev/null +++ b/src/kernel/syscall.c @@ -0,0 +1,13 @@ +#include + +int debug_syscall_count = 0; +int debug_syscall_lastnr = 0; + +void syscall_entry(gint_inth_callback_context_t *ptr) +{ + /* TODO: Currently, only user's r0...r7, spc, and ssr are saved here */ + (void)ptr; + + ++debug_syscall_count; + debug_syscall_lastnr = ptr->r3; +} diff --git a/src/tmu/inth-tmu.s b/src/tmu/inth-tmu.s index 3344f9c..46bf5c3 100644 --- a/src/tmu/inth-tmu.s +++ b/src/tmu/inth-tmu.s @@ -32,8 +32,7 @@ _inth_tmu: sts.l pr, @-r15 mov.l r5, @-r15 - /* Clear the interrupt flag. Because r5 contains 0, 1 or 2 the 16 top - bits are 0 so we can compare without extending */ + /* Clear the interrupt flag */ 1: mov.w @r1, r5 extu.b r5, r3 cmp/eq r5, r3