OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [frv/] [kernel/] [switch_to.S] - Rev 19

Go to most recent revision | Compare with Previous | Blame | View Log

###############################################################################
#
# switch_to.S: context switch operation
#
# Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
# Written by David Howells (dhowells@redhat.com)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version
# 2 of the License, or (at your option) any later version.
#
###############################################################################

#include <linux/linkage.h>
#include <asm/thread_info.h>
#include <asm/processor.h>
#include <asm/registers.h>
#include <asm/spr-regs.h>

.macro LEDS val
        setlos          #~\val,gr27
        st              gr27,@(gr30,gr0)
        membar
        dcf             @(gr30,gr0)
.endm

        .section        .sdata
        .balign         8

        # address of frame 0 (userspace) on current kernel stack
        .globl          __kernel_frame0_ptr
__kernel_frame0_ptr:
        .long           init_thread_union + THREAD_SIZE - FRV_FRAME0_SIZE

        # address of current task
        .globl          __kernel_current_task
__kernel_current_task:
        .long           init_task

        .section        .text
        .balign         4

###############################################################################
#
# struct task_struct *__switch_to(struct thread_struct *prev_thread,
#                                 struct thread_struct *next_thread,
#                                 struct task_struct *prev)
#
###############################################################################
        .globl          __switch_to
__switch_to:
        # save outgoing process's context
        sethi.p         %hi(__switch_back),gr13
        setlo           %lo(__switch_back),gr13
        movsg           lr,gr12

        stdi            gr28,@(gr8,#__THREAD_FRAME)
        sti             sp  ,@(gr8,#__THREAD_SP)
        sti             fp  ,@(gr8,#__THREAD_FP)
        stdi            gr12,@(gr8,#__THREAD_LR)
        stdi            gr16,@(gr8,#__THREAD_GR(16))
        stdi            gr18,@(gr8,#__THREAD_GR(18))
        stdi            gr20,@(gr8,#__THREAD_GR(20))
        stdi            gr22,@(gr8,#__THREAD_GR(22))
        stdi            gr24,@(gr8,#__THREAD_GR(24))
        stdi.p          gr26,@(gr8,#__THREAD_GR(26))

        or              gr8,gr8,gr22
        ldi.p           @(gr8,#__THREAD_USER),gr8
        call            save_user_regs
        or              gr22,gr22,gr8
        
        # retrieve the new context
        sethi.p         %hi(__kernel_frame0_ptr),gr6
        setlo           %lo(__kernel_frame0_ptr),gr6
        movsg           psr,gr4

        lddi.p          @(gr9,#__THREAD_FRAME),gr10
        or              gr10,gr10,gr27          ; save prev for the return value

        ldi             @(gr11,#4),gr19         ; get new_current->thread_info

        lddi            @(gr9,#__THREAD_SP),gr12
        ldi             @(gr9,#__THREAD_LR),gr14
        ldi             @(gr9,#__THREAD_PC),gr18
        ldi.p           @(gr9,#__THREAD_FRAME0),gr7

        # actually switch kernel contexts with ordinary exceptions disabled
        andi            gr4,#~PSR_ET,gr5
        movgs           gr5,psr

        or.p            gr10,gr0,gr28           ; set __frame
        or              gr11,gr0,gr29           ; set __current
        or.p            gr12,gr0,sp
        or              gr13,gr0,fp
        or              gr19,gr0,gr15           ; set __current_thread_info

        sti             gr7,@(gr6,#0)           ; set __kernel_frame0_ptr
        sti             gr29,@(gr6,#4)          ; set __kernel_current_task

        movgs           gr14,lr
        bar

        srli            gr15,#28,gr5
        subicc          gr5,#0xc,gr0,icc0
        beq             icc0,#0,111f
        break
        nop
111:

        # jump to __switch_back or ret_from_fork as appropriate
        # - move prev to GR8
        movgs           gr4,psr
        jmpl.p          @(gr18,gr0)
        or              gr27,gr27,gr8

###############################################################################
#
# restore incoming process's context
# - on entry:
#   - SP, FP, LR, GR15, GR28 and GR29 will have been set up appropriately
#   - GR8 will point to the outgoing task_struct
#   - GR9 will point to the incoming thread_struct
#
###############################################################################
__switch_back:
        lddi            @(gr9,#__THREAD_GR(16)),gr16
        lddi            @(gr9,#__THREAD_GR(18)),gr18
        lddi            @(gr9,#__THREAD_GR(20)),gr20
        lddi            @(gr9,#__THREAD_GR(22)),gr22
        lddi            @(gr9,#__THREAD_GR(24)),gr24
        lddi            @(gr9,#__THREAD_GR(26)),gr26

        # fall through into restore_user_regs()
        ldi.p           @(gr9,#__THREAD_USER),gr8
        or              gr8,gr8,gr9

###############################################################################
#
# restore extra general regs and FP/Media regs
# - void *restore_user_regs(const struct user_context *target, void *retval)
# - on entry:
#   - GR8 will point to the user context to swap in
#   - GR9 will contain the value to be returned in GR8 (prev task on context switch)
#
###############################################################################
        .globl          restore_user_regs
restore_user_regs:
        movsg           hsr0,gr6
        ori             gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6
        movgs           gr6,hsr0
        movsg           hsr0,gr6

        movsg           psr,gr7
        ori             gr7,#PSR_EF|PSR_EM,gr7
        movgs           gr7,psr
        movsg           psr,gr7
        srli            gr7,#24,gr7
        bar

        lddi            @(gr8,#__FPMEDIA_MSR(0)),gr4

        movgs           gr4,msr0
        movgs           gr5,msr1

        lddfi           @(gr8,#__FPMEDIA_ACC(0)),fr16
        lddfi           @(gr8,#__FPMEDIA_ACC(2)),fr18
        ldbfi           @(gr8,#__FPMEDIA_ACCG(0)),fr20
        ldbfi           @(gr8,#__FPMEDIA_ACCG(1)),fr21
        ldbfi           @(gr8,#__FPMEDIA_ACCG(2)),fr22
        ldbfi           @(gr8,#__FPMEDIA_ACCG(3)),fr23

        mwtacc          fr16,acc0
        mwtacc          fr17,acc1
        mwtacc          fr18,acc2
        mwtacc          fr19,acc3
        mwtaccg         fr20,accg0
        mwtaccg         fr21,accg1
        mwtaccg         fr22,accg2
        mwtaccg         fr23,accg3

        # some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs
        subicc.p        gr7,#0x50,gr0,icc0
        subicc          gr7,#0x31,gr0,icc1
        beq             icc0,#0,__restore_acc_fr451
        beq             icc1,#0,__restore_acc_fr555
__restore_acc_cont:

        # some CPU's have GR32-GR63
        setlos          #HSR0_FRHE,gr4
        andcc           gr6,gr4,gr0,icc0
        beq             icc0,#1,__restore_skip_gr32_gr63

        lddi            @(gr8,#__INT_GR(32)),gr32
        lddi            @(gr8,#__INT_GR(34)),gr34
        lddi            @(gr8,#__INT_GR(36)),gr36
        lddi            @(gr8,#__INT_GR(38)),gr38
        lddi            @(gr8,#__INT_GR(40)),gr40
        lddi            @(gr8,#__INT_GR(42)),gr42
        lddi            @(gr8,#__INT_GR(44)),gr44
        lddi            @(gr8,#__INT_GR(46)),gr46
        lddi            @(gr8,#__INT_GR(48)),gr48
        lddi            @(gr8,#__INT_GR(50)),gr50
        lddi            @(gr8,#__INT_GR(52)),gr52
        lddi            @(gr8,#__INT_GR(54)),gr54
        lddi            @(gr8,#__INT_GR(56)),gr56
        lddi            @(gr8,#__INT_GR(58)),gr58
        lddi            @(gr8,#__INT_GR(60)),gr60
        lddi            @(gr8,#__INT_GR(62)),gr62
__restore_skip_gr32_gr63:

        # all CPU's have FR0-FR31
        lddfi           @(gr8,#__FPMEDIA_FR( 0)),fr0
        lddfi           @(gr8,#__FPMEDIA_FR( 2)),fr2
        lddfi           @(gr8,#__FPMEDIA_FR( 4)),fr4
        lddfi           @(gr8,#__FPMEDIA_FR( 6)),fr6
        lddfi           @(gr8,#__FPMEDIA_FR( 8)),fr8
        lddfi           @(gr8,#__FPMEDIA_FR(10)),fr10
        lddfi           @(gr8,#__FPMEDIA_FR(12)),fr12
        lddfi           @(gr8,#__FPMEDIA_FR(14)),fr14
        lddfi           @(gr8,#__FPMEDIA_FR(16)),fr16
        lddfi           @(gr8,#__FPMEDIA_FR(18)),fr18
        lddfi           @(gr8,#__FPMEDIA_FR(20)),fr20
        lddfi           @(gr8,#__FPMEDIA_FR(22)),fr22
        lddfi           @(gr8,#__FPMEDIA_FR(24)),fr24
        lddfi           @(gr8,#__FPMEDIA_FR(26)),fr26
        lddfi           @(gr8,#__FPMEDIA_FR(28)),fr28
        lddfi.p         @(gr8,#__FPMEDIA_FR(30)),fr30

        # some CPU's have FR32-FR63
        setlos          #HSR0_FRHE,gr4
        andcc           gr6,gr4,gr0,icc0
        beq             icc0,#1,__restore_skip_fr32_fr63

        lddfi           @(gr8,#__FPMEDIA_FR(32)),fr32
        lddfi           @(gr8,#__FPMEDIA_FR(34)),fr34
        lddfi           @(gr8,#__FPMEDIA_FR(36)),fr36
        lddfi           @(gr8,#__FPMEDIA_FR(38)),fr38
        lddfi           @(gr8,#__FPMEDIA_FR(40)),fr40
        lddfi           @(gr8,#__FPMEDIA_FR(42)),fr42
        lddfi           @(gr8,#__FPMEDIA_FR(44)),fr44
        lddfi           @(gr8,#__FPMEDIA_FR(46)),fr46
        lddfi           @(gr8,#__FPMEDIA_FR(48)),fr48
        lddfi           @(gr8,#__FPMEDIA_FR(50)),fr50
        lddfi           @(gr8,#__FPMEDIA_FR(52)),fr52
        lddfi           @(gr8,#__FPMEDIA_FR(54)),fr54
        lddfi           @(gr8,#__FPMEDIA_FR(56)),fr56
        lddfi           @(gr8,#__FPMEDIA_FR(58)),fr58
        lddfi           @(gr8,#__FPMEDIA_FR(60)),fr60
        lddfi           @(gr8,#__FPMEDIA_FR(62)),fr62
__restore_skip_fr32_fr63:

        lddi            @(gr8,#__FPMEDIA_FNER(0)),gr4
        movsg           fner0,gr4
        movsg           fner1,gr5
        or.p            gr9,gr9,gr8
        bralr

        # the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)
__restore_acc_fr451:
        lddfi           @(gr8,#__FPMEDIA_ACC(4)),fr16
        lddfi           @(gr8,#__FPMEDIA_ACC(6)),fr18
        ldbfi           @(gr8,#__FPMEDIA_ACCG(4)),fr20
        ldbfi           @(gr8,#__FPMEDIA_ACCG(5)),fr21
        ldbfi           @(gr8,#__FPMEDIA_ACCG(6)),fr22
        ldbfi           @(gr8,#__FPMEDIA_ACCG(7)),fr23

        mwtacc          fr16,acc8
        mwtacc          fr17,acc9
        mwtacc          fr18,acc10
        mwtacc          fr19,acc11
        mwtaccg         fr20,accg8
        mwtaccg         fr21,accg9
        mwtaccg         fr22,accg10
        mwtaccg         fr23,accg11
        bra             __restore_acc_cont

        # the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg
__restore_acc_fr555:
        lddfi           @(gr8,#__FPMEDIA_ACC(4)),fr16
        lddfi           @(gr8,#__FPMEDIA_ACC(6)),fr18
        ldbfi           @(gr8,#__FPMEDIA_ACCG(4)),fr20
        ldbfi           @(gr8,#__FPMEDIA_ACCG(5)),fr21
        ldbfi           @(gr8,#__FPMEDIA_ACCG(6)),fr22
        ldbfi           @(gr8,#__FPMEDIA_ACCG(7)),fr23

        mnop.p
        mwtacc          fr16,acc4
        mnop.p
        mwtacc          fr17,acc5
        mnop.p
        mwtacc          fr18,acc6
        mnop.p
        mwtacc          fr19,acc7
        mnop.p
        mwtaccg         fr20,accg4
        mnop.p
        mwtaccg         fr21,accg5
        mnop.p
        mwtaccg         fr22,accg6
        mnop.p
        mwtaccg         fr23,accg7

        ldi             @(gr8,#__FPMEDIA_FSR(0)),gr4
        movgs           gr4,fsr0

        bra             __restore_acc_cont


###############################################################################
#
# save extra general regs and FP/Media regs
# - void save_user_regs(struct user_context *target)
#
###############################################################################
        .globl          save_user_regs
save_user_regs:
        movsg           hsr0,gr6
        ori             gr6,#HSR0_GRHE|HSR0_FRLE|HSR0_FRHE,gr6
        movgs           gr6,hsr0
        movsg           hsr0,gr6

        movsg           psr,gr7
        ori             gr7,#PSR_EF|PSR_EM,gr7
        movgs           gr7,psr
        movsg           psr,gr7
        srli            gr7,#24,gr7
        bar

        movsg           fner0,gr4
        movsg           fner1,gr5
        stdi.p          gr4,@(gr8,#__FPMEDIA_FNER(0))

        # some CPU's have GR32-GR63
        setlos          #HSR0_GRHE,gr4
        andcc           gr6,gr4,gr0,icc0
        beq             icc0,#1,__save_skip_gr32_gr63

        stdi            gr32,@(gr8,#__INT_GR(32))
        stdi            gr34,@(gr8,#__INT_GR(34))
        stdi            gr36,@(gr8,#__INT_GR(36))
        stdi            gr38,@(gr8,#__INT_GR(38))
        stdi            gr40,@(gr8,#__INT_GR(40))
        stdi            gr42,@(gr8,#__INT_GR(42))
        stdi            gr44,@(gr8,#__INT_GR(44))
        stdi            gr46,@(gr8,#__INT_GR(46))
        stdi            gr48,@(gr8,#__INT_GR(48))
        stdi            gr50,@(gr8,#__INT_GR(50))
        stdi            gr52,@(gr8,#__INT_GR(52))
        stdi            gr54,@(gr8,#__INT_GR(54))
        stdi            gr56,@(gr8,#__INT_GR(56))
        stdi            gr58,@(gr8,#__INT_GR(58))
        stdi            gr60,@(gr8,#__INT_GR(60))
        stdi            gr62,@(gr8,#__INT_GR(62))
__save_skip_gr32_gr63:

        # all CPU's have FR0-FR31
        stdfi           fr0 ,@(gr8,#__FPMEDIA_FR( 0))
        stdfi           fr2 ,@(gr8,#__FPMEDIA_FR( 2))
        stdfi           fr4 ,@(gr8,#__FPMEDIA_FR( 4))
        stdfi           fr6 ,@(gr8,#__FPMEDIA_FR( 6))
        stdfi           fr8 ,@(gr8,#__FPMEDIA_FR( 8))
        stdfi           fr10,@(gr8,#__FPMEDIA_FR(10))
        stdfi           fr12,@(gr8,#__FPMEDIA_FR(12))
        stdfi           fr14,@(gr8,#__FPMEDIA_FR(14))
        stdfi           fr16,@(gr8,#__FPMEDIA_FR(16))
        stdfi           fr18,@(gr8,#__FPMEDIA_FR(18))
        stdfi           fr20,@(gr8,#__FPMEDIA_FR(20))
        stdfi           fr22,@(gr8,#__FPMEDIA_FR(22))
        stdfi           fr24,@(gr8,#__FPMEDIA_FR(24))
        stdfi           fr26,@(gr8,#__FPMEDIA_FR(26))
        stdfi           fr28,@(gr8,#__FPMEDIA_FR(28))
        stdfi.p         fr30,@(gr8,#__FPMEDIA_FR(30))

        # some CPU's have FR32-FR63
        setlos          #HSR0_FRHE,gr4
        andcc           gr6,gr4,gr0,icc0
        beq             icc0,#1,__save_skip_fr32_fr63

        stdfi           fr32,@(gr8,#__FPMEDIA_FR(32))
        stdfi           fr34,@(gr8,#__FPMEDIA_FR(34))
        stdfi           fr36,@(gr8,#__FPMEDIA_FR(36))
        stdfi           fr38,@(gr8,#__FPMEDIA_FR(38))
        stdfi           fr40,@(gr8,#__FPMEDIA_FR(40))
        stdfi           fr42,@(gr8,#__FPMEDIA_FR(42))
        stdfi           fr44,@(gr8,#__FPMEDIA_FR(44))
        stdfi           fr46,@(gr8,#__FPMEDIA_FR(46))
        stdfi           fr48,@(gr8,#__FPMEDIA_FR(48))
        stdfi           fr50,@(gr8,#__FPMEDIA_FR(50))
        stdfi           fr52,@(gr8,#__FPMEDIA_FR(52))
        stdfi           fr54,@(gr8,#__FPMEDIA_FR(54))
        stdfi           fr56,@(gr8,#__FPMEDIA_FR(56))
        stdfi           fr58,@(gr8,#__FPMEDIA_FR(58))
        stdfi           fr60,@(gr8,#__FPMEDIA_FR(60))
        stdfi           fr62,@(gr8,#__FPMEDIA_FR(62))
__save_skip_fr32_fr63:

        mrdacc          acc0 ,fr4
        mrdacc          acc1 ,fr5

        stdfi.p         fr4 ,@(gr8,#__FPMEDIA_ACC(0))

        mrdacc          acc2 ,fr6
        mrdacc          acc3 ,fr7

        stdfi.p         fr6 ,@(gr8,#__FPMEDIA_ACC(2))

        mrdaccg         accg0,fr4
        stbfi.p         fr4 ,@(gr8,#__FPMEDIA_ACCG(0))

        mrdaccg         accg1,fr5
        stbfi.p         fr5 ,@(gr8,#__FPMEDIA_ACCG(1))

        mrdaccg         accg2,fr6
        stbfi.p         fr6 ,@(gr8,#__FPMEDIA_ACCG(2))

        mrdaccg         accg3,fr7
        stbfi           fr7 ,@(gr8,#__FPMEDIA_ACCG(3))

        movsg           msr0 ,gr4
        movsg           msr1 ,gr5

        stdi            gr4 ,@(gr8,#__FPMEDIA_MSR(0))

        # some CPUs have extra ACCx and ACCGx regs and maybe FSRx regs
        subicc.p        gr7,#0x50,gr0,icc0
        subicc          gr7,#0x31,gr0,icc1
        beq             icc0,#0,__save_acc_fr451
        beq             icc1,#0,__save_acc_fr555
__save_acc_cont:

        lddfi           @(gr8,#__FPMEDIA_FR(4)),fr4
        lddfi.p         @(gr8,#__FPMEDIA_FR(6)),fr6
        bralr

        # the FR451 also has ACC8-11/ACCG8-11 regs (but not 4-7...)
__save_acc_fr451:
        mrdacc          acc8 ,fr4
        mrdacc          acc9 ,fr5

        stdfi.p         fr4 ,@(gr8,#__FPMEDIA_ACC(4))

        mrdacc          acc10,fr6
        mrdacc          acc11,fr7

        stdfi.p         fr6 ,@(gr8,#__FPMEDIA_ACC(6))

        mrdaccg         accg8,fr4
        stbfi.p         fr4 ,@(gr8,#__FPMEDIA_ACCG(4))

        mrdaccg         accg9,fr5
        stbfi.p         fr5 ,@(gr8,#__FPMEDIA_ACCG(5))

        mrdaccg         accg10,fr6
        stbfi.p         fr6 ,@(gr8,#__FPMEDIA_ACCG(6))

        mrdaccg         accg11,fr7
        stbfi           fr7 ,@(gr8,#__FPMEDIA_ACCG(7))
        bra             __save_acc_cont

        # the FR555 also has ACC4-7/ACCG4-7 regs and an FSR0 reg
__save_acc_fr555:
        mnop.p
        mrdacc          acc4 ,fr4
        mnop.p
        mrdacc          acc5 ,fr5

        stdfi           fr4 ,@(gr8,#__FPMEDIA_ACC(4))

        mnop.p
        mrdacc          acc6 ,fr6
        mnop.p
        mrdacc          acc7 ,fr7

        stdfi           fr6 ,@(gr8,#__FPMEDIA_ACC(6))

        mnop.p
        mrdaccg         accg4,fr4
        stbfi           fr4 ,@(gr8,#__FPMEDIA_ACCG(4))

        mnop.p
        mrdaccg         accg5,fr5
        stbfi           fr5 ,@(gr8,#__FPMEDIA_ACCG(5))

        mnop.p
        mrdaccg         accg6,fr6
        stbfi           fr6 ,@(gr8,#__FPMEDIA_ACCG(6))

        mnop.p
        mrdaccg         accg7,fr7
        stbfi           fr7 ,@(gr8,#__FPMEDIA_ACCG(7))

        movsg           fsr0 ,gr4
        sti             gr4 ,@(gr8,#__FPMEDIA_FSR(0))
        bra             __save_acc_cont

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.