linux/arch/mn10300/kernel/switch_to.S
<<
>>
Prefs
   1###############################################################################
   2#
   3# MN10300 Context switch operation
   4#
   5# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   6# Written by David Howells (dhowells@redhat.com)
   7#
   8# This program is free software; you can redistribute it and/or
   9# modify it under the terms of the GNU General Public Licence
  10# as published by the Free Software Foundation; either version
  11# 2 of the Licence, or (at your option) any later version.
  12#
  13###############################################################################
  14#include <linux/sys.h>
  15#include <linux/linkage.h>
  16#include <asm/thread_info.h>
  17#include <asm/cpu-regs.h>
  18#ifdef CONFIG_SMP
  19#include <proc/smp-regs.h>
  20#endif /* CONFIG_SMP */
  21
  22        .text
  23
  24###############################################################################
  25#
  26# struct task_struct *__switch_to(struct thread_struct *prev,
  27#                                 struct thread_struct *next,
  28#                                 struct task_struct *prev_task)
  29#
  30###############################################################################
  31ENTRY(__switch_to)
  32        movm    [d2,d3,a2,a3,exreg1],(sp)
  33        or      EPSW_NMID,epsw
  34
  35        mov     (44,sp),d2
  36
  37        mov     d0,a0
  38        mov     d1,a1
  39
  40        # save prev context
  41        mov     __switch_back,d0
  42        mov     sp,a2
  43        mov     a2,(THREAD_SP,a0)
  44        mov     a3,(THREAD_A3,a0)
  45
  46#ifdef CONFIG_KGDB
  47        btst    0xff,(kgdb_single_step)
  48        bne     __switch_to__lift_sstep_bp
  49__switch_to__continue:
  50#endif
  51        mov     d0,(THREAD_PC,a0)
  52
  53        mov     (THREAD_A3,a1),a3
  54        mov     (THREAD_SP,a1),a2
  55
  56        # switch
  57        mov     a2,sp
  58
  59        # load next context
  60        GET_THREAD_INFO a2
  61        mov     a2,(__current_ti)
  62        mov     (TI_task,a2),a2
  63        mov     a2,(__current)
  64#ifdef CONFIG_MN10300_CURRENT_IN_E2
  65        mov     a2,e2
  66#endif
  67
  68        mov     (THREAD_PC,a1),a2
  69        mov     d2,d0                   # for ret_from_fork
  70        mov     d0,a0                   # for __switch_to
  71
  72        jmp     (a2)
  73
  74__switch_back:
  75        and     ~EPSW_NMID,epsw
  76        ret     [d2,d3,a2,a3,exreg1],32
  77
  78#ifdef CONFIG_KGDB
  79###############################################################################
  80#
  81# Lift the single-step breakpoints when the task being traced is switched out
  82# A0 = prev
  83# A1 = next
  84#
  85###############################################################################
  86__switch_to__lift_sstep_bp:
  87        add     -12,sp
  88        mov     a0,e4
  89        mov     a1,e5
  90
  91        # Clear the single-step flag to prevent us coming this way until we get
  92        # switched back in
  93        bclr    0xff,(kgdb_single_step)
  94
  95        # Remove first breakpoint
  96        mov     (kgdb_sstep_bp_addr),a2
  97        cmp     0,a2
  98        beq     1f
  99        movbu   (kgdb_sstep_bp),d0
 100        movbu   d0,(a2)
 101#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
 102        mov     a2,d0
 103        mov     a2,d1
 104        add     1,d1
 105        calls   flush_icache_range
 106#endif
 1071:
 108
 109        # Remove second breakpoint
 110        mov     (kgdb_sstep_bp_addr+4),a2
 111        cmp     0,a2
 112        beq     2f
 113        movbu   (kgdb_sstep_bp+1),d0
 114        movbu   d0,(a2)
 115#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
 116        mov     a2,d0
 117        mov     a2,d1
 118        add     1,d1
 119        calls   flush_icache_range
 120#endif
 1212:
 122
 123        # Change the resumption address and return
 124        mov     __switch_back__reinstall_sstep_bp,d0
 125        mov     e4,a0
 126        mov     e5,a1
 127        add     12,sp
 128        bra     __switch_to__continue
 129
 130###############################################################################
 131#
 132# Reinstall the single-step breakpoints when the task being traced is switched
 133# back in (A1 points to the new thread_struct).
 134#
 135###############################################################################
 136__switch_back__reinstall_sstep_bp:
 137        add     -12,sp
 138        mov     a0,e4                   # save the return value
 139        mov     0xff,d3
 140
 141        # Reinstall first breakpoint
 142        mov     (kgdb_sstep_bp_addr),a2
 143        cmp     0,a2
 144        beq     1f
 145        movbu   (a2),d0
 146        movbu   d0,(kgdb_sstep_bp)
 147        movbu   d3,(a2)
 148#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
 149        mov     a2,d0
 150        mov     a2,d1
 151        add     1,d1
 152        calls   flush_icache_range
 153#endif
 1541:
 155
 156        # Reinstall second breakpoint
 157        mov     (kgdb_sstep_bp_addr+4),a2
 158        cmp     0,a2
 159        beq     2f
 160        movbu   (a2),d0
 161        movbu   d0,(kgdb_sstep_bp+1)
 162        movbu   d3,(a2)
 163#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
 164        mov     a2,d0
 165        mov     a2,d1
 166        add     1,d1
 167        calls   flush_icache_range
 168#endif
 1692:
 170
 171        mov     d3,(kgdb_single_step)
 172
 173        # Restore the return value (the previous thread_struct pointer)
 174        mov     e4,a0
 175        mov     a0,d0
 176        add     12,sp
 177        bra     __switch_back
 178
 179#endif /* CONFIG_KGDB */
 180