From: kosmirror <kos...@us...> - 2025-08-05 18:13:02
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via f7ee03a8533adbba8dd6f03cc458a28b69802a89 (commit) via 85c46b357012ae25be83f811bf826d05b43397b8 (commit) via e8887270d1f896f2888791d905c620babd5fafab (commit) from c5243a942b2389d5231a32a5fffe0f0ce67e6592 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f7ee03a8533adbba8dd6f03cc458a28b69802a89 Author: Falco Girgis <gyr...@gm...> Date: Tue Aug 5 13:05:31 2025 -0500 Addressed review feedback. commit 85c46b357012ae25be83f811bf826d05b43397b8 Author: Falco Girgis <gyr...@gm...> Date: Tue Aug 5 09:19:07 2025 -0500 Addressed review feedback. commit e8887270d1f896f2888791d905c620babd5fafab Author: Falco Girgis <gyr...@gm...> Date: Sun Jun 8 22:30:52 2025 -0500 Faster IRQ enable/disable/restore + SR fetch. Despite being tiny little routines that clobber either just one register or nothing at all, the following routines were being implemented in pure out-of-line ASM, which meant the compiler could never inline them even with LTO: a. irq_get_sr() b. irq_restore() c. irq_disable() d. irq_enable() This PR moves them into inline functions as inline ASM where the compiler should definitely be inlining them at even low optimization levels for pretty high perf gainz, since these are very hot throughout the codebase. 1) Removed all out-of-line implementations of theses routines from entry.s. 2) Rewrote them as inlined functions in inline ASM within irq.h 3) Had to tweak the following ASM routines to no longer call into the removed routines, since ASM cannot call inline C functions: a. irq_save_regs() [entry.s] b. thd_block_now() [thdswitch.s] ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/include/arch/irq.h | 47 ++++++++++++------- kernel/arch/dreamcast/kernel/entry.s | 77 +++++++------------------------- kernel/arch/dreamcast/kernel/thdswitch.s | 22 +++++---- 3 files changed, 59 insertions(+), 87 deletions(-) diff --git a/kernel/arch/dreamcast/include/arch/irq.h b/kernel/arch/dreamcast/include/arch/irq.h index f0a50bf9..a6167499 100644 --- a/kernel/arch/dreamcast/include/arch/irq.h +++ b/kernel/arch/dreamcast/include/arch/irq.h @@ -1,9 +1,9 @@ /* KallistiOS ##version## arch/dreamcast/include/arch/irq.h - Copyright (C) 2000-2001 Megan Potter + Copyright (C) 2000, 2001 Megan Potter Copyright (C) 2024 Paul Cercueil - Copyright (C) 2024 Falco Girgis + Copyright (C) 2024, 2025 Falco Girgis */ @@ -308,7 +308,25 @@ typedef uint32_t irq_mask_t; \retval Status register word \sa irq_disable() */ -irq_mask_t irq_get_sr(void); +static inline irq_mask_t irq_get_sr(void) { + irq_mask_t value; + __asm__ volatile("stc sr, %0" : "=r" (value)); + return value; +} + +/** Restore IRQ state. + + This function will restore the interrupt state to the value specified. This + should correspond to a value returned by irq_disable(). + + \param v The IRQ state to restore. This should be a value + returned by irq_disable(). + + \sa irq_disable() +*/ +static inline void irq_restore(irq_mask_t old) { + __asm__ volatile("ldc %0, sr" : : "r" (old)); +} /** Disable interrupts. @@ -321,7 +339,11 @@ irq_mask_t irq_get_sr(void); \sa irq_restore(), irq_enable() */ -irq_mask_t irq_disable(void); +static inline irq_mask_t irq_disable(void) { + uint32_t mask = (uint32_t)irq_get_sr(); + irq_restore((mask & 0xefffff0f) | 0x000000f0); + return mask; +} /** Enable all interrupts. @@ -329,19 +351,10 @@ irq_mask_t irq_disable(void); \sa irq_disable() */ -void irq_enable(void); - -/** Restore IRQ state. - - This function will restore the interrupt state to the value specified. This - should correspond to a value returned by irq_disable(). - - \param v The IRQ state to restore. This should be a value - returned by irq_disable(). - - \sa irq_disable() -*/ -void irq_restore(irq_mask_t v); +static inline void irq_enable(void) { + uint32_t mask = ((uint32_t)irq_get_sr() & 0xefffff0f); + irq_restore(mask); +} /** \brief Disable interrupts with scope management. diff --git a/kernel/arch/dreamcast/kernel/entry.s b/kernel/arch/dreamcast/kernel/entry.s index 4f01bae7..1ee06592 100644 --- a/kernel/arch/dreamcast/kernel/entry.s +++ b/kernel/arch/dreamcast/kernel/entry.s @@ -1,8 +1,9 @@ ! KallistiOS ##version## ! ! arch/dreamcast/kernel/entry.s -! (c)2000-2001 Megan Potter +! Copyright (C) 2000, 2001 Megan Potter ! Copyright (C) 2023 Paul Cercueil <pa...@cr...> +! Copyright (C) 2025 Falco Girgis ! ! Assembler code for entry and exit to/from the kernel via exceptions ! @@ -111,8 +112,12 @@ _irq_save_regs: ! Before we enter the main C code again, re-enable exceptions ! (but not interrupts) so we can still debug inside handlers. - bsr _irq_disable - nop + mov.l irqd_and,r1 + mov.l irqd_or,r2 + stc sr,r0 + and r0,r1 + or r2,r1 + ldc r1,sr ! R4 still contains the exception code mov.l hdl_except,r2 ! Call handle_exception @@ -121,6 +126,12 @@ _irq_save_regs: bra _save_regs_finish nop + .align 2 +irqd_and: + .long 0xefffff0f +irqd_or: + .long 0x000000f0 + ! irq_force_return() jumps here; make sure we're in register ! bank 1 (as opposed to 0) _irq_force_return: @@ -331,62 +342,4 @@ _vma_table_400: ! TLB miss exceptions (MMU) _vma_table_600: ! IRQs nop bra _irq_save_regs - mov #3,r4 ! Set exception code - - -! Disable interrupts, but leave exceptions enabled. Returns the old -! interrupt status. -! -! Calling this inside an exception/interrupt handler will generally not have -! any effect. -! - .globl _irq_disable -_irq_disable: - mov.l _irqd_and,r1 - mov.l _irqd_or,r2 - stc sr,r0 - and r0,r1 - or r2,r1 - ldc r1,sr - rts - nop - - .align 2 -_irqd_and: - .long 0xefffff0f -_irqd_or: - .long 0x000000f0 - - -! Enable interrupts and exceptions. Returns the old interrupt status. -! -! Call this inside an exception/interrupt handler only with GREAT CARE. -! - .globl _irq_enable -_irq_enable: - mov.l _irqe_and,r1 - stc sr,r0 - and r0,r1 - ldc r1,sr - rts - nop - - .align 2 -_irqe_and: - .long 0xefffff0f - - -! Restore interrupts to the state returned by irq_disable() -! or irq_enable(). - .globl _irq_restore -_irq_restore: - ldc r4,sr - rts - nop - - -! Retrieve SR - .globl _irq_get_sr -_irq_get_sr: - rts - stc sr,r0 + mov #3,r4 ! Set exception code \ No newline at end of file diff --git a/kernel/arch/dreamcast/kernel/thdswitch.s b/kernel/arch/dreamcast/kernel/thdswitch.s index 26be2830..bf19c959 100644 --- a/kernel/arch/dreamcast/kernel/thdswitch.s +++ b/kernel/arch/dreamcast/kernel/thdswitch.s @@ -1,8 +1,9 @@ ! KallistiOS ##version## ! ! arch/dreamcast/kernel/thdswitch.s -! Copyright (c)2003 Megan Potter +! Copyright (C) 2003 Megan Potter ! Copyright (C) 2023 Paul Cercueil <pa...@cr...> +! Copyright (C) 2025 Falco Girgis ! ! Assembler code for swapping out running threads ! @@ -33,12 +34,13 @@ _thd_block_now: ! and start at R8. ! Save SR and disable interrupts - sts.l pr,@-r15 - mov.l idaddr,r0 - jsr @r0 - nop + mov.l irqd_and,r1 + mov.l irqd_or,r2 + stc sr,r0 + and r0,r1 + or r2,r1 + ldc r1,sr - lds.l @r15+,pr add #0x72,r4 mov r0,r1 @@ -122,9 +124,13 @@ _thd_block_now: jmp @r1 mov r0,r4 + .align 2 +irqd_and: + .long 0xefffff0f +irqd_or: + .long 0x000000f0 + .balign 4 -idaddr: - .long _irq_disable ifraddr: .long _irq_force_return tcnaddr: hooks/post-receive -- A pseudo Operating System for the Dreamcast. |