sparc: write through switched_from in arch_switch()

Write through switched_from in arch_switch() as required by the
switch protocol.

Also restructure the implementation to better match the template in
kernel_arch_interface.h, by removing a wrapper routine and instead
use CONTAINER_OF().

Fixes #32197

Signed-off-by: Martin Åberg <martin.aberg@gaisler.com>
This commit is contained in:
Martin Åberg 2021-02-11 16:04:17 +01:00 committed by Anas Nashif
parent 0c1877a999
commit 88f478108d
2 changed files with 29 additions and 7 deletions

View file

@ -13,12 +13,16 @@ GTEXT(z_sparc_arch_switch)
GTEXT(z_sparc_context_switch)
GTEXT(z_thread_entry_wrapper)
/* In this implementation, switch_handle is the thread itself. */
SECTION_FUNC(TEXT, z_sparc_arch_switch)
ba z_sparc_context_switch
sub %o1, ___thread_t_switch_handle_OFFSET, %o1
/*
* The routine z_sparc_context_switch() is called from arch_switch(), or from
* the interrupt trap handler in case of preemption. The subtraction to get the
* "old" thread from "switched_from" has already been performed and the "old"
* thread is now in register %o1. We can address old->switch_handle in assembly
* as: [%o1 + ___thread_t_switch_handle_OFFSET].
*
* The switch_handle is written in z_sparc_context_switch() after the old
* context has been saved.
*
* This is a leaf function, so only out registers
* can be used without saving their context first.
*
@ -101,6 +105,15 @@ SECTION_FUNC(TEXT, z_sparc_context_switch)
nop
nop
/*
* We have finished saving the "old" context and are also back in the
* register window for which z_sparc_context_switch() was called.
*
* Now write the old thread into switch handle.
* "old->switch_handle = old".
*/
st %o1, [%o1 + ___thread_t_switch_handle_OFFSET]
ldd [%o0 + _thread_offset_to_y], %o4
mov %o4, %y

View file

@ -26,11 +26,20 @@ static ALWAYS_INLINE void arch_kernel_init(void)
{
}
void z_sparc_arch_switch(void *switch_to, void **switched_from);
void z_sparc_context_switch(struct k_thread *newt, struct k_thread *oldt);
/*
* In this implementation, the thread->switch_handle is the thread itself, so
* the parameter "switched_from" is assumed to be the address of
* thread->switch_handle.
*/
static inline void arch_switch(void *switch_to, void **switched_from)
{
z_sparc_arch_switch(switch_to, switched_from);
struct k_thread *newt = switch_to;
struct k_thread *oldt = CONTAINER_OF(switched_from, struct k_thread,
switch_handle);
z_sparc_context_switch(newt, oldt);
}
FUNC_NORETURN void z_sparc_fatal_error(unsigned int reason,