linux/arch/mips/kernel/r2300_switch.S
<<
>>
Prefs
   1/*
   2 * r2300_switch.S: R2300 specific task switching code.
   3 *
   4 * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
   5 * Copyright (C) 1994, 1995, 1996 by Andreas Busse
   6 *
   7 * Multi-cpu abstraction and macros for easier reading:
   8 * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
   9 *
  10 * Further modifications to make this work:
  11 * Copyright (c) 1998-2000 Harald Koerfgen
  12 */
  13#include <asm/asm.h>
  14#include <asm/cachectl.h>
  15#include <asm/export.h>
  16#include <asm/fpregdef.h>
  17#include <asm/mipsregs.h>
  18#include <asm/asm-offsets.h>
  19#include <asm/regdef.h>
  20#include <asm/stackframe.h>
  21#include <asm/thread_info.h>
  22
  23#include <asm/asmmacro.h>
  24
  25        .set    mips1
  26        .align  5
  27
  28/*
  29 * Offset to the current process status flags, the first 32 bytes of the
  30 * stack are not used.
  31 */
  32#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
  33
  34/*
  35 * task_struct *resume(task_struct *prev, task_struct *next,
  36 *                     struct thread_info *next_ti)
  37 */
  38LEAF(resume)
  39        mfc0    t1, CP0_STATUS
  40        sw      t1, THREAD_STATUS(a0)
  41        cpu_save_nonscratch a0
  42        sw      ra, THREAD_REG31(a0)
  43
  44#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
  45        PTR_LA  t8, __stack_chk_guard
  46        LONG_L  t9, TASK_STACK_CANARY(a1)
  47        LONG_S  t9, 0(t8)
  48#endif
  49
  50        /*
  51         * The order of restoring the registers takes care of the race
  52         * updating $28, $29 and kernelsp without disabling ints.
  53         */
  54        move    $28, a2
  55        cpu_restore_nonscratch a1
  56
  57        addiu   t1, $28, _THREAD_SIZE - 32
  58        sw      t1, kernelsp
  59
  60        mfc0    t1, CP0_STATUS          /* Do we really need this? */
  61        li      a3, 0xff01
  62        and     t1, a3
  63        lw      a2, THREAD_STATUS(a1)
  64        nor     a3, $0, a3
  65        and     a2, a3
  66        or      a2, t1
  67        mtc0    a2, CP0_STATUS
  68        move    v0, a0
  69        jr      ra
  70        END(resume)
  71
  72/*
  73 * Save a thread's fp context.
  74 */
  75LEAF(_save_fp)
  76EXPORT_SYMBOL(_save_fp)
  77        fpu_save_single a0, t1                  # clobbers t1
  78        jr      ra
  79        END(_save_fp)
  80
  81/*
  82 * Restore a thread's fp context.
  83 */
  84LEAF(_restore_fp)
  85        fpu_restore_single a0, t1               # clobbers t1
  86        jr      ra
  87        END(_restore_fp)
  88
  89/*
  90 * Load the FPU with signalling NANS.  This bit pattern we're using has
  91 * the property that no matter whether considered as single or as double
  92 * precision represents signaling NANS.
  93 *
  94 * The value to initialize fcr31 to comes in $a0.
  95 */
  96
  97        .set push
  98        SET_HARDFLOAT
  99
 100LEAF(_init_fpu)
 101        mfc0    t0, CP0_STATUS
 102        li      t1, ST0_CU1
 103        or      t0, t1
 104        mtc0    t0, CP0_STATUS
 105
 106        ctc1    a0, fcr31
 107
 108        li      t0, -1
 109
 110        mtc1    t0, $f0
 111        mtc1    t0, $f1
 112        mtc1    t0, $f2
 113        mtc1    t0, $f3
 114        mtc1    t0, $f4
 115        mtc1    t0, $f5
 116        mtc1    t0, $f6
 117        mtc1    t0, $f7
 118        mtc1    t0, $f8
 119        mtc1    t0, $f9
 120        mtc1    t0, $f10
 121        mtc1    t0, $f11
 122        mtc1    t0, $f12
 123        mtc1    t0, $f13
 124        mtc1    t0, $f14
 125        mtc1    t0, $f15
 126        mtc1    t0, $f16
 127        mtc1    t0, $f17
 128        mtc1    t0, $f18
 129        mtc1    t0, $f19
 130        mtc1    t0, $f20
 131        mtc1    t0, $f21
 132        mtc1    t0, $f22
 133        mtc1    t0, $f23
 134        mtc1    t0, $f24
 135        mtc1    t0, $f25
 136        mtc1    t0, $f26
 137        mtc1    t0, $f27
 138        mtc1    t0, $f28
 139        mtc1    t0, $f29
 140        mtc1    t0, $f30
 141        mtc1    t0, $f31
 142        jr      ra
 143        END(_init_fpu)
 144
 145        .set pop
 146