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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [exec/] [score/] [cpu/] [a29k/] [cpu_asm.S] - Rev 590

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

;/*  cpu_asm.c  ===> cpu_asm.S or cpu_asm.s
; *
; *  Author:  Craig Lebakken <craigl@transition.com>
; *
; *  COPYRIGHT (c) 1996 by Transition Networks Inc.
; *
; *  To anyone who acknowledges that this file is provided "AS IS"
; *  without any express or implied warranty:
; *   permission to use, copy, modify, and distribute this file
; *   for any purpose is hereby granted without fee, provided that
; *   the above copyright notice and this notice appears in all
; *   copies, and that the name of Transition Networks not be used in
; *   advertising or publicity pertaining to distribution of the
; *   software without specific, written prior permission.
; *   Transition Networks makes no representations about the suitability
; *   of this software for any purpose.
; *
; *
; *  This file contains the basic algorithms for all assembly code used
; *  in an specific CPU port of RTEMS.  These algorithms must be implemented
; *  in assembly language
; *
; *  NOTE:  This is supposed to be a .S or .s file NOT a C file.
; *
; *  COPYRIGHT (c) 1989-1999.
; *  On-Line Applications Research Corporation (OAR).
; *
; *  The license and distribution terms for this file may be
; *  found in the file LICENSE in this distribution or at
; *  http://www.OARcorp.com/rtems/license.html.
; *
; *  $Id: cpu_asm.S,v 1.2 2001-09-27 11:59:21 chris Exp $
; */

;/*
; *  This is supposed to be an assembly file.  This means that system.h
; *  and cpu.h should not be included in a "real" cpu_asm file.  An
; *  implementation in assembly should include "cpu_asm.h>
; */

;#include <cpu_asm.h>
        .include "register.ah"
        .include "amd.ah"
        .include "pswmacro.ah"
;       .extern _bsp_exit 
;
; push a register onto the struct
        .macro  spush, sp, reg
        store   0, 0, reg, sp           ; push register
        add     sp, sp, 4               ; adjust stack pointer
        .endm
; push a register onto the struct
        .macro  spushsr, sp, reg, sr
        mfsr    reg, sr
        store   0, 0, reg, sp           ; push register
        add     sp, sp, 4               ; adjust stack pointer
        .endm
; pop a register from the struct
        .macro  spop, reg, sp
        load    0, 0, reg, sp
        add     sp,sp,4
        .endm
; pop a special register from the struct
        .macro  spopsr, sreg, reg, sp
        load    0, 0, reg, sp
        mtsr    sreg, reg
        add     sp,sp,4
        .endm
;
;/*
; *  _CPU_Context_save_fp_context
; *
; *  This routine is responsible for saving the FP context
; *  at *fp_context_ptr.  If the point to load the FP context
; *  from is changed then the pointer is modified by this routine.
; *
; *  Sometimes a macro implementation of this is in cpu.h which dereferences
; *  the ** and a similarly named routine in this file is passed something
; *  like a (Context_Control_fp *).  The general rule on making this decision
; *  is to avoid writing assembly language.
; */

;#if 0
;void _CPU_Context_save_fp(
;  void **fp_context_ptr
;)
;{
;}
;#endif
        .global _CPU_Context_save_fp
_CPU_Context_save_fp:
        jmpi    lr0
        nop

;/*
; *  _CPU_Context_restore_fp_context
; *
; *  This routine is responsible for restoring the FP context
; *  at *fp_context_ptr.  If the point to load the FP context
; *  from is changed then the pointer is modified by this routine.
; *
; *  Sometimes a macro implementation of this is in cpu.h which dereferences
; *  the ** and a similarly named routine in this file is passed something
; *  like a (Context_Control_fp *).  The general rule on making this decision
; *  is to avoid writing assembly language.
; */

;#if 0
;void _CPU_Context_restore_fp(
;  void **fp_context_ptr
;)
;{
;}
;#endif
        .global __CPU_Context_restore_fp
__CPU_Context_restore_fp:
        jmpi    lr0
        nop

;/*  _CPU_Context_switch
; *
; *  This routine performs a normal non-FP context switch.
; */
;#if 0
;void _CPU_Context_switch(
;  Context_Control  *run,
;  Context_Control  *heir
;)
;{
;}
;#endif
        .global __CPU_Context_switch
__CPU_Context_switch:
        asneq   106, gr1, gr1                           ; syscall
        jmpi    lr0                                     ;
        nop                                             ;



        .global _a29k_context_switch_sup
_a29k_context_switch_sup:
        add     pcb,lr2,0
        add     kt1,lr3,0       ;move heir pointer to safe location
        constn  it0,SIG_SYNC
        spush   pcb,it0
        spush   pcb,gr1
        spush   pcb,rab         ;push rab
        spushsr pcb,it0,pc0     ;push specials
        spushsr pcb,it0,pc1
        add     pcb,pcb,1*4     ;space pc2
        spushsr pcb,it0,CHA     ;push CHA
        spushsr pcb,it0,CHD     ;push CHD
        spushsr pcb,it0,CHC     ;push CHC
        add     pcb,pcb,1*4     ;space for alu
        spushsr pcb,it0,ops     ;push OPS
        mfsr    kt0,cps         ;current status
        const   it1,FZ          ;FZ constant
        andn    it1,kt0,it1     ;clear FZ bit
        mtsr    cps,it1         ;cps without FZ
        add     pcb,pcb,1*4     ;space for tav
        mtsrim  chc,0           ;possible DERR
;
        spush   pcb,lr1         ;push R-stack
        spush   pcb,rfb         ; support
        spush   pcb,msp         ;push M-stack pnt.
;
        add     pcb,pcb,3*4     ;space for floating point
;       spush   pcb,FPStat0     ;floating point
;       spush   pcb,FPStat1
;       spush   pcb,FPStat2
;
        add     pcb,pcb,4*4     ;space for IPA..Q
;
        mtsrim  cr,29-1
        storem  0,0,gr96,pcb    ;push gr96-124, optional
        add     pcb,pcb,29*4    ;space for gr96-124
;
        sub     it0,rfb,gr1     ;get bytes in cache
        srl     it0,it0,2       ;adjust to words
        sub     it0,it0,1
        spush   pcb,it0
        mtsr    cr,it0
        storem  0,0,lr0,pcb     ;save lr0-rfb
;
context_restore:
        add     pcb,kt1,0       ;pcb=heir
        add     pcb,pcb,4       ;space for signal num
        spop    gr1,pcb         ;restore freeze registers
        add     gr1,gr1,0       ;alu op
        add     pcb,pcb,9*4     ;move past freeze registers
        add     pcb,pcb,1*4     ;space for tav
        spop    lr1,pcb
        spop    rfb,pcb
        spop    msp,pcb
;       spop    FPStat0,pcb
;       spop    FPStat1,pcb
;       spop    FPStat2,pcb
        add     pcb,pcb,3*4     ;space for floating point
        add     pcb,pcb,4*4     ;space for IPA..Q
        mtsrim  cr,29-1
        loadm   0,0,gr96,pcb    ;pop gr96-gr124
        add     pcb,pcb,29*4    ;space for gr96-124

        spop    it1,pcb         ;pop locals count
        mtsr    cr,it1
        loadm   0,0,lr0,pcb     ;load locals
        
        add     pcb,kt1,0       ;pcb=heir
        mtsr    cps,kt0         ;cps with FZ
        nop
        add     pcb,pcb,4       ;space for signal num
        spop    gr1,pcb         ;restore freeze registers
        add     gr1,gr1,0       ;alu op
        spop    rab,pcb
        spopsr  pc0,it1,pcb
        spopsr  pc1,it1,pcb
        add     pcb,pcb,4       ;space for pc2
        spopsr  CHA,it1,pcb
        spopsr  CHD,it1,pcb
        spopsr  CHC,it1,pcb
        add     pcb,pcb,4       ;space for alu
        spopsr  ops,it1,pcb
        nop
        iret


;/*
; *  _CPU_Context_restore
; *
; *  This routine is generally used only to restart self in an
; *  efficient manner.  It may simply be a label in _CPU_Context_switch.
; *
; *  NOTE: May be unnecessary to reload some registers.
; */
;#if 0
;void _CPU_Context_restore(
;  Context_Control *new_context
;)
;{
;}
;#endif

        .global __CPU_Context_restore
__CPU_Context_restore:
        asneq   107, gr1, gr1                   ; syscall
        jmpi    lr0                                     ;
        nop                                             ;

        .global _a29k_context_restore_sup
_a29k_context_restore_sup:
        add     kt1,lr2,0       ;kt1 = restore context
        mfsr    kt0,cps         ;current status
        const   it1,FZ          ;FZ constant
        andn    it1,kt0,it1     ;clear FZ bit
        mtsr    cps,it1         ;cps without FZ
        jmp     context_restore
        nop

        .global _a29k_context_save_sup
_a29k_context_save_sup:
        add     pcb,lr2,0
        constn  it0,SIG_SYNC
        spush   pcb,it0
        spush   pcb,gr1
        spush   pcb,rab         ;push rab
        spushsr pcb,it0,pc0     ;push specials
        spushsr pcb,it0,pc1
        add     pcb,pcb,1*4     ;space pc2
        spushsr pcb,it0,CHA     ;push CHA
        spushsr pcb,it0,CHD     ;push CHD
        spushsr pcb,it0,CHC     ;push CHC
        add     pcb,pcb,1*4     ;space for alu
        spushsr pcb,it0,ops     ;push OPS
        mfsr    it0,cps         ;current status
SaveFZState     it1,it2
        add     pcb,pcb,1*4     ;space for tav
        mtsrim  chc,0           ;possible DERR
;
        spush   pcb,lr1         ;push R-stack
        spush   pcb,rfb         ; support
        spush   pcb,msp         ;push M-stack pnt.
;
        spush   pcb,FPStat0     ;floating point
        spush   pcb,FPStat1     
        spush   pcb,FPStat2
;
        add     pcb,pcb,4*4     ;space for IPA..Q
;
        mtsrim  cr,29-1
        storem  0,0,gr96,pcb    ;push gr96-124, optional
        add     pcb,pcb,29*4    ;space for gr96-124
;
        sub     kt0,rfb,gr1     ;get bytes in cache
        srl     kt0,kt0,2       ;adjust to words
        sub     kt0,kt0,1       
        spush   pcb,kt0         ;push number of words
        mtsr    cr,kt0
        storem  0,0,lr0,pcb     ;save lr0-rfb
;
        mtsr    cps,it0         ;cps with FZ
RestoreFZState  it1,it2

        nop
        nop
        nop
;
        iret
;

        .global __CPU_Context_save
__CPU_Context_save:
        asneq   108, gr1, gr1                   ; syscall
        jmpi    lr0                                     ;
        nop                                             ;


;/*  void __ISR_Handler()
; *
; *  This routine provides the RTEMS interrupt management.
; *
; */

;#if 0
;void _ISR_Handler()
;{
;   /*
;    *  This discussion ignores a lot of the ugly details in a real
;    *  implementation such as saving enough registers/state to be
;    *  able to do something real.  Keep in mind that the goal is
;    *  to invoke a user's ISR handler which is written in C and
;    *  uses a certain set of registers.
;    *
;    *  Also note that the exact order is to a large extent flexible.
;    *  Hardware will dictate a sequence for a certain subset of
;    *  _ISR_Handler while requirements for setting
;    */

;  /*
;   *  At entry to "common" _ISR_Handler, the vector number must be
;   *  available.  On some CPUs the hardware puts either the vector
;   *  number or the offset into the vector table for this ISR in a
;   *  known place.  If the hardware does not give us this information,
;   *  then the assembly portion of RTEMS for this port will contain
;   *  a set of distinct interrupt entry points which somehow place
;   *  the vector number in a known place (which is safe if another
;   *  interrupt nests this one) and branches to _ISR_Handler.
;   *
;   *  save some or all context on stack
;   *  may need to save some special interrupt information for exit
;   *
;   *  #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
;   *    if ( _ISR_Nest_level == 0 )
;   *      switch to software interrupt stack
;   *  #endif
;   *
;   *  _ISR_Nest_level++;
;   *
;   *  _Thread_Dispatch_disable_level++;
;   *
;   *  (*_ISR_Vector_table[ vector ])( vector );
;   *
;   *  --_ISR_Nest_level;
;   *
;   *  if ( _ISR_Nest_level )
;   *    goto the label "exit interrupt (simple case)"
;   *
;   *  #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
;   *    restore stack
;   *  #endif
;   *  
;   *  if ( !_Context_Switch_necessary )
;   *    goto the label "exit interrupt (simple case)"
;   *  
;   *  if ( !_ISR_Signals_to_thread_executing )
;   *    goto the label "exit interrupt (simple case)"
;   *
;   *  call _Thread_Dispatch() or prepare to return to _ISR_Dispatch
;   *
;   *  prepare to get out of interrupt
;   *  return from interrupt  (maybe to _ISR_Dispatch)
;   *
;   *  LABEL "exit interrupt (simple case):
;   *  prepare to get out of interrupt
;   *  return from interrupt
;   */
;}
;#endif
;        .global __ISR_Handler
;__ISR_Handler:
;       jmpi lr0
;        nop

        .global _a29k_getops
_a29k_getops:
        asneq 113, gr96, gr96
        jmpi lr0
        nop

        .global _a29k_getops_sup
_a29k_getops_sup:
        mfsr    gr96, ops       ; caller wants ops
        iret
        nop

        .global _a29k_disable
_a29k_disable:
        asneq 110, gr96, gr96
        jmpi lr0
        nop

        .global _a29k_disable_sup
_a29k_disable_sup:
        mfsr    kt0, ops
        add     gr96, kt0, 0    ; return ops to caller
        const   kt1, (DI | TD)
        consth  kt1, (DI | TD)
        or      kt1, kt0, kt1
        mtsr    ops, kt1
        iret
        nop

        .global _a29k_disable_all
_a29k_disable_all:
        asneq 112, gr96, gr96
        jmpi lr0
        nop

        .global _a29k_disable_all_sup
_a29k_disable_all_sup:
        mfsr    kt0, ops
        const   kt1, (DI | TD)
        consth  kt1, (DI | TD)
        or      kt1, kt0, kt1
        mtsr    ops, kt1
        iret
        nop

        .global _a29k_enable_all
_a29k_enable_all:
        asneq 111, gr96, gr96
        jmpi lr0
        nop

        .global _a29k_enable_all_sup
_a29k_enable_all_sup:
        mfsr    kt0, ops
        const   kt1, (DI | TD)
        consth  kt1, (DI | TD)
        andn    kt1, kt0, kt1
        mtsr    ops, kt1
        iret
        nop

        .global _a29k_enable
_a29k_enable:
        asneq 109, gr96, gr96
        jmpi lr0
        nop

        .global _a29k_enable_sup
_a29k_enable_sup:
        mfsr    kt0, ops
        const   kt1, (DI | TD)
        consth  kt1, (DI | TD)
        and     kt3, lr2, kt1
        andn    kt0, kt0, kt1
        or      kt1, kt0, kt3
        mtsr    ops, kt1
        iret
        nop

        .global _a29k_halt
_a29k_halt:
        halt
        jmp _a29k_halt
        nop

        .global _a29k_super_mode
_a29k_super_mode:
        mfsr gr96, ops
        or gr96, gr96, 0x10
        mtsr ops, gr96
        iret
        nop

        .global _a29k_as70
_a29k_as70:
        asneq 70,gr96,gr96
        jmpi lr0
        nop

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.