Browse Source

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>
pull/32202/head
Martin Åberg 4 years ago committed by Anas Nashif
parent
commit
88f478108d
  1. 23
      arch/sparc/core/switch.S
  2. 13
      arch/sparc/include/kernel_arch_func.h

23
arch/sparc/core/switch.S

@ -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

13
arch/sparc/include/kernel_arch_func.h

@ -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…
Cancel
Save