PageRenderTime 32ms CodeModel.GetById 25ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/mn10300/kernel/switch_to.S

http://github.com/mirrors/linux
Assembly | 179 lines | 156 code | 23 blank | 0 comment | 7 complexity | 57bef4f40082f04916db33bf871aa517 MD5 | raw file
  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 */