From 4173bf1f786740329c96859e7c3bf72e6714903f Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Mon, 15 Jul 2024 20:52:25 +0200 Subject: [PATCH] exch, inth: save more data in context structure, and simplify entries --- include/gint/gint.h | 14 ++++--------- src/gdb/gdb.c | 2 +- src/intc/intc.c | 4 ++-- src/kernel/exch.s | 42 +++++++++++++-------------------------- src/kernel/inth.S | 47 ++++++++++++++++++++++---------------------- src/kernel/kernel.c | 2 +- src/kernel/syscall.c | 2 +- 7 files changed, 46 insertions(+), 67 deletions(-) diff --git a/include/gint/gint.h b/include/gint/gint.h index 84aeeb9..2c4ed09 100644 --- a/include/gint/gint.h +++ b/include/gint/gint.h @@ -166,16 +166,10 @@ extern int (*gint_inth_callback)(gint_call_t const *call); /* gint_inth_callback_context_t: Context of the interrupted function when an interrupt is handled by gint_inth_callback. */ typedef struct { - uint32_t ssr; - uint32_t spc; - uint32_t r7; - uint32_t r6; - uint32_t r5; - uint32_t r4; - uint32_t r3; - uint32_t r2; - uint32_t r1; - uint32_t r0; + uint32_t mach, macl, gbr; + uint32_t sr; + uint32_t pc; + uint32_t r[8]; } gint_inth_callback_context_t; /* gint_set_quit_handler(): Setup a call to be invoked when leaving the add-in diff --git a/src/gdb/gdb.c b/src/gdb/gdb.c index 1b9f0d2..e5aa661 100644 --- a/src/gdb/gdb.c +++ b/src/gdb/gdb.c @@ -766,7 +766,7 @@ static void gdb_notifier_function(void) if (gdb_single_step_backup.single_stepped) return; - gdb_handle_single_step(usb_interrupt_context->spc, UBC_BREAK_AFTER); + gdb_handle_single_step(usb_interrupt_context->pc, UBC_BREAK_AFTER); } static int gdb_panic_handler(uint32_t code) diff --git a/src/intc/intc.c b/src/intc/intc.c index 688d194..caba6a2 100644 --- a/src/intc/intc.c +++ b/src/intc/intc.c @@ -168,8 +168,8 @@ void *intc_handler(int event_code, const void *handler, size_t size) /* On SH4, just use the code as offset */ else { - /* 0x40 is the size of the entry gate */ - dest = (void *)cpu_getVBR() + 0x640 + (event_code - 0x400); + /* 0x20 is the size of the entry gate */ + dest = (void *)cpu_getVBR() + 0x620 + (event_code - 0x400); } return memcpy(dest, handler, size); diff --git a/src/kernel/exch.s b/src/kernel/exch.s index 70d876c..7dc9db4 100644 --- a/src/kernel/exch.s +++ b/src/kernel/exch.s @@ -4,28 +4,23 @@ _gint_exch: sts.l pr, @-r15 - stc.l gbr, @-r15 - sts.l mach, @-r15 - sts.l macl, @-r15 - mov.l r8, @-r15 - mov.l r9, @-r15 /* Get the first word of the gint hardware array (HWMPU). If it has the last bit set, we're SH3 */ mov.l .gint, r0 mov.l @r0, r0 tst #1, r0 - mov.l .expevt_sh4, r8 - mov.l .tra_sh4, r9 + mov.l .expevt_sh4, r6 + mov.l .tra_sh4, r7 bt syscall - mov.l .expevt_sh3, r8 - mov.l .tra_sh3, r9 + mov.l .expevt_sh3, r6 + mov.l .tra_sh3, r7 syscall: /* If this is trapa #31, save context and run the syscall interface. */ - mov.l @r8, r4 + mov.l @r6, r4 mov.w .expevt_trapa, r5 - mov.l @r9, r0 + mov.l @r7, r0 cmp/eq r4, r5 bf catch cmp/eq #31*4, r0 @@ -45,36 +40,32 @@ syscall: catch: /* Panic if the catcher is NULL */ mov.l .catcher, r0 + mov.l r4, @-r15 mov.l @r0, r0 tst r0, r0 bt panic /* Set BL=0, IMASK=15 */ - stc sr, r9 + stc sr, r7 + mov.l r7, @-r15 mov.l .SR_set_IMASK, r1 - or r9, r1 + or r7, r1 mov.l .SR_clear_BL, r2 and r2, r1 ldc r1, sr /* Call the catcher and leave if it returns zero (exception handled) */ jsr @r0 - mov.l @r8, r4 + nop - ldc r9, sr + ldc.l @r15+, sr tst r0, r0 - bt end + bt.s end + mov.l @r15+, r4 panic: /* RTE to the panic function, but manually, so that SPC is preserved */ - mov.l @r8, r4 ldc r4, r4_bank - - mov.l @r15+, r9 - mov.l @r15+, r8 - lds.l @r15+, macl - lds.l @r15+, mach - ldc.l @r15+, gbr lds.l @r15+, pr /* Here we switch banks so r0..r7 change meaning! */ @@ -87,11 +78,6 @@ panic: nop end: - mov.l @r15+, r9 - mov.l @r15+, r8 - lds.l @r15+, macl - lds.l @r15+, mach - ldc.l @r15+, gbr lds.l @r15+, pr rte nop diff --git a/src/kernel/inth.S b/src/kernel/inth.S index 1133722..fd39167 100644 --- a/src/kernel/inth.S +++ b/src/kernel/inth.S @@ -63,15 +63,12 @@ _gint_inth_7305: 1: .long 0xff000028 #endif -/* SH7305-TYPE INTERRUPT HANDLER ENTRY - 40 BYTES */ +/* SH7305-TYPE INTERRUPT HANDLER ENTRY - 28 BYTES */ _gint_inth_7305: /* Save caller-saved registers which might currently be in use by the interrupted function, as we don't know what the callback will do */ sts.l pr, @-r15 - stc.l gbr, @-r15 - sts.l mach, @-r15 - sts.l macl, @-r15 /* Get the event code from the INTEVT register */ mov.l 1f, r0 @@ -89,15 +86,11 @@ _gint_inth_7305: .jump_over: /* Restore caller-saved registers */ - lds.l @r15+, macl - lds.l @r15+, mach - ldc.l @r15+, gbr lds.l @r15+, pr - rte nop - .zero 24 + .zero 4 1: .long 0xff000028 .first_entry: @@ -200,16 +193,19 @@ _inth_remap: @r4 Address of callback function -> Returns the return value of the callback (int). */ _gint_inth_callback_reloc: - stc.l r0_bank, @-r15 - stc.l r1_bank, @-r15 - stc.l r2_bank, @-r15 - stc.l r3_bank, @-r15 - stc.l r4_bank, @-r15 - stc.l r5_bank, @-r15 - stc.l r6_bank, @-r15 stc.l r7_bank, @-r15 + stc.l r6_bank, @-r15 + stc.l r5_bank, @-r15 + stc.l r4_bank, @-r15 + stc.l r3_bank, @-r15 + stc.l r2_bank, @-r15 + stc.l r1_bank, @-r15 + stc.l r0_bank, @-r15 stc.l spc, @-r15 stc.l ssr, @-r15 + stc.l gbr, @-r15 + sts.l macl, @-r15 + sts.l mach, @-r15 /* We backup the address of the gint_inth_callback_context_t built on the stack to the user bank. */ ldc r15, r4_bank @@ -279,17 +275,20 @@ _gint_inth_callback_reloc: /* We can now pull the return value since interrupts are disabled */ stc r0_bank, r0 + lds.l @r15+, mach + lds.l @r15+, macl + ldc.l @r15+, gbr ldc.l @r15+, ssr ldc.l @r15+, spc - ldc.l @r15+, r7_bank - ldc.l @r15+, r6_bank - ldc.l @r15+, r5_bank - ldc.l @r15+, r4_bank - ldc.l @r15+, r3_bank - ldc.l @r15+, r2_bank - ldc.l @r15+, r1_bank - rts ldc.l @r15+, r0_bank + ldc.l @r15+, r1_bank + ldc.l @r15+, r2_bank + ldc.l @r15+, r3_bank + ldc.l @r15+, r4_bank + ldc.l @r15+, r5_bank + ldc.l @r15+, r6_bank + rts + ldc.l @r15+, r7_bank .align 4 .SR_clear_RB_BL: diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 47fe93e..602a9db 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -83,7 +83,7 @@ void kinit(void) /* Load the event handler entry points into memory */ memcpy((void *)VBR + 0x100, gint_exch, exch_size); memcpy((void *)VBR + 0x400, gint_tlbh, tlbh_size); - memcpy((void *)VBR + 0x600, inth_entry, 64); + memcpy((void *)VBR + 0x600, inth_entry, isSH3() ? 64 : 32); /* Initialize memory allocators */ kmalloc_init(); diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 2929cef..a7ffe68 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -9,5 +9,5 @@ void syscall_entry(gint_inth_callback_context_t *ptr) (void)ptr; ++debug_syscall_count; - debug_syscall_lastnr = ptr->r3; + debug_syscall_lastnr = ptr->r[3]; }