⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu_asm.s

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 S
字号:
;/*  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.rtems.com/license/LICENSE.; *; *  $Id: cpu_asm.S,v 1.4.4.1 2003/09/04 18:47:21 joel 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:#if 0	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#endif;/*; *  _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:#if 0        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 statusSaveFZState	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 FZRestoreFZState	it1,it2	nop	nop	nop;	iret;#endif        .global __CPU_Context_save__CPU_Context_save:#if 0        asneq   108, gr1, gr1                   ; syscall        jmpi    lr0                                     ;        nop                                             ;#endif;/*  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:#if 0	asneq 113, gr96, gr96	jmpi lr0	nop#endif	.global	_a29k_getops_sup_a29k_getops_sup:#if 0	mfsr	gr96, ops	; caller wants ops	iret	nop#endif	.global	_a29k_disable_a29k_disable:#if 0	asneq 110, gr96, gr96	jmpi lr0	nop#endif	.global	_a29k_disable_sup_a29k_disable_sup:#if 0	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#endif        .global _a29k_disable_all_a29k_disable_all:#if 0        asneq 112, gr96, gr96        jmpi lr0        nop#endif        .global _a29k_disable_all_sup_a29k_disable_all_sup:#if 0        mfsr    kt0, ops	const	kt1, (DI | TD)	consth	kt1, (DI | TD)        or    	kt1, kt0, kt1        mtsr    ops, kt1        iret        nop#endif        .global _a29k_enable_all_a29k_enable_all:#if 0        asneq 111, gr96, gr96        jmpi lr0        nop#endif        .global _a29k_enable_all_sup_a29k_enable_all_sup:#if 0        mfsr    kt0, ops	const	kt1, (DI | TD)	consth	kt1, (DI | TD)        andn    kt1, kt0, kt1        mtsr    ops, kt1        iret        nop#endif	.global	_a29k_enable_a29k_enable:#if 0	asneq 109, gr96, gr96	jmpi lr0	nop#endif	.global	_a29k_enable_sup_a29k_enable_sup:#if 0	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#endif	.global _a29k_halt_a29k_halt:#if 0	halt	jmp _a29k_halt	nop#endif	.global _a29k_super_mode_a29k_super_mode:#if 0	mfsr gr96, ops	or gr96, gr96, 0x10	mtsr ops, gr96	iret	nop#endif	.global _a29k_as70_a29k_as70:#if 0	asneq 70,gr96,gr96	jmpi lr0	nop#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -