forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -19,69 +19,81 @@
|
||||
#include <rtems/asm.h>
|
||||
#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
|
||||
*/
|
||||
.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
|
||||
*/
|
||||
|
||||
.align 32 ! Align to 32-byte cache-line
|
||||
PUBLIC(syscall)
|
||||
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)
|
||||
|
||||
SYM(sparc_disable_interrupts):
|
||||
|
||||
mov SYS_irqdis, %g1
|
||||
retl
|
||||
ta 0
|
||||
|
||||
PUBLIC(sparc_enable_interrupts)
|
||||
|
||||
SYM(sparc_enable_interrupts):
|
||||
|
||||
mov SYS_irqen, %g1
|
||||
retl
|
||||
ta 0
|
||||
|
||||
PUBLIC(sparc_syscall_exit)
|
||||
PUBLIC(sparc_syscall_exit)
|
||||
|
||||
SYM(sparc_syscall_exit):
|
||||
|
||||
mov SYS_exit, %g1
|
||||
mov %o0, %g2 ! Additional exit code 1
|
||||
mov %o1, %g3 ! Additional exit code 2
|
||||
ta 0
|
||||
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)
|
||||
*/
|
||||
|
||||
.align 32 ! Align to 32-byte cache-line
|
||||
PUBLIC(syscall_irqdis)
|
||||
|
||||
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
|
||||
|
||||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
.align 32 ! Align to 32-byte cache-line
|
||||
PUBLIC(syscall_irqen)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
#define SYS_exit 1
|
||||
#define SYS_irqdis 2
|
||||
#define SYS_irqen 3
|
||||
|
||||
Reference in New Issue
Block a user