sparc: fix interrupt enable/disable code

The manually written code was all wrong (missing branch delay slots,
wrong type of return instruction used, probably more bugs). Use the same
approach as x86 to have inline functions instead, which is much better
for performance and simpler to write.

Change-Id: Iac0fc814c15311658f983da58ac7f9d3edd75b81
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3595
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
PulkoMandy 2021-01-01 21:46:49 +01:00 committed by waddlesplash
parent 6f743e6853
commit 0da81fed54
2 changed files with 64 additions and 48 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2019, Haiku Inc. All rights reserved.
* Copyright 2005-2021, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -14,5 +14,62 @@
#define NUM_IO_VECTORS 256
static inline void
arch_int_enable_interrupts_inline(void)
{
int tmp;
asm volatile(
"rdpr %%pstate, %0\n"
"or %0, 2, %0\n"
"wrpr %0, %%pstate\n"
: "=r" (tmp)
);
}
static inline int
arch_int_disable_interrupts_inline(void)
{
int flags;
int tmp;
asm volatile(
"rdpr %%pstate, %0\n"
"andn %0, 2, %1\n"
"wrpr %1, %%pstate\n"
: "=r" (flags), "=r" (tmp)
);
return flags & 2;
}
static inline void
arch_int_restore_interrupts_inline(int oldState)
{
if (oldState)
arch_int_enable_interrupts_inline();
}
static inline bool
arch_int_are_interrupts_enabled_inline(void)
{
int flags;
asm volatile(
"rdpr %%pstate, %0\n"
: "=r" (flags)
);
return flags & 2;
}
// map the functions to the inline versions
#define arch_int_enable_interrupts() arch_int_enable_interrupts_inline()
#define arch_int_disable_interrupts() arch_int_disable_interrupts_inline()
#define arch_int_restore_interrupts(status) \
arch_int_restore_interrupts_inline(status)
#define arch_int_are_interrupts_enabled() \
arch_int_are_interrupts_enabled_inline()
#endif /* _KERNEL_ARCH_SPARC_INT_H */

View File

@ -10,66 +10,25 @@
.text
/* void arch_int_enable_interrupts(void) */
FUNCTION(arch_int_enable_interrupts):
rdpr %pstate, %o0
or %o0, 2, %o0
wrpr %o0, 0, %pstate
ret
FUNCTION_END(arch_int_enable_interrupts)
/* int arch_int_disable_interrupts(void)
*/
FUNCTION(arch_int_disable_interrupts):
rdpr %pstate, %o1
// Set output register to previous state
and %o1, 2, %o0
// Clear interrupt bit
andn %o1, 2, %o1
wrpr %o1, 0, %pstate
ret
FUNCTION_END(arch_int_disable_interrupts)
/* void arch_int_restore_interrupts(int oldState)
*/
FUNCTION(arch_int_restore_interrupts):
rdpr %pstate, %o1
// Clear interrupt bit
andn %o1, 2, %o1
// Restore previous interript bit state
or %o1, %o0, %o1
wrpr %o1, 0, %pstate
ret
FUNCTION_END(arch_int_restore_interrupts)
/* bool arch_int_are_interrupts_enabled(void) */
FUNCTION(arch_int_are_interrupts_enabled):
rdpr %pstate, %o0
andn %o0, 2, %o0
ret
FUNCTION_END(arch_int_are_interrupts_enabled)
/* status_t arch_cpu_user_memcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */
FUNCTION(_arch_cpu_user_memcpy):
// TODO
ret
retl
nop
FUNCTION_END(_arch_cpu_user_memcpy)
/* status_t arch_cpu_user_memset(void *to, char c, size_t count, addr_t *faultHandler) */
FUNCTION(_arch_cpu_user_memset):
// TODO
ret
retl
nop
FUNCTION_END(_arch_cpu_user_memset)
/* ssize_t arch_cpu_user_strlcpy(void *to, const void *from, size_t size, addr_t *faultHandler) */
FUNCTION(_arch_cpu_user_strlcpy):
// TODO
ret
retl
nop
FUNCTION_END(_arch_cpu_user_strlcpy)