###############################################################################1#2# switch_to.S: context switch operation3#4# Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.5# Written by David Howells ([email protected])6#7# This program is free software; you can redistribute it and/or8# modify it under the terms of the GNU General Public License9# as published by the Free Software Foundation; either version10# 2 of the License, or (at your option) any later version.11#12###############################################################################1314#include <linux/linkage.h>15#include <asm/thread_info.h>16#include <asm/processor.h>17#include <asm/registers.h>18#include <asm/spr-regs.h>1920.macro LEDS val21setlos #~\val,gr2722st gr27,@(gr30,gr0)23membar24dcf @(gr30,gr0)25.endm2627.section .sdata28.balign 82930# address of frame 0 (userspace) on current kernel stack31.globl __kernel_frame0_ptr32__kernel_frame0_ptr:33.long init_thread_union + THREAD_SIZE - FRV_FRAME0_SIZE3435# address of current task36.globl __kernel_current_task37__kernel_current_task:38.long init_task3940.section .text41.balign 44243###############################################################################44#45# struct task_struct *__switch_to(struct thread_struct *prev_thread,46# struct thread_struct *next_thread,47# struct task_struct *prev)48#49###############################################################################50.globl __switch_to51__switch_to:52# save outgoing process's context53sethi.p %hi(__switch_back),gr1354setlo %lo(__switch_back),gr1355movsg lr,gr125657stdi gr28,@(gr8,#__THREAD_FRAME)58sti sp ,@(gr8,#__THREAD_SP)59sti fp ,@(gr8,#__THREAD_FP)60stdi gr12,@(gr8,#__THREAD_LR)61stdi gr16,@(gr8,#__THREAD_GR(16))62stdi gr18,@(gr8,#__THREAD_GR(18))63stdi gr20,@(gr8,#__THREAD_GR(20))64stdi gr22,@(gr8,#__THREAD_GR(22))65stdi gr24,@(gr8,#__THREAD_GR(24))66stdi.p gr26,@(gr8,#__THREAD_GR(26))6768or gr8,gr8,gr2269ldi.p @(gr8,#__THREAD_USER),gr870call save_user_regs71or gr22,gr22,gr87273# retrieve the new context74sethi.p %hi(__kernel_frame0_ptr),gr675setlo %lo(__kernel_frame0_ptr),gr676movsg psr,gr47778lddi.p @(gr9,#__THREAD_FRAME),gr1079or gr10,gr10,gr27 ; save prev for the return value8081ldi @(gr11,#4),gr19 ; get new_current->thread_info8283lddi @(gr9,#__THREAD_SP),gr1284ldi @(gr9,#__THREAD_LR),gr1485ldi @(gr9,#__THREAD_PC),gr1886ldi.p @(gr9,#__THREAD_FRAME0),gr78788# actually switch kernel contexts with ordinary exceptions disabled89andi gr4,#~PSR_ET,gr590movgs gr5,psr9192or.p gr10,gr0,gr28 ; set __frame93or gr11,gr0,gr29 ; set __current94or.p gr12,gr0,sp95or gr13,gr0,fp96or gr19,gr0,gr15 ; set __current_thread_info9798sti gr7,@(gr6,#0) ; set __kernel_frame0_ptr99sti gr29,@(gr6,#4) ; set __kernel_current_task100101movgs gr14,lr102bar103104# jump to __switch_back or ret_from_fork as appropriate105# - move prev to GR8106movgs gr4,psr107jmpl.p @(gr18,gr0)108or gr27,gr27,gr8109110###############################################################################111#112# restore incoming process's context113# - on entry:114# - SP, FP, LR, GR15, GR28 and GR29 will have been set up appropriately115# - GR8 will point to the outgoing task_struct116# - GR9 will point to the incoming thread_struct117#118###############################################################################119__switch_back:120lddi @(gr9,#__THREAD_GR(16)),gr16121lddi @(gr9,#__THREAD_GR(18)),gr18122lddi @(gr9,#__THREAD_GR(20)),gr20123lddi @(gr9,#__THREAD_GR(22)),gr22124lddi @(gr9,#__THREAD_GR(24)),gr24125lddi @(gr9,#__THREAD_GR(26)),gr26126127# fall through into restore_user_regs()128ldi.p @(gr9,#__THREAD_USER),gr8129or gr8,gr8,gr9130131###############################################################################132#133# restore extra general regs and FP/Media regs134# - void *restore_user_regs(const struct user_context *target, void *retval)135# - on entry:136# - GR8 will point to the user context to swap in137# - GR9 will contain the value to be returned in GR8 (prev task on context switch)138#139###############################################################################140.globl restore_user_regs141restore_user_regs:142movsg hsr0,gr6143ori gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6144movgs gr6,hsr0145movsg hsr0,gr6146147movsg psr,gr7148ori gr7,#PSR_EF|PSR_EM,gr7149movgs gr7,psr150movsg psr,gr7151srli gr7,#24,gr7152bar153154lddi @(gr8,#__FPMEDIA_MSR(0)),gr4155156movgs gr4,msr0157movgs gr5,msr1158159lddfi @(gr8,#__FPMEDIA_ACC(0)),fr16160lddfi @(gr8,#__FPMEDIA_ACC(2)),fr18161ldbfi @(gr8,#__FPMEDIA_ACCG(0)),fr20162ldbfi @(gr8,#__FPMEDIA_ACCG(1)),fr21163ldbfi @(gr8,#__FPMEDIA_ACCG(2)),fr22164ldbfi @(gr8,#__FPMEDIA_ACCG(3)),fr23165166mwtacc fr16,acc0167mwtacc fr17,acc1168mwtacc fr18,acc2169mwtacc fr19,acc3170mwtaccg fr20,accg0171mwtaccg fr21,accg1172mwtaccg fr22,accg2173mwtaccg fr23,accg3174175# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs176subicc.p gr7,#0x50,gr0,icc0177subicc gr7,#0x31,gr0,icc1178beq icc0,#0,__restore_acc_fr451179beq icc1,#0,__restore_acc_fr555180__restore_acc_cont:181182# some CPU's have GR32-GR63183setlos #HSR0_FRHE,gr4184andcc gr6,gr4,gr0,icc0185beq icc0,#1,__restore_skip_gr32_gr63186187lddi @(gr8,#__INT_GR(32)),gr32188lddi @(gr8,#__INT_GR(34)),gr34189lddi @(gr8,#__INT_GR(36)),gr36190lddi @(gr8,#__INT_GR(38)),gr38191lddi @(gr8,#__INT_GR(40)),gr40192lddi @(gr8,#__INT_GR(42)),gr42193lddi @(gr8,#__INT_GR(44)),gr44194lddi @(gr8,#__INT_GR(46)),gr46195lddi @(gr8,#__INT_GR(48)),gr48196lddi @(gr8,#__INT_GR(50)),gr50197lddi @(gr8,#__INT_GR(52)),gr52198lddi @(gr8,#__INT_GR(54)),gr54199lddi @(gr8,#__INT_GR(56)),gr56200lddi @(gr8,#__INT_GR(58)),gr58201lddi @(gr8,#__INT_GR(60)),gr60202lddi @(gr8,#__INT_GR(62)),gr62203__restore_skip_gr32_gr63:204205# all CPU's have FR0-FR31206lddfi @(gr8,#__FPMEDIA_FR( 0)),fr0207lddfi @(gr8,#__FPMEDIA_FR( 2)),fr2208lddfi @(gr8,#__FPMEDIA_FR( 4)),fr4209lddfi @(gr8,#__FPMEDIA_FR( 6)),fr6210lddfi @(gr8,#__FPMEDIA_FR( 8)),fr8211lddfi @(gr8,#__FPMEDIA_FR(10)),fr10212lddfi @(gr8,#__FPMEDIA_FR(12)),fr12213lddfi @(gr8,#__FPMEDIA_FR(14)),fr14214lddfi @(gr8,#__FPMEDIA_FR(16)),fr16215lddfi @(gr8,#__FPMEDIA_FR(18)),fr18216lddfi @(gr8,#__FPMEDIA_FR(20)),fr20217lddfi @(gr8,#__FPMEDIA_FR(22)),fr22218lddfi @(gr8,#__FPMEDIA_FR(24)),fr24219lddfi @(gr8,#__FPMEDIA_FR(26)),fr26220lddfi @(gr8,#__FPMEDIA_FR(28)),fr28221lddfi.p @(gr8,#__FPMEDIA_FR(30)),fr30222223# some CPU's have FR32-FR63224setlos #HSR0_FRHE,gr4225andcc gr6,gr4,gr0,icc0226beq icc0,#1,__restore_skip_fr32_fr63227228lddfi @(gr8,#__FPMEDIA_FR(32)),fr32229lddfi @(gr8,#__FPMEDIA_FR(34)),fr34230lddfi @(gr8,#__FPMEDIA_FR(36)),fr36231lddfi @(gr8,#__FPMEDIA_FR(38)),fr38232lddfi @(gr8,#__FPMEDIA_FR(40)),fr40233lddfi @(gr8,#__FPMEDIA_FR(42)),fr42234lddfi @(gr8,#__FPMEDIA_FR(44)),fr44235lddfi @(gr8,#__FPMEDIA_FR(46)),fr46236lddfi @(gr8,#__FPMEDIA_FR(48)),fr48237lddfi @(gr8,#__FPMEDIA_FR(50)),fr50238lddfi @(gr8,#__FPMEDIA_FR(52)),fr52239lddfi @(gr8,#__FPMEDIA_FR(54)),fr54240lddfi @(gr8,#__FPMEDIA_FR(56)),fr56241lddfi @(gr8,#__FPMEDIA_FR(58)),fr58242lddfi @(gr8,#__FPMEDIA_FR(60)),fr60243lddfi @(gr8,#__FPMEDIA_FR(62)),fr62244__restore_skip_fr32_fr63:245246lddi @(gr8,#__FPMEDIA_FNER(0)),gr4247movsg fner0,gr4248movsg fner1,gr5249or.p gr9,gr9,gr8250bralr251252# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)253__restore_acc_fr451:254lddfi @(gr8,#__FPMEDIA_ACC(4)),fr16255lddfi @(gr8,#__FPMEDIA_ACC(6)),fr18256ldbfi @(gr8,#__FPMEDIA_ACCG(4)),fr20257ldbfi @(gr8,#__FPMEDIA_ACCG(5)),fr21258ldbfi @(gr8,#__FPMEDIA_ACCG(6)),fr22259ldbfi @(gr8,#__FPMEDIA_ACCG(7)),fr23260261mwtacc fr16,acc8262mwtacc fr17,acc9263mwtacc fr18,acc10264mwtacc fr19,acc11265mwtaccg fr20,accg8266mwtaccg fr21,accg9267mwtaccg fr22,accg10268mwtaccg fr23,accg11269bra __restore_acc_cont270271# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg272__restore_acc_fr555:273lddfi @(gr8,#__FPMEDIA_ACC(4)),fr16274lddfi @(gr8,#__FPMEDIA_ACC(6)),fr18275ldbfi @(gr8,#__FPMEDIA_ACCG(4)),fr20276ldbfi @(gr8,#__FPMEDIA_ACCG(5)),fr21277ldbfi @(gr8,#__FPMEDIA_ACCG(6)),fr22278ldbfi @(gr8,#__FPMEDIA_ACCG(7)),fr23279280mnop.p281mwtacc fr16,acc4282mnop.p283mwtacc fr17,acc5284mnop.p285mwtacc fr18,acc6286mnop.p287mwtacc fr19,acc7288mnop.p289mwtaccg fr20,accg4290mnop.p291mwtaccg fr21,accg5292mnop.p293mwtaccg fr22,accg6294mnop.p295mwtaccg fr23,accg7296297ldi @(gr8,#__FPMEDIA_FSR(0)),gr4298movgs gr4,fsr0299300bra __restore_acc_cont301302303###############################################################################304#305# save extra general regs and FP/Media regs306# - void save_user_regs(struct user_context *target)307#308###############################################################################309.globl save_user_regs310save_user_regs:311movsg hsr0,gr6312ori gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6313movgs gr6,hsr0314movsg hsr0,gr6315316movsg psr,gr7317ori gr7,#PSR_EF|PSR_EM,gr7318movgs gr7,psr319movsg psr,gr7320srli gr7,#24,gr7321bar322323movsg fner0,gr4324movsg fner1,gr5325stdi.p gr4,@(gr8,#__FPMEDIA_FNER(0))326327# some CPU's have GR32-GR63328setlos #HSR0_GRHE,gr4329andcc gr6,gr4,gr0,icc0330beq icc0,#1,__save_skip_gr32_gr63331332stdi gr32,@(gr8,#__INT_GR(32))333stdi gr34,@(gr8,#__INT_GR(34))334stdi gr36,@(gr8,#__INT_GR(36))335stdi gr38,@(gr8,#__INT_GR(38))336stdi gr40,@(gr8,#__INT_GR(40))337stdi gr42,@(gr8,#__INT_GR(42))338stdi gr44,@(gr8,#__INT_GR(44))339stdi gr46,@(gr8,#__INT_GR(46))340stdi gr48,@(gr8,#__INT_GR(48))341stdi gr50,@(gr8,#__INT_GR(50))342stdi gr52,@(gr8,#__INT_GR(52))343stdi gr54,@(gr8,#__INT_GR(54))344stdi gr56,@(gr8,#__INT_GR(56))345stdi gr58,@(gr8,#__INT_GR(58))346stdi gr60,@(gr8,#__INT_GR(60))347stdi gr62,@(gr8,#__INT_GR(62))348__save_skip_gr32_gr63:349350# all CPU's have FR0-FR31351stdfi fr0 ,@(gr8,#__FPMEDIA_FR( 0))352stdfi fr2 ,@(gr8,#__FPMEDIA_FR( 2))353stdfi fr4 ,@(gr8,#__FPMEDIA_FR( 4))354stdfi fr6 ,@(gr8,#__FPMEDIA_FR( 6))355stdfi fr8 ,@(gr8,#__FPMEDIA_FR( 8))356stdfi fr10,@(gr8,#__FPMEDIA_FR(10))357stdfi fr12,@(gr8,#__FPMEDIA_FR(12))358stdfi fr14,@(gr8,#__FPMEDIA_FR(14))359stdfi fr16,@(gr8,#__FPMEDIA_FR(16))360stdfi fr18,@(gr8,#__FPMEDIA_FR(18))361stdfi fr20,@(gr8,#__FPMEDIA_FR(20))362stdfi fr22,@(gr8,#__FPMEDIA_FR(22))363stdfi fr24,@(gr8,#__FPMEDIA_FR(24))364stdfi fr26,@(gr8,#__FPMEDIA_FR(26))365stdfi fr28,@(gr8,#__FPMEDIA_FR(28))366stdfi.p fr30,@(gr8,#__FPMEDIA_FR(30))367368# some CPU's have FR32-FR63369setlos #HSR0_FRHE,gr4370andcc gr6,gr4,gr0,icc0371beq icc0,#1,__save_skip_fr32_fr63372373stdfi fr32,@(gr8,#__FPMEDIA_FR(32))374stdfi fr34,@(gr8,#__FPMEDIA_FR(34))375stdfi fr36,@(gr8,#__FPMEDIA_FR(36))376stdfi fr38,@(gr8,#__FPMEDIA_FR(38))377stdfi fr40,@(gr8,#__FPMEDIA_FR(40))378stdfi fr42,@(gr8,#__FPMEDIA_FR(42))379stdfi fr44,@(gr8,#__FPMEDIA_FR(44))380stdfi fr46,@(gr8,#__FPMEDIA_FR(46))381stdfi fr48,@(gr8,#__FPMEDIA_FR(48))382stdfi fr50,@(gr8,#__FPMEDIA_FR(50))383stdfi fr52,@(gr8,#__FPMEDIA_FR(52))384stdfi fr54,@(gr8,#__FPMEDIA_FR(54))385stdfi fr56,@(gr8,#__FPMEDIA_FR(56))386stdfi fr58,@(gr8,#__FPMEDIA_FR(58))387stdfi fr60,@(gr8,#__FPMEDIA_FR(60))388stdfi fr62,@(gr8,#__FPMEDIA_FR(62))389__save_skip_fr32_fr63:390391mrdacc acc0 ,fr4392mrdacc acc1 ,fr5393394stdfi.p fr4 ,@(gr8,#__FPMEDIA_ACC(0))395396mrdacc acc2 ,fr6397mrdacc acc3 ,fr7398399stdfi.p fr6 ,@(gr8,#__FPMEDIA_ACC(2))400401mrdaccg accg0,fr4402stbfi.p fr4 ,@(gr8,#__FPMEDIA_ACCG(0))403404mrdaccg accg1,fr5405stbfi.p fr5 ,@(gr8,#__FPMEDIA_ACCG(1))406407mrdaccg accg2,fr6408stbfi.p fr6 ,@(gr8,#__FPMEDIA_ACCG(2))409410mrdaccg accg3,fr7411stbfi fr7 ,@(gr8,#__FPMEDIA_ACCG(3))412413movsg msr0 ,gr4414movsg msr1 ,gr5415416stdi gr4 ,@(gr8,#__FPMEDIA_MSR(0))417418# some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs419subicc.p gr7,#0x50,gr0,icc0420subicc gr7,#0x31,gr0,icc1421beq icc0,#0,__save_acc_fr451422beq icc1,#0,__save_acc_fr555423__save_acc_cont:424425lddfi @(gr8,#__FPMEDIA_FR(4)),fr4426lddfi.p @(gr8,#__FPMEDIA_FR(6)),fr6427bralr428429# the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)430__save_acc_fr451:431mrdacc acc8 ,fr4432mrdacc acc9 ,fr5433434stdfi.p fr4 ,@(gr8,#__FPMEDIA_ACC(4))435436mrdacc acc10,fr6437mrdacc acc11,fr7438439stdfi.p fr6 ,@(gr8,#__FPMEDIA_ACC(6))440441mrdaccg accg8,fr4442stbfi.p fr4 ,@(gr8,#__FPMEDIA_ACCG(4))443444mrdaccg accg9,fr5445stbfi.p fr5 ,@(gr8,#__FPMEDIA_ACCG(5))446447mrdaccg accg10,fr6448stbfi.p fr6 ,@(gr8,#__FPMEDIA_ACCG(6))449450mrdaccg accg11,fr7451stbfi fr7 ,@(gr8,#__FPMEDIA_ACCG(7))452bra __save_acc_cont453454# the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg455__save_acc_fr555:456mnop.p457mrdacc acc4 ,fr4458mnop.p459mrdacc acc5 ,fr5460461stdfi fr4 ,@(gr8,#__FPMEDIA_ACC(4))462463mnop.p464mrdacc acc6 ,fr6465mnop.p466mrdacc acc7 ,fr7467468stdfi fr6 ,@(gr8,#__FPMEDIA_ACC(6))469470mnop.p471mrdaccg accg4,fr4472stbfi fr4 ,@(gr8,#__FPMEDIA_ACCG(4))473474mnop.p475mrdaccg accg5,fr5476stbfi fr5 ,@(gr8,#__FPMEDIA_ACCG(5))477478mnop.p479mrdaccg accg6,fr6480stbfi fr6 ,@(gr8,#__FPMEDIA_ACCG(6))481482mnop.p483mrdaccg accg7,fr7484stbfi fr7 ,@(gr8,#__FPMEDIA_ACCG(7))485486movsg fsr0 ,gr4487sti gr4 ,@(gr8,#__FPMEDIA_FSR(0))488bra __save_acc_cont489490491