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