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:
parent
0c1877a999
commit
88f478108d
|
@ -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
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue