linux/arch/sh/include/asm/switch_to_32.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef __ASM_SH_SWITCH_TO_32_H
   3#define __ASM_SH_SWITCH_TO_32_H
   4
   5#ifdef CONFIG_SH_DSP
   6
   7#define is_dsp_enabled(tsk)                                             \
   8        (!!(tsk->thread.dsp_status.status & SR_DSP))
   9
  10#define __restore_dsp(tsk)                                              \
  11do {                                                                    \
  12        register u32 *__ts2 __asm__ ("r2") =                            \
  13                        (u32 *)&tsk->thread.dsp_status;                 \
  14        __asm__ __volatile__ (                                          \
  15                ".balign 4\n\t"                                         \
  16                "movs.l @r2+, a0\n\t"                                   \
  17                "movs.l @r2+, a1\n\t"                                   \
  18                "movs.l @r2+, a0g\n\t"                                  \
  19                "movs.l @r2+, a1g\n\t"                                  \
  20                "movs.l @r2+, m0\n\t"                                   \
  21                "movs.l @r2+, m1\n\t"                                   \
  22                "movs.l @r2+, x0\n\t"                                   \
  23                "movs.l @r2+, x1\n\t"                                   \
  24                "movs.l @r2+, y0\n\t"                                   \
  25                "movs.l @r2+, y1\n\t"                                   \
  26                "lds.l  @r2+, dsr\n\t"                                  \
  27                "ldc.l  @r2+, rs\n\t"                                   \
  28                "ldc.l  @r2+, re\n\t"                                   \
  29                "ldc.l  @r2+, mod\n\t"                                  \
  30                : : "r" (__ts2));                                       \
  31} while (0)
  32
  33#define __save_dsp(tsk)                                                 \
  34do {                                                                    \
  35        register u32 *__ts2 __asm__ ("r2") =                            \
  36                        (u32 *)&tsk->thread.dsp_status + 14;            \
  37                                                                        \
  38        __asm__ __volatile__ (                                          \
  39                ".balign 4\n\t"                                         \
  40                "stc.l  mod, @-r2\n\t"                                  \
  41                "stc.l  re, @-r2\n\t"                                   \
  42                "stc.l  rs, @-r2\n\t"                                   \
  43                "sts.l  dsr, @-r2\n\t"                                  \
  44                "movs.l y1, @-r2\n\t"                                   \
  45                "movs.l y0, @-r2\n\t"                                   \
  46                "movs.l x1, @-r2\n\t"                                   \
  47                "movs.l x0, @-r2\n\t"                                   \
  48                "movs.l m1, @-r2\n\t"                                   \
  49                "movs.l m0, @-r2\n\t"                                   \
  50                "movs.l a1g, @-r2\n\t"                                  \
  51                "movs.l a0g, @-r2\n\t"                                  \
  52                "movs.l a1, @-r2\n\t"                                   \
  53                "movs.l a0, @-r2\n\t"                                   \
  54                : : "r" (__ts2));                                       \
  55} while (0)
  56
  57#else
  58
  59#define is_dsp_enabled(tsk)     (0)
  60#define __save_dsp(tsk)         do { } while (0)
  61#define __restore_dsp(tsk)      do { } while (0)
  62#endif
  63
  64struct task_struct *__switch_to(struct task_struct *prev,
  65                                struct task_struct *next);
  66
  67/*
  68 *      switch_to() should switch tasks to task nr n, first
  69 */
  70#define switch_to(prev, next, last)                             \
  71do {                                                            \
  72        register u32 *__ts1 __asm__ ("r1");                     \
  73        register u32 *__ts2 __asm__ ("r2");                     \
  74        register u32 *__ts4 __asm__ ("r4");                     \
  75        register u32 *__ts5 __asm__ ("r5");                     \
  76        register u32 *__ts6 __asm__ ("r6");                     \
  77        register u32 __ts7 __asm__ ("r7");                      \
  78        struct task_struct *__last;                             \
  79                                                                \
  80        if (is_dsp_enabled(prev))                               \
  81                __save_dsp(prev);                               \
  82        if (is_dsp_enabled(next))                               \
  83                __restore_dsp(next);                            \
  84                                                                \
  85        __ts1 = (u32 *)&prev->thread.sp;                        \
  86        __ts2 = (u32 *)&prev->thread.pc;                        \
  87        __ts4 = (u32 *)prev;                                    \
  88        __ts5 = (u32 *)next;                                    \
  89        __ts6 = (u32 *)&next->thread.sp;                        \
  90        __ts7 = next->thread.pc;                                \
  91                                                                \
  92        __asm__ __volatile__ (                                  \
  93                ".balign 4\n\t"                                 \
  94                "stc.l  gbr, @-r15\n\t"                         \
  95                "sts.l  pr, @-r15\n\t"                          \
  96                "mov.l  r8, @-r15\n\t"                          \
  97                "mov.l  r9, @-r15\n\t"                          \
  98                "mov.l  r10, @-r15\n\t"                         \
  99                "mov.l  r11, @-r15\n\t"                         \
 100                "mov.l  r12, @-r15\n\t"                         \
 101                "mov.l  r13, @-r15\n\t"                         \
 102                "mov.l  r14, @-r15\n\t"                         \
 103                "mov.l  r15, @r1\t! save SP\n\t"                \
 104                "mov.l  @r6, r15\t! change to new stack\n\t"    \
 105                "mova   1f, %0\n\t"                             \
 106                "mov.l  %0, @r2\t! save PC\n\t"                 \
 107                "mov.l  2f, %0\n\t"                             \
 108                "jmp    @%0\t! call __switch_to\n\t"            \
 109                " lds   r7, pr\t!  with return to new PC\n\t"   \
 110                ".balign        4\n"                            \
 111                "2:\n\t"                                        \
 112                ".long  __switch_to\n"                          \
 113                "1:\n\t"                                        \
 114                "mov.l  @r15+, r14\n\t"                         \
 115                "mov.l  @r15+, r13\n\t"                         \
 116                "mov.l  @r15+, r12\n\t"                         \
 117                "mov.l  @r15+, r11\n\t"                         \
 118                "mov.l  @r15+, r10\n\t"                         \
 119                "mov.l  @r15+, r9\n\t"                          \
 120                "mov.l  @r15+, r8\n\t"                          \
 121                "lds.l  @r15+, pr\n\t"                          \
 122                "ldc.l  @r15+, gbr\n\t"                         \
 123                : "=z" (__last)                                 \
 124                : "r" (__ts1), "r" (__ts2), "r" (__ts4),        \
 125                  "r" (__ts5), "r" (__ts6), "r" (__ts7)         \
 126                : "r3", "t");                                   \
 127                                                                \
 128        last = __last;                                          \
 129} while (0)
 130
 131#endif /* __ASM_SH_SWITCH_TO_32_H */
 132