root/arch/arc/kernel/ctx_sw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __switch_to

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
   4  *
   5  * Vineetg: Aug 2009
   6  *  -"C" version of lowest level context switch asm macro called by schedular
   7  *   gcc doesn't generate the dward CFI info for hand written asm, hence can't
   8  *   backtrace out of it (e.g. tasks sleeping in kernel).
   9  *   So we cheat a bit by writing almost similar code in inline-asm.
  10  *  -This is a hacky way of doing things, but there is no other simple way.
  11  *   I don't want/intend to extend unwinding code to understand raw asm
  12  */
  13 
  14 #include <asm/asm-offsets.h>
  15 #include <linux/sched.h>
  16 #include <linux/sched/debug.h>
  17 #ifdef CONFIG_ARC_PLAT_EZNPS
  18 #include <plat/ctop.h>
  19 #endif
  20 
  21 #define KSP_WORD_OFF    ((TASK_THREAD + THREAD_KSP) / 4)
  22 
  23 struct task_struct *__sched
  24 __switch_to(struct task_struct *prev_task, struct task_struct *next_task)
  25 {
  26         unsigned int tmp;
  27         unsigned int prev = (unsigned int)prev_task;
  28         unsigned int next = (unsigned int)next_task;
  29 
  30         __asm__ __volatile__(
  31                 /* FP/BLINK save generated by gcc (standard function prologue */
  32                 "st.a    r13, [sp, -4]   \n\t"
  33                 "st.a    r14, [sp, -4]   \n\t"
  34                 "st.a    r15, [sp, -4]   \n\t"
  35                 "st.a    r16, [sp, -4]   \n\t"
  36                 "st.a    r17, [sp, -4]   \n\t"
  37                 "st.a    r18, [sp, -4]   \n\t"
  38                 "st.a    r19, [sp, -4]   \n\t"
  39                 "st.a    r20, [sp, -4]   \n\t"
  40                 "st.a    r21, [sp, -4]   \n\t"
  41                 "st.a    r22, [sp, -4]   \n\t"
  42                 "st.a    r23, [sp, -4]   \n\t"
  43                 "st.a    r24, [sp, -4]   \n\t"
  44 #ifndef CONFIG_ARC_CURR_IN_REG
  45                 "st.a    r25, [sp, -4]   \n\t"
  46 #else
  47                 "sub     sp, sp, 4      \n\t"   /* usual r25 placeholder */
  48 #endif
  49 
  50                 /* set ksp of outgoing task in tsk->thread.ksp */
  51 #if KSP_WORD_OFF <= 255
  52                 "st.as   sp, [%3, %1]    \n\t"
  53 #else
  54                 /*
  55                  * Workaround for NR_CPUS=4k
  56                  * %1 is bigger than 255 (S9 offset for st.as)
  57                  */
  58                 "add2    r24, %3, %1     \n\t"
  59                 "st      sp, [r24]       \n\t"
  60 #endif
  61 
  62                 /*
  63                  * setup _current_task with incoming tsk.
  64                  * optionally, set r25 to that as well
  65                  * For SMP extra work to get to &_current_task[cpu]
  66                  * (open coded SET_CURR_TASK_ON_CPU)
  67                  */
  68 #ifndef CONFIG_SMP
  69                 "st  %2, [@_current_task]       \n\t"
  70 #else
  71 #ifdef CONFIG_ARC_PLAT_EZNPS
  72                 "lr   r24, [%4]         \n\t"
  73 #ifndef CONFIG_EZNPS_MTM_EXT
  74                 "lsr  r24, r24, 4               \n\t"
  75 #endif
  76 #else
  77                 "lr   r24, [identity]           \n\t"
  78                 "lsr  r24, r24, 8               \n\t"
  79                 "bmsk r24, r24, 7               \n\t"
  80 #endif
  81                 "add2 r24, @_current_task, r24  \n\t"
  82                 "st   %2,  [r24]                \n\t"
  83 #endif
  84 #ifdef CONFIG_ARC_CURR_IN_REG
  85                 "mov r25, %2   \n\t"
  86 #endif
  87 
  88                 /* get ksp of incoming task from tsk->thread.ksp */
  89                 "ld.as  sp, [%2, %1]   \n\t"
  90 
  91                 /* start loading it's CALLEE reg file */
  92 
  93 #ifndef CONFIG_ARC_CURR_IN_REG
  94                 "ld.ab   r25, [sp, 4]   \n\t"
  95 #else
  96                 "add    sp, sp, 4       \n\t"
  97 #endif
  98                 "ld.ab   r24, [sp, 4]   \n\t"
  99                 "ld.ab   r23, [sp, 4]   \n\t"
 100                 "ld.ab   r22, [sp, 4]   \n\t"
 101                 "ld.ab   r21, [sp, 4]   \n\t"
 102                 "ld.ab   r20, [sp, 4]   \n\t"
 103                 "ld.ab   r19, [sp, 4]   \n\t"
 104                 "ld.ab   r18, [sp, 4]   \n\t"
 105                 "ld.ab   r17, [sp, 4]   \n\t"
 106                 "ld.ab   r16, [sp, 4]   \n\t"
 107                 "ld.ab   r15, [sp, 4]   \n\t"
 108                 "ld.ab   r14, [sp, 4]   \n\t"
 109                 "ld.ab   r13, [sp, 4]   \n\t"
 110 
 111                 /* last (ret value) = prev : although for ARC it mov r0, r0 */
 112                 "mov     %0, %3        \n\t"
 113 
 114                 /* FP/BLINK restore generated by gcc (standard func epilogue */
 115 
 116                 : "=r"(tmp)
 117                 : "n"(KSP_WORD_OFF), "r"(next), "r"(prev)
 118 #ifdef CONFIG_ARC_PLAT_EZNPS
 119                 , "i"(CTOP_AUX_LOGIC_GLOBAL_ID)
 120 #endif
 121                 : "blink"
 122         );
 123 
 124         return (struct task_struct *)tmp;
 125 }

/* [<][>][^][v][top][bottom][index][help] */