ivt.s

来自「xen虚拟机源代码安装包」· S 代码 · 共 873 行 · 第 1/2 页

S
873
字号
/* * Copyright (c) 2007 Dietmar Hahn <dietmar.hahn@fujitsu-siemens.com> * Description: ia64 specific trap handling. * **************************************************************************** * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: *  * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  * DEALINGS IN THE SOFTWARE. * */#include "asm.h"#include "page.h"#include "ia64_cpu.h"#include "privop.h"#include "offsets.h"/* General register usage in interrupt handling: *	r16, r17, ... are used for input parameters of sub-routines *	r29:	used to access memory which may raise nested TLB fault *	r30:	b0 save register *	r31:	predicates save register *	p30,p31:	used for TLB stuff: (0,1)=data, (1,0)=instruction */#define FILL_FP_PAIR(f1, f2, b1, b2)	\	ldf.fill	f1=[b1],32	;\	ldf.fill	f2=[b2],32	;\	;;#define SPILL_FP_PAIR(f1, f2, b1, b2)	\	stf.spill	[b1]=f1,32	;\	stf.spill	[b2]=f2,32	;\	;;#define FILL_REG_PAIR(r1, r2, b1, b2)	\	ld8.fill	r1=[b1],16	;\	ld8.fill	r2=[b2],16	;\	;;#define SPILL_REG_PAIR(r1, r2, b1, b2)	\	.mem.offset 0,0			;\	st8.spill	[b1]=r1,16	;\	.mem.offset 8,0			;\	st8.spill	[b2]=r2,16	;\	;;/** *	The function does a store of the current processor context *	to the given exception frame address. *	These are some special and the scratch registers for calling *	C-functions later. *	The bspstore will be the same. A clean RSE is made with the *	cover instruction. *	 *	The return is done through a jump to the next bundle after ip (r16). * *	Used register: r16, r18, r19, r20, r21, r22 of bank 0 * * 	@param: r16 ip of the bundle with the jump. *	@param: r18 pointer to the trap frame. *	@param: r23 trap number/err val * */ENTRY(save_tf_rse_switch)	movl	r21=XSI_IPSR		// XEN !!	movl	r22=XSI_IIP		// XEN !!	;;	ld8	r21=[r21]		// XEN.ipsr	ld8	r22=[r22];;		// XEN.iip#if defined(BIG_ENDIAN)	mux1	r21=r21,@rev		// swap because mini-os is in BE	mux1	r22=r22,@rev		// swap because mini-os is in BE	;;#endif	add	r19=TF_IPSR,r18	add	r20=TF_IIP,r18	;;	st8	[r19]=r21		// store cr.ipsr	st8	[r20]=r22		// store cr.iip	;;	//// r16 return jump pointer, r18 - trap frame base, 	add	r19=TF_UNAT,r18	mov	r20=ar.unat	;;	st8	[r19]=r20		// store scratch unat	;;	add	r19=TF_GP,r18	add	r20=TF_SP,r18	;;	st8	[r19]=gp,TF_TP-TF_GP	// store gp	st8	[r20]=sp,TF_PR-TF_SP	// store sp	mov	r21=pr	;;	st8	[r19]=r13		// store tp	st8	[r20]=r21		// store pr	;;	add	r19=TF_GREG2,r18	// Now first general regs.	add	r20=TF_GREG3,r18	;;	SPILL_REG_PAIR( r2, r3,r19,r20)	SPILL_REG_PAIR( r8, r9,r19,r20)	SPILL_REG_PAIR(r10,r11,r19,r20)	SPILL_REG_PAIR(r14,r15,r19,r20)	;;	mov	r14=r18		// move trap frame base for bsw	mov	r15=r16		// save return address	;;	//bsw.1		// switch to bank 1 for saving these registers.	movl r30=XSI_BANKNUM		// Switch to bank 1.	mov r31=1;;#if defined(BIG_ENDIAN)	mux1	r31=r31,@rev		// swap because mini-os is in BE	;;#endif	st4 [r30]=r31	;;	/*	 * On XEN the hypervisor has stored the bank 1 registers	 * r16-r31. I must reload these registers here to get	 * access.	 */	movl r30=XSI_BANK1_R16;	movl r31=XSI_BANK1_R16+8;; 	ld8 r16=[r30],16; ld8 r17=[r31],16;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r16=r16,@rev; mux1 r17=r17,@rev;;#endif	ld8 r18=[r30],16; ld8 r19=[r31],16;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r18=r18,@rev; mux1 r19=r19,@rev;;#endif	ld8 r20=[r30],16; ld8 r21=[r31],16;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r20=r20,@rev; mux1 r21=r21,@rev;;#endif	ld8 r22=[r30],16; ld8 r23=[r31],16;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r22=r22,@rev; mux1 r23=r23,@rev;;#endif	ld8 r24=[r30],16; ld8 r25=[r31],16;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r24=r24,@rev; mux1 r25=r25,@rev;;#endif	ld8 r26=[r30],16; ld8 r27=[r31],16;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r26=r26,@rev; mux1 r27=r27,@rev;;#endif	ld8 r28=[r30],16; ld8 r29=[r31],16;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r28=r28,@rev; mux1 r29=r29,@rev;;#endif	ld8 r30=[r30]; ld8 r31=[r31];;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r30=r30,@rev; mux1 r31=r31,@rev;;#endif	add	r2=TF_GREG16,r14	add	r3=TF_GREG17,r14	;;	SPILL_REG_PAIR(r16,r17,r2,r3)	SPILL_REG_PAIR(r18,r19,r2,r3)	SPILL_REG_PAIR(r20,r21,r2,r3)	SPILL_REG_PAIR(r22,r23,r2,r3)	SPILL_REG_PAIR(r24,r25,r2,r3)	SPILL_REG_PAIR(r26,r27,r2,r3)	SPILL_REG_PAIR(r28,r29,r2,r3)	SPILL_REG_PAIR(r30,r31,r2,r3)	;;	//bsw.0				// back to interrupt bank 0	movl r2=XSI_BANKNUM;;	st4 [r2]=r0	;;	mov	r18=r14			// restore context pointer	mov	r16=r15			// restore return address	;;	//// r16 return jump pointer, r18 - trap frame base, 	add	r19=TF_CCV,r18	add	r20=TF_CSD,r18	mov	r21=ar.ccv	mov	r22=ar.csd	;;	st8	[r19]=r21		// ar.ccv	st8	[r20]=r22		// ar.csd	;;	add	r19=TF_SSD,r18	mov	r21=ar.ssd	;;	st8	[r19]=r21		// ar.ssd	;;	add	r19=TF_FREG6,r18	add	r20=TF_FREG7,r18	;;	SPILL_FP_PAIR(f6, f7, r19, r20)	SPILL_FP_PAIR(f8, f9, r19, r20)	SPILL_FP_PAIR(f10, f11, r19, r20)	add	r19=TF_BREG0,r18	// b0, b6, b7	add	r20=TF_BREG6,r18	mov	r21=b0	mov	r22=b6	;;	st8	[r19]=r21,TF_BREG7-TF_BREG0	// store b0	st8	[r20]=r22,16		// store b6	;;	mov	r21=b7	;;	st8	[r19]=r21		// store b7	//// r16 return jump pointer, r18 - trap frame base, 		// Read and save RSC, PFS	add	r19=TF_PFS,r18	add	r20=TF_RSC,r18	mov	r21=ar.pfs	mov	r22=ar.rsc	;;{	.mmb	st8	[r19]=r21		// store ar.pfs	st8	[r20]=r22		// store ar.rsc		// Issue cover instruction	cover		// must be the last instruction in bundle	//XEN_HYPER_COVER	;;}		// Read and save IFS	add	r19=TF_IFS,r18	add	r20=TF_CFM,r18		/* xen special handling for possibly lazy cover */	movl	r8=XSI_PRECOVER_IFS;	;;	ld8	r21=[r8]	;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r21=r21,@rev	;;#endif	st8	[r19]=r21		// store cr.ifs	dep.z	r22=r21,0,38		// copy ifm part from ifs.ifm	;;	st8	[r20]=r22		// store cfm		// RSE in enforced lazy mode	mov	ar.rsc=IA64_RSE_LAZY	;;		// Read and save BSPSTORE and RNAT	add	r19=TF_BSP,r18	add	r20=TF_RNAT,r18	mov	r21=ar.bspstore	mov	r22=ar.rnat	;;	st8	[r19]=r21	                // store ar.bspstore	st8	[r20]=r22			// store ar.rnat	;;		// Write new BSPSTORE	//mov	r21=ar.bsp	//;;	mov	r22=r21			// new bspstore equal to old	;;	mov	ar.bspstore=r22		// the new bspstore	;;		// Read and save the new BSP for calculating number of dirty regs.	mov	r21=ar.bsp	;;	sub	r21=r21,r22		// r21 -> ndirty	add     r19=TF_NDIRTY-TF_BSP,r19        // TF_NDIRTY pos in r19	;;	st8	[r19]=r21		// store ndirty	;;	mov	ar.rsc=IA64_RSE_EAGER	// RSE on again	;;	add	r19=TF_FPSR,r18	;;	mov	r21=ar.fpsr	;;	st8	[r19]=r21		// ar.fpsr	;;	//// r16 return jump pointer, r18 - trap frame base, 		// Load the gp with our module __gp	movl	gp=__gp	;;	add	r16=16,r16	// for jump to next bundle	;;	mov	b7=r16	;;{	.mfb	srlz.d	nop	0	br.sptk	b7	;;}END(save_tf_rse_switch)/** *	The function reloads the processor context stored in *	save_tf_rse_switch(). *	 *	On calling the function the bank 0 must be activ. *	The return is done through a rfi. *	Used register: b7, r16, r18, r19, r20, r21, r22 of bank 0 * *	@param: r18 pointer to the exception frame * */ENTRY(restore_tf_rse_switch) 	add	r19=TF_IPSR,r18	add	r20=TF_IIP,r18	;;	ld8	r21=[r19]		// load cr.ipsr	ld8	r22=[r20]		// load cr.iip#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	;;	mux1	r21=r21,@rev	mux1	r22=r22,@rev	;;#endif	movl	r16=XSI_IPSR		// XEN !!	;;	st8	[r16]=r21,XSI_IIP_OFS-XSI_IPSR_OFS	// XEN.ipsr	mov	r2=r21			// save for fp stuff below	;;	st8	[r16]=r22		// XEN.iip	;;	//// r18 - trap frame base 		// Allocate a zero sized frame	alloc	r30=ar.pfs,0,0,0,0	// discard current frame	;;		// calc number of dirty regs and put this into rsc.loardrs	add	r19=TF_NDIRTY,r18	;;	ld8	r22=[r19]		// ndirty	;;	shl	r21=r22,16		// value for ar.rsc	//mov	r19=(MOS_IA64_RSC_BE << IA64_RSC_BE)	;;	or	r21=(MOS_IA64_RSC_BE << IA64_RSC_BE),r21	;;	mov	ar.rsc=r21		// setup for loadrs	;;		// Issue a loadrs instruction{	.mmi	loadrs		// must be the first instruction	;;	nop 0x0	nop 0x0}		// Restore BSPSTORE from interrupted context	add	r19=TF_BSP,r18	add	r20=TF_RNAT,r18	;;		ld8	r21=[r19]		// load ar.bspstore	ld8	r22=[r20]		// load ar.rnat	;;	mov	ar.bspstore=r21		// set ar.bspstore	;;		// Restore RNAT	mov	ar.rnat=r22		// set ar.rnat	;;		// Restore PFS and IFS	add	r19=TF_PFS,r18	add	r20=TF_IFS,r18	movl	r16=XSI_IFS		// XEN !!	;;	ld8	r21=[r19]		// load ar.pfs	ld8	r22=[r20]		// load cr.ifs	;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r22=r22,@rev	;;#endif	add	r19=TF_RSC,r18	mov	ar.pfs=r21	st8	[r16]=r22		// XEN.ifs	;;		// Restore RSC	ld8	r21=[r19]		// load ar.rsc	;;	mov	ar.rsc=r21		// set ar.rsc	//// r18 - trap frame base	add	r19=TF_GP,r18	add	r20=TF_SP,r18	;;	ld8	gp=[r19],TF_TP-TF_GP	// load gp	ld8	sp=[r20],TF_PR-TF_SP	// load sp	;;	ld8	r13=[r19]		// load tp	ld8	r21=[r20]		// load pr	;;	mov	pr=r21,-1		// set pr	;;	add	r19=TF_BREG0,r18	add	r20=TF_BREG6,r18	;;	ld8	r21=[r19],TF_BREG7-TF_BREG0	// load b0	ld8	r22=[r20],16		// load b6	;;	mov	b0=r21	mov	b6=r22	;;	ld8	r21=[r19]		// load b7	ld8	r22=[r20],16		// load b3	;;	mov	b7=r21	//// r18 - trap frame base	mov	r14=r18			// Save the context pointer	;;	// bsw.1	movl r30=XSI_BANKNUM		// Switch to bank 1.	mov r31=1;;#if defined(BIG_ENDIAN)			// swap because mini-os is in BE	mux1	r31=r31,@rev	;;#endif	st4 [r30]=r31	;;

⌨️ 快捷键说明

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