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
2 changed files with 29 additions and 7 deletions
|
@ -13,12 +13,16 @@ GTEXT(z_sparc_arch_switch)
|
||||||
GTEXT(z_sparc_context_switch)
|
GTEXT(z_sparc_context_switch)
|
||||||
GTEXT(z_thread_entry_wrapper)
|
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
|
* This is a leaf function, so only out registers
|
||||||
* can be used without saving their context first.
|
* can be used without saving their context first.
|
||||||
*
|
*
|
||||||
|
@ -101,6 +105,15 @@ SECTION_FUNC(TEXT, z_sparc_context_switch)
|
||||||
nop
|
nop
|
||||||
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
|
ldd [%o0 + _thread_offset_to_y], %o4
|
||||||
mov %o4, %y
|
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)
|
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,
|
FUNC_NORETURN void z_sparc_fatal_error(unsigned int reason,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue