/* * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * $NetBSD: locore.s,v 1.47 1998/03/22 07:26:32 thorpej Exp $ * $FreeBSD$ */ #include #include /**************************************************************************/ /* * XentArith: * System arithmetic trap entry point. */ PALVECT(XentArith) /* setup frame, save registers */ /* a0, a1, & a2 already set up */ ldiq a3, ALPHA_KENTRY_ARITH mov sp, a4 ; .loc 1 __LINE__ CALL(trap) jmp zero, exception_return END(XentArith) /**************************************************************************/ /* * XentIF: * System instruction fault trap entry point. */ PALVECT(XentIF) /* setup frame, save registers */ /* a0, a1, & a2 already set up */ ldiq a3, ALPHA_KENTRY_IF mov sp, a4 ; .loc 1 __LINE__ CALL(trap) jmp zero, exception_return END(XentIF) /**************************************************************************/ /* * XentInt: * System interrupt entry point. */ PALVECT(XentInt) /* setup frame, save registers */ /* a0, a1, & a2 already set up */ mov sp, a3 ; .loc 1 __LINE__ CALL(interrupt) jmp zero, exception_return END(XentInt) /**************************************************************************/ /* * XentMM: * System memory management fault entry point. */ PALVECT(XentMM) /* setup frame, save registers */ /* a0, a1, & a2 already set up */ ldiq a3, ALPHA_KENTRY_MM mov sp, a4 ; .loc 1 __LINE__ CALL(trap) jmp zero, exception_return END(XentMM) /**************************************************************************/ /* * XentSys: * System call entry point. */ ESETUP(XentSys) ; .loc 1 __LINE__ stq v0,(FRAME_V0*8)(sp) /* in case we need to restart */ stq s0,(FRAME_S0*8)(sp) stq s1,(FRAME_S1*8)(sp) stq s2,(FRAME_S2*8)(sp) stq s3,(FRAME_S3*8)(sp) stq s4,(FRAME_S4*8)(sp) stq s5,(FRAME_S5*8)(sp) stq s6,(FRAME_S6*8)(sp) stq a3,(FRAME_A3*8)(sp) stq a4,(FRAME_A4*8)(sp) stq a5,(FRAME_A5*8)(sp) stq ra,(FRAME_RA*8)(sp) stq a0,(FRAME_A0*8)(sp) stq a1,(FRAME_A1*8)(sp) stq a2,(FRAME_A2*8)(sp) ldiq t1,FRAME_FLAGS_SYSCALL stq t1,(FRAME_FLAGS*8)(sp) /* syscall number, passed in v0, is first arg, frame pointer second */ mov v0,a0 mov sp,a1 ; .loc 1 __LINE__ br pv,1f 1: LDGP(pv) CALL(syscall) /* Handle any AST's. */ 2: ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */ call_pal PAL_OSF1_swpipl ldq s0, PC_CURTHREAD(pcpup) /* checking for pending asts */ ldl s1, TD_FLAGS(s0) ldiq s2, TDF_ASTPENDING | TDF_NEEDRESCHED and s1, s2 beq s1, 3f ldiq a0, ALPHA_PSL_IPL_0 /* reenable interrupts */ call_pal PAL_OSF1_swpipl mov sp, a0 /* only arg is frame */ CALL(ast) jmp zero, 2b /* see if we need a full exception_return */ 3: ldq t1, (FRAME_FLAGS*8)(sp) and t1, FRAME_FLAGS_SYSCALL beq t1, exception_return /* set the hae register if this process has specified a value */ ldq t1, TD_MD_FLAGS(s0) and t1, MDTD_HAEUSED beq t1, 3f ldq a0, TD_MD_HAE(s0) ldq pv, chipset + CHIPSET_WRITE_HAE CALL((pv)) 3: #ifdef SMP /* leave the kernel */ stl zero, TD_MD_KERNNEST(s0) #endif /* restore the registers, and return */ ldq v0,(FRAME_V0*8)(sp) ldq s0,(FRAME_S0*8)(sp) ldq s1,(FRAME_S1*8)(sp) ldq s2,(FRAME_S2*8)(sp) ldq s3,(FRAME_S3*8)(sp) ldq s4,(FRAME_S4*8)(sp) ldq s5,(FRAME_S5*8)(sp) ldq s6,(FRAME_S6*8)(sp) ldq a3,(FRAME_A3*8)(sp) ldq a4,(FRAME_A4*8)(sp) ldq a5,(FRAME_A5*8)(sp) ldq ra,(FRAME_RA*8)(sp) ldq a0,(FRAME_A0*8)(sp) ldq a1,(FRAME_A1*8)(sp) ldq a2,(FRAME_A2*8)(sp) lda sp,(FRAME_SW_SIZE*8)(sp) call_pal PAL_OSF1_retsys END(XentSys) /**************************************************************************/ /* * XentUna: * System unaligned access entry point. */ LEAF(XentUna, 3) /* XXX should be NESTED */ .set noat lda sp,-(FRAME_SW_SIZE*8)(sp) stq at_reg,(FRAME_AT*8)(sp) .set at stq ra,(FRAME_RA*8)(sp) bsr ra, exception_save_regs /* jmp/CALL trashes pv/t12 */ /* a0, a1, & a2 already set up */ ldiq a3, ALPHA_KENTRY_UNA mov sp, a4 ; .loc 1 __LINE__ br pv, 1f 1: LDGP(pv) CALL(trap) jmp zero, exception_return END(XentUna) /**************************************************************************/ /* * console 'restart' routine to be placed in HWRPB. */ LEAF(XentRestart, 1) /* XXX should be NESTED */ .set noat lda sp,-(FRAME_SIZE*8)(sp) stq at_reg,(FRAME_AT*8)(sp) .set at stq v0,(FRAME_V0*8)(sp) stq a3,(FRAME_A3*8)(sp) stq a4,(FRAME_A4*8)(sp) stq a5,(FRAME_A5*8)(sp) stq s0,(FRAME_S0*8)(sp) stq s1,(FRAME_S1*8)(sp) stq s2,(FRAME_S2*8)(sp) stq s3,(FRAME_S3*8)(sp) stq s4,(FRAME_S4*8)(sp) stq s5,(FRAME_S5*8)(sp) stq s6,(FRAME_S6*8)(sp) stq t0,(FRAME_T0*8)(sp) stq t1,(FRAME_T1*8)(sp) stq t2,(FRAME_T2*8)(sp) stq t3,(FRAME_T3*8)(sp) stq t4,(FRAME_T4*8)(sp) stq t5,(FRAME_T5*8)(sp) stq t6,(FRAME_T6*8)(sp) stq t7,(FRAME_T7*8)(sp) stq t8,(FRAME_T8*8)(sp) stq t9,(FRAME_T9*8)(sp) stq t10,(FRAME_T10*8)(sp) stq t11,(FRAME_T11*8)(sp) stq t12,(FRAME_T12*8)(sp) stq ra,(FRAME_RA*8)(sp) br pv,1f 1: LDGP(pv) ldq a0,(FRAME_RA*8)(sp) /* a0 = ra */ ldq a1,(FRAME_T11*8)(sp) /* a1 = ai */ ldq a2,(FRAME_T12*8)(sp) /* a2 = pv */ CALL(console_restart) call_pal PAL_halt END(XentRestart) /* * exception_return: return from trap, exception, or syscall */ LEAF(exception_return, 1) /* XXX should be NESTED */ br pv, Ler1 Ler1: LDGP(pv) ldq s0, PC_CURTHREAD(pcpup) /* save curthread in s0 */ #ifdef SMP ldl s1, TD_MD_KERNNEST(s0) subl s1, 1, s1 /* decrement nesting level */ #endif ldq t1, (FRAME_PS * 8)(sp) /* get the saved PS */ and t1, ALPHA_PSL_USERMODE, t0 /* are we returning to user? */ beq t0, Lkernelret /* no: kernel return */ /* Handle any AST's or resched's. */ 1: ldiq a0, ALPHA_PSL_IPL_HIGH /* disable all interrupts */ call_pal PAL_OSF1_swpipl ldl s2, TD_FLAGS(s0) /* atomically with returning */ ldiq s3, TDF_ASTPENDING | TDF_NEEDRESCHED and s2, s3 beq s2, 2f ldiq a0, ALPHA_PSL_IPL_0 /* reenable interrupts */ call_pal PAL_OSF1_swpipl mov sp, a0 /* only arg is frame */ CALL(ast) jmp zero, 1b 2: #ifdef SMP br Lrestoreregs #endif Lkernelret: #ifdef SMP beq s1, Lrestoreregs stq pcpup, (FRAME_T7*8)(sp) /* fixup pcpup */ #endif Lrestoreregs: /* set the hae register if this process has specified a value */ ldq t1, TD_MD_FLAGS(s0) and t1, MDTD_HAEUSED beq t1, Lnohae ldq a0, TD_MD_HAE(t0) ldq pv, chipset + CHIPSET_WRITE_HAE CALL((pv)) Lnohae: #ifdef SMP /* leave the kernel */ stl s1, TD_MD_KERNNEST(s0) #endif /* restore the registers, and return */ bsr ra, exception_restore_regs /* jmp/CALL trashes pv/t12 */ ldq ra,(FRAME_RA*8)(sp) .set noat ldq at_reg,(FRAME_AT*8)(sp) lda sp,(FRAME_SW_SIZE*8)(sp) call_pal PAL_OSF1_rti .set at END(exception_return) LEAF(exception_save_regs, 0) stq v0,(FRAME_V0*8)(sp) stq a3,(FRAME_A3*8)(sp) stq a4,(FRAME_A4*8)(sp) stq a5,(FRAME_A5*8)(sp) stq s0,(FRAME_S0*8)(sp) stq s1,(FRAME_S1*8)(sp) stq s2,(FRAME_S2*8)(sp) stq s3,(FRAME_S3*8)(sp) stq s4,(FRAME_S4*8)(sp) stq s5,(FRAME_S5*8)(sp) stq s6,(FRAME_S6*8)(sp) stq t0,(FRAME_T0*8)(sp) stq t1,(FRAME_T1*8)(sp) stq t2,(FRAME_T2*8)(sp) stq t3,(FRAME_T3*8)(sp) stq t4,(FRAME_T4*8)(sp) stq t5,(FRAME_T5*8)(sp) stq t6,(FRAME_T6*8)(sp) stq t7,(FRAME_T7*8)(sp) stq t8,(FRAME_T8*8)(sp) stq t9,(FRAME_T9*8)(sp) stq t10,(FRAME_T10*8)(sp) stq t11,(FRAME_T11*8)(sp) stq t12,(FRAME_T12*8)(sp) .set noat lda at_reg,(FRAME_SIZE*8)(sp) stq at_reg,(FRAME_SP*8)(sp) .set at stq zero,(FRAME_FLAGS*8)(sp) RET END(exception_save_regs) LEAF(exception_restore_regs, 0) ldq v0,(FRAME_V0*8)(sp) ldq a3,(FRAME_A3*8)(sp) ldq a4,(FRAME_A4*8)(sp) ldq a5,(FRAME_A5*8)(sp) ldq s0,(FRAME_S0*8)(sp) ldq s1,(FRAME_S1*8)(sp) ldq s2,(FRAME_S2*8)(sp) ldq s3,(FRAME_S3*8)(sp) ldq s4,(FRAME_S4*8)(sp) ldq s5,(FRAME_S5*8)(sp) ldq s6,(FRAME_S6*8)(sp) ldq t0,(FRAME_T0*8)(sp) ldq t1,(FRAME_T1*8)(sp) ldq t2,(FRAME_T2*8)(sp) ldq t3,(FRAME_T3*8)(sp) ldq t4,(FRAME_T4*8)(sp) ldq t5,(FRAME_T5*8)(sp) ldq t6,(FRAME_T6*8)(sp) ldq t7,(FRAME_T7*8)(sp) ldq t8,(FRAME_T8*8)(sp) ldq t9,(FRAME_T9*8)(sp) ldq t10,(FRAME_T10*8)(sp) ldq t11,(FRAME_T11*8)(sp) ldq t12,(FRAME_T12*8)(sp) RET END(exception_restore_regs)