From 0da81fed5406294d9564f549c699563b06c2bd96 Mon Sep 17 00:00:00 2001 From: PulkoMandy Date: Fri, 1 Jan 2021 21:46:49 +0100 Subject: [PATCH] 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 --- headers/private/kernel/arch/sparc/arch_int.h | 59 +++++++++++++++++++- src/system/kernel/arch/sparc/arch_asm.S | 53 ++---------------- 2 files changed, 64 insertions(+), 48 deletions(-) diff --git a/headers/private/kernel/arch/sparc/arch_int.h b/headers/private/kernel/arch/sparc/arch_int.h index d59e0eb684..661a784603 100644 --- a/headers/private/kernel/arch/sparc/arch_int.h +++ b/headers/private/kernel/arch/sparc/arch_int.h @@ -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 */ diff --git a/src/system/kernel/arch/sparc/arch_asm.S b/src/system/kernel/arch/sparc/arch_asm.S index 25eef0aafc..33fe89becf 100644 --- a/src/system/kernel/arch/sparc/arch_asm.S +++ b/src/system/kernel/arch/sparc/arch_asm.S @@ -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)