From dff1803cfbec3775fff1b9c34cc707c05494dc3b Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Wed, 3 Dec 2014 11:35:52 +0100 Subject: SPARC: optimize IRQ enable & disable * Coding style cleanups. * Use OS reserved trap 0x89 for IRQ Disable * Use OS reserved trap 0x8A for IRQ Enable * Add to SPARC CPU supplement documentation This will result in faster Disable/Enable code since the system trap handler does not need to decode which function the user wants. Besides the IRQ disable/enabled can now be inline which avoids the caller to take into account that o0-o7+g1-g4 registers are destroyed by trap handler. It was also possible to reduce the interrupt trap handler by five instructions due to this. --- c/src/lib/libcpu/sparc/syscall/syscall.S | 118 +++++++++++++++++-------------- c/src/lib/libcpu/sparc/syscall/syscall.h | 2 - 2 files changed, 65 insertions(+), 55 deletions(-) (limited to 'c/src/lib/libcpu/sparc/syscall') diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.S b/c/src/lib/libcpu/sparc/syscall/syscall.S index 9ce7fa54ef..64c4805af6 100644 --- a/c/src/lib/libcpu/sparc/syscall/syscall.S +++ b/c/src/lib/libcpu/sparc/syscall/syscall.S @@ -19,69 +19,81 @@ #include #include "syscall.h" - .seg "text" - /* - * system call - * - * On entry: - * - * l0 = psr (from trap table) - * l1 = pc - * l2 = npc - * g1 = system call id - * - * System Call 1 (exit): - * g2 = additional exit code 1 - * g3 = additional exit code 2 - */ - -.align 32 ! Align to 32-byte cache-line - PUBLIC(syscall) + .seg "text" + /* + * system call - halt + * + * On entry: + * + * l0 = psr (from trap table) + * l1 = pc + * l2 = npc + * g1 = system call id (1) + * + * System Call 1 (exit): + * g2 = additional exit code 1 + * g3 = additional exit code 2 + */ + + PUBLIC(syscall) SYM(syscall): + ta 0 ! syscall 1, halt with %g1,%g2,%g3 info - ! "subcc, %g1, 3, %g0" done in trap table - bne 2f ! syscall 3? enable interrupt - and %i0, SPARC_PSR_PIL_MASK, %l4 - andn %l0, SPARC_PSR_PIL_MASK, %l5 - wr %l4, %l5, %psr ! Update PSR according to syscall 3 -1: ! leave, with 3 inst PSR-write delay - mov 0, %g1 ! clear %g1 - or %l0, SPARC_PSR_ET_MASK, %i0 ! return old psr with ET=1. No - ! effect on syscall 3 - jmpl %l2, %g0 - rett %l2 + 4 - -2: or %l0, 0x0f00, %l4 ! set PIL=15 - subcc %g1, 2, %g0 ! syscall 2? disable interrupts - beq,a 1b ! Annul delay-slot for syscall 1 - mov %l4, %psr ! Update PSR according to Syscall 2 - ta 0 ! syscall 1 (not 2 or 3), halt - - PUBLIC(sparc_disable_interrupts) + PUBLIC(sparc_syscall_exit) -SYM(sparc_disable_interrupts): - - mov SYS_irqdis, %g1 - retl - ta 0 +SYM(sparc_syscall_exit): - PUBLIC(sparc_enable_interrupts) + mov SYS_exit, %g1 + mov %o0, %g2 ! Additional exit code 1 + mov %o1, %g3 ! Additional exit code 2 + ta SPARC_SWTRAP_SYSCALL + + /* + * system call - Interrupt Disable + * + * On entry: + * + * l0 = psr (from trap table) + * l1 = pc + * l2 = npc + * l3 = psr | SPARC_PSR_PIL_MASK + * + * On exit: + * g1 = old psr (to user) + */ -SYM(sparc_enable_interrupts): +.align 32 ! Align to 32-byte cache-line + PUBLIC(syscall_irqdis) - mov SYS_irqen, %g1 - retl - ta 0 +SYM(syscall_irqdis): + mov %l3, %psr ! Set PSR. Write delay 3 instr + or %l0, SPARC_PSR_ET_MASK, %g1 ! return old PSR with ET=1 + nop ! PSR write delay + jmp %l2 ! Return to after TA 9. + rett %l2 + 4 - PUBLIC(sparc_syscall_exit) + /* + * system call - Interrupt Enable + * + * On entry: + * + * l0 = psr (from trap table) + * l1 = pc + * l2 = npc + * l3 = psr & ~0x0f00 + * g1 = new PIL to write (from user) + */ -SYM(sparc_syscall_exit): +.align 32 ! Align to 32-byte cache-line + PUBLIC(syscall_irqen) - mov SYS_exit, %g1 - mov %o0, %g2 ! Additional exit code 1 - mov %o1, %g3 ! Additional exit code 2 - ta 0 +SYM(syscall_irqen): + and %g1, SPARC_PSR_PIL_MASK, %l4 ! %l4 = (%g1 & 0xf00) + wr %l3, %l4, %psr ! PSR = (PSR & ~0xf00) ^ %l4 + nop; nop ! PSR write delay; + jmp %l2 ! Return to after TA 10. + rett %l2 + 4 #if defined(RTEMS_PARAVIRT) diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.h b/c/src/lib/libcpu/sparc/syscall/syscall.h index 9af3560267..2f20886840 100644 --- a/c/src/lib/libcpu/sparc/syscall/syscall.h +++ b/c/src/lib/libcpu/sparc/syscall/syscall.h @@ -1,3 +1 @@ #define SYS_exit 1 -#define SYS_irqdis 2 -#define SYS_irqen 3 -- cgit v1.2.3