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

📄 mca_asm.s

📁 linux 内核源代码
💻 S
📖 第 1 页 / 共 2 页
字号:
	add regs=MCA_SWITCH_STACK_OFFSET-MCA_PT_REGS_OFFSET, regs	;;	add temp1=SW(F2), regs	add temp2=SW(F3), regs	;;	stf.spill [temp1]=f2,32	stf.spill [temp2]=f3,32	;;	stf.spill [temp1]=f4,32	stf.spill [temp2]=f5,32	;;	stf.spill [temp1]=f12,32	stf.spill [temp2]=f13,32	;;	stf.spill [temp1]=f14,32	stf.spill [temp2]=f15,32	;;	stf.spill [temp1]=f16,32	stf.spill [temp2]=f17,32	;;	stf.spill [temp1]=f18,32	stf.spill [temp2]=f19,32	;;	stf.spill [temp1]=f20,32	stf.spill [temp2]=f21,32	;;	stf.spill [temp1]=f22,32	stf.spill [temp2]=f23,32	;;	stf.spill [temp1]=f24,32	stf.spill [temp2]=f25,32	;;	stf.spill [temp1]=f26,32	stf.spill [temp2]=f27,32	;;	stf.spill [temp1]=f28,32	stf.spill [temp2]=f29,32	;;	stf.spill [temp1]=f30,SW(B2)-SW(F30)	stf.spill [temp2]=f31,SW(B3)-SW(F31)	mov temp3=b2	mov temp4=b3	;;	st8 [temp1]=temp3,16	// save b2	st8 [temp2]=temp4,16	// save b3	mov temp3=b4	mov temp4=b5	;;	st8 [temp1]=temp3,SW(AR_LC)-SW(B4)	// save b4	st8 [temp2]=temp4	// save b5	mov temp3=ar.lc	;;	st8 [temp1]=temp3	// save ar.lc	// FIXME: Some proms are incorrectly accessing the minstate area as	// cached data.  The C code uses region 6, uncached virtual.  Ensure	// that there is no cache data lying around for the first 1K of the	// minstate area.	// Remove this code in September 2006, that gives platforms a year to	// fix their proms and get their customers updated.	add r1=32*1,r17	add r2=32*2,r17	add r3=32*3,r17	add r4=32*4,r17	add r5=32*5,r17	add r6=32*6,r17	add r7=32*7,r17	;;	fc r17	fc r1	fc r2	fc r3	fc r4	fc r5	fc r6	fc r7	add r17=32*8,r17	add r1=32*8,r1	add r2=32*8,r2	add r3=32*8,r3	add r4=32*8,r4	add r5=32*8,r5	add r6=32*8,r6	add r7=32*8,r7	;;	fc r17	fc r1	fc r2	fc r3	fc r4	fc r5	fc r6	fc r7	add r17=32*8,r17	add r1=32*8,r1	add r2=32*8,r2	add r3=32*8,r3	add r4=32*8,r4	add r5=32*8,r5	add r6=32*8,r6	add r7=32*8,r7	;;	fc r17	fc r1	fc r2	fc r3	fc r4	fc r5	fc r6	fc r7	add r17=32*8,r17	add r1=32*8,r1	add r2=32*8,r2	add r3=32*8,r3	add r4=32*8,r4	add r5=32*8,r5	add r6=32*8,r6	add r7=32*8,r7	;;	fc r17	fc r1	fc r2	fc r3	fc r4	fc r5	fc r6	fc r7	br.sptk b0//EndStub////////////////////////////////////////////////////////////////////////++// Name://	ia64_state_restore()//// Stub Description:////	Restore the SAL/OS state.  This is sensitive to the layout of struct//	ia64_sal_os_state in mca.h.////	r2 contains the return address, r3 contains either//	IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.////	In addition to the SAL to OS state, this routine restores all the//	registers that appear in struct pt_regs and struct switch_stack,//	excluding those in the PAL minstate area.////--ia64_state_restore:	// Restore the switch_stack data that is not in minstate nor pt_regs.	add regs=MCA_SWITCH_STACK_OFFSET, r3	mov b0=r2		// save return address	;;	GET_IA64_MCA_DATA(temp2)	;;	add regs=temp2, regs	;;	add temp1=SW(F2), regs	add temp2=SW(F3), regs	;;	ldf.fill f2=[temp1],32	ldf.fill f3=[temp2],32	;;	ldf.fill f4=[temp1],32	ldf.fill f5=[temp2],32	;;	ldf.fill f12=[temp1],32	ldf.fill f13=[temp2],32	;;	ldf.fill f14=[temp1],32	ldf.fill f15=[temp2],32	;;	ldf.fill f16=[temp1],32	ldf.fill f17=[temp2],32	;;	ldf.fill f18=[temp1],32	ldf.fill f19=[temp2],32	;;	ldf.fill f20=[temp1],32	ldf.fill f21=[temp2],32	;;	ldf.fill f22=[temp1],32	ldf.fill f23=[temp2],32	;;	ldf.fill f24=[temp1],32	ldf.fill f25=[temp2],32	;;	ldf.fill f26=[temp1],32	ldf.fill f27=[temp2],32	;;	ldf.fill f28=[temp1],32	ldf.fill f29=[temp2],32	;;	ldf.fill f30=[temp1],SW(B2)-SW(F30)	ldf.fill f31=[temp2],SW(B3)-SW(F31)	;;	ld8 temp3=[temp1],16	// restore b2	ld8 temp4=[temp2],16	// restore b3	;;	mov b2=temp3	mov b3=temp4	ld8 temp3=[temp1],SW(AR_LC)-SW(B4)	// restore b4	ld8 temp4=[temp2]	// restore b5	;;	mov b4=temp3	mov b5=temp4	ld8 temp3=[temp1]	// restore ar.lc	;;	mov ar.lc=temp3	// Restore the pt_regs data that is not in minstate.  The previous code	// left regs at switch_stack.	add regs=MCA_PT_REGS_OFFSET-MCA_SWITCH_STACK_OFFSET, regs	;;	add temp1=PT(B6), regs	add temp2=PT(B7), regs	;;	ld8 temp3=[temp1],PT(AR_CSD)-PT(B6)		// restore b6	ld8 temp4=[temp2],PT(AR_SSD)-PT(B7)		// restore b7	;;	mov b6=temp3	mov b7=temp4	ld8 temp3=[temp1],PT(AR_UNAT)-PT(AR_CSD)	// restore ar.csd	ld8 temp4=[temp2],PT(AR_PFS)-PT(AR_SSD)		// restore ar.ssd	;;	mov ar.csd=temp3	mov ar.ssd=temp4	ld8 temp3=[temp1]				// restore ar.unat	add temp1=PT(AR_CCV)-PT(AR_UNAT), temp1	ld8 temp4=[temp2],PT(AR_FPSR)-PT(AR_PFS)	// restore ar.pfs	;;	mov ar.unat=temp3	mov ar.pfs=temp4	// ar.rnat, ar.bspstore, loadrs are restore in ia64_old_stack.	ld8 temp3=[temp1],PT(F6)-PT(AR_CCV)		// restore ar.ccv	ld8 temp4=[temp2],PT(F7)-PT(AR_FPSR)		// restore ar.fpsr	;;	mov ar.ccv=temp3	mov ar.fpsr=temp4	ldf.fill f6=[temp1],PT(F8)-PT(F6)	ldf.fill f7=[temp2],PT(F9)-PT(F7)	;;	ldf.fill f8=[temp1],PT(F10)-PT(F8)	ldf.fill f9=[temp2],PT(F11)-PT(F9)	;;	ldf.fill f10=[temp1]	ldf.fill f11=[temp2]	// Restore the SAL to OS state. The previous code left regs at pt_regs.	add regs=MCA_SOS_OFFSET-MCA_PT_REGS_OFFSET, regs	;;	add temp1=SOS(SAL_RA), regs	add temp2=SOS(SAL_GP), regs	;;	ld8 r12=[temp1],16	// sal_ra	ld8 r9=[temp2],16	// sal_gp	;;	ld8 r22=[temp1],16	// pal_min_state, virtual	ld8 r13=[temp2],16	// prev_IA64_KR_CURRENT	;;	ld8 r16=[temp1],16	// prev_IA64_KR_CURRENT_STACK	ld8 r20=[temp2],16	// prev_task	;;	ld8 temp3=[temp1],16	// cr.isr	ld8 temp4=[temp2],16	// cr.ifa	;;	mov cr.isr=temp3	mov cr.ifa=temp4	ld8 temp3=[temp1],16	// cr.itir	ld8 temp4=[temp2],16	// cr.iipa	;;	mov cr.itir=temp3	mov cr.iipa=temp4	ld8 temp3=[temp1]	// cr.iim	ld8 temp4=[temp2]		// cr.iha	add temp1=SOS(OS_STATUS), regs	add temp2=SOS(CONTEXT), regs	;;	mov cr.iim=temp3	mov cr.iha=temp4	dep r22=0,r22,62,1	// pal_min_state, physical, uncached	mov IA64_KR(CURRENT)=r13	ld8 r8=[temp1]		// os_status	ld8 r10=[temp2]		// context	/* Wire IA64_TR_CURRENT_STACK to the stack that we are resuming to.  To	 * avoid any dependencies on the algorithm in ia64_switch_to(), just	 * purge any existing CURRENT_STACK mapping and insert the new one.	 *	 * r16 contains prev_IA64_KR_CURRENT_STACK, r13 contains	 * prev_IA64_KR_CURRENT, these values may have been changed by the C	 * code.  Do not use r8, r9, r10, r22, they contain values ready for	 * the return to SAL.	 */	mov r15=IA64_KR(CURRENT_STACK)		// physical granule mapped by IA64_TR_CURRENT_STACK	;;	shl r15=r15,IA64_GRANULE_SHIFT	;;	dep r15=-1,r15,61,3			// virtual granule	mov r18=IA64_GRANULE_SHIFT<<2		// for cr.itir.ps	;;	ptr.d r15,r18	;;	srlz.d	extr.u r19=r13,61,3			// r13 = prev_IA64_KR_CURRENT	shl r20=r16,IA64_GRANULE_SHIFT		// r16 = prev_IA64_KR_CURRENT_STACK	movl r21=PAGE_KERNEL			// page properties	;;	mov IA64_KR(CURRENT_STACK)=r16	cmp.ne p6,p0=RGN_KERNEL,r19		// new stack is in the kernel region?	or r21=r20,r21				// construct PA | page properties(p6)	br.spnt 1f				// the dreaded cpu 0 idle task in region 5:(	;;	mov cr.itir=r18	mov cr.ifa=r13	mov r20=IA64_TR_CURRENT_STACK	;;	itr.d dtr[r20]=r21	;;	srlz.d1:	br.sptk b0//EndStub////////////////////////////////////////////////////////////////////////++// Name://	ia64_new_stack()//// Stub Description:////	Switch to the MCA/INIT stack.////	r2 contains the return address, r3 contains either//	IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.////	On entry RBS is still on the original stack, this routine switches RBS//	to use the MCA/INIT stack.////	On entry, sos->pal_min_state is physical, on exit it is virtual.////--ia64_new_stack:	add regs=MCA_PT_REGS_OFFSET, r3	add temp2=MCA_SOS_OFFSET+SOS(PAL_MIN_STATE), r3	mov b0=r2			// save return address	GET_IA64_MCA_DATA(temp1)	invala	;;	add temp2=temp2, temp1		// struct ia64_sal_os_state.pal_min_state on MCA or INIT stack	add regs=regs, temp1		// struct pt_regs on MCA or INIT stack	;;	// Address of minstate area provided by PAL is physical, uncacheable.	// Convert to Linux virtual address in region 6 for C code.	ld8 ms=[temp2]			// pal_min_state, physical	;;	dep temp1=-1,ms,62,2		// set region 6	mov temp3=IA64_RBS_OFFSET-MCA_PT_REGS_OFFSET	;;	st8 [temp2]=temp1		// pal_min_state, virtual	add temp4=temp3, regs		// start of bspstore on new stack	;;	mov ar.bspstore=temp4		// switch RBS to MCA/INIT stack	;;	flushrs				// must be first in group	br.sptk b0//EndStub////////////////////////////////////////////////////////////////////////++// Name://	ia64_old_stack()//// Stub Description:////	Switch to the old stack.////	r2 contains the return address, r3 contains either//	IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.////	On entry, pal_min_state is virtual, on exit it is physical.////	On entry RBS is on the MCA/INIT stack, this routine switches RBS//	back to the previous stack.////	The psr is set to all zeroes.  SAL return requires either all zeroes or//	just psr.mc set.  Leaving psr.mc off allows INIT to be issued if this//	code does not perform correctly.////	The dirty registers at the time of the event were flushed to the//	MCA/INIT stack in ia64_pt_regs_save().  Restore the dirty registers//	before reverting to the previous bspstore.//--ia64_old_stack:	add regs=MCA_PT_REGS_OFFSET, r3	mov b0=r2			// save return address	GET_IA64_MCA_DATA(temp2)	LOAD_PHYSICAL(p0,temp1,1f)	;;	mov cr.ipsr=r0	mov cr.ifs=r0	mov cr.iip=temp1	;;	invala	rfi1:	add regs=regs, temp2		// struct pt_regs on MCA or INIT stack	;;	add temp1=PT(LOADRS), regs	;;	ld8 temp2=[temp1],PT(AR_BSPSTORE)-PT(LOADRS)	// restore loadrs	;;	ld8 temp3=[temp1],PT(AR_RNAT)-PT(AR_BSPSTORE)	// restore ar.bspstore	mov ar.rsc=temp2	;;	loadrs	ld8 temp4=[temp1]		// restore ar.rnat	;;	mov ar.bspstore=temp3		// back to old stack	;;	mov ar.rnat=temp4	;;	br.sptk b0//EndStub////////////////////////////////////////////////////////////////////////++// Name://	ia64_set_kernel_registers()//// Stub Description:////	Set the registers that are required by the C code in order to run on an//	MCA/INIT stack.////	r2 contains the return address, r3 contains either//	IA64_MCA_CPU_MCA_STACK_OFFSET or IA64_MCA_CPU_INIT_STACK_OFFSET.////--ia64_set_kernel_registers:	add temp3=MCA_SP_OFFSET, r3	mov b0=r2		// save return address	GET_IA64_MCA_DATA(temp1)	;;	add r12=temp1, temp3	// kernel stack pointer on MCA/INIT stack	add r13=temp1, r3	// set current to start of MCA/INIT stack	add r20=temp1, r3	// physical start of MCA/INIT stack	;;	DATA_PA_TO_VA(r12,temp2)	DATA_PA_TO_VA(r13,temp3)	;;	mov IA64_KR(CURRENT)=r13	/* Wire IA64_TR_CURRENT_STACK to the MCA/INIT handler stack.  To avoid	 * any dependencies on the algorithm in ia64_switch_to(), just purge	 * any existing CURRENT_STACK mapping and insert the new one.	 */	mov r16=IA64_KR(CURRENT_STACK)		// physical granule mapped by IA64_TR_CURRENT_STACK	;;	shl r16=r16,IA64_GRANULE_SHIFT	;;	dep r16=-1,r16,61,3			// virtual granule	mov r18=IA64_GRANULE_SHIFT<<2		// for cr.itir.ps	;;	ptr.d r16,r18	;;	srlz.d	shr.u r16=r20,IA64_GRANULE_SHIFT	// r20 = physical start of MCA/INIT stack	movl r21=PAGE_KERNEL			// page properties	;;	mov IA64_KR(CURRENT_STACK)=r16	or r21=r20,r21				// construct PA | page properties	;;	mov cr.itir=r18	mov cr.ifa=r13	mov r20=IA64_TR_CURRENT_STACK	movl r17=FPSR_DEFAULT	;;	mov.m ar.fpsr=r17			// set ar.fpsr to kernel default value	;;	itr.d dtr[r20]=r21	;;	srlz.d	br.sptk b0//EndStub//////////////////////////////////////////////////////////////////////#undef	ms#undef	regs#undef	temp1#undef	temp2#undef	temp3#undef	temp4// Support function for mca.c, it is here to avoid using inline asm.  Given the// address of an rnat slot, if that address is below the current ar.bspstore// then return the contents of that slot, otherwise return the contents of// ar.rnat.GLOBAL_ENTRY(ia64_get_rnat)	alloc r14=ar.pfs,1,0,0,0	mov ar.rsc=0	;;	mov r14=ar.bspstore	;;	cmp.lt p6,p7=in0,r14	;;(p6)	ld8 r8=[in0](p7)	mov r8=ar.rnat	mov ar.rsc=3	br.ret.sptk.many rpEND(ia64_get_rnat)

⌨️ 快捷键说明

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