From owner-p4-projects@FreeBSD.ORG Tue Apr 8 01:15:00 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C7E9137B404; Tue, 8 Apr 2003 01:14:59 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 63F7A37B401 for ; Tue, 8 Apr 2003 01:14:59 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id B6FF743F93 for ; Tue, 8 Apr 2003 01:14:58 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h388Ew0U009055 for ; Tue, 8 Apr 2003 01:14:58 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h388Ew6U009052 for perforce@freebsd.org; Tue, 8 Apr 2003 01:14:58 -0700 (PDT) Date: Tue, 8 Apr 2003 01:14:58 -0700 (PDT) Message-Id: <200304080814.h388Ew6U009052@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 28499 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Apr 2003 08:15:00 -0000 http://perforce.freebsd.org/chv.cgi?CH=28499 Change 28499 by marcel@marcel_nfs on 2003/04/08 01:14:28 Snapshot highlights: o cpu_switch() and cpu_throw() are now C functions. cpu_switch() handles the high-level switching, while the low-level switching is handled by swapctx(). cpu_throw() depends on restorectx(). o New implementation of exception_save() and exception_restore(). Does not have everything yet for interrupting user space. We also don't use physical addressing anymore. We align the frame on a 1K boundary and arrange for a well-defined failure point so that we know where to jump to if we have a nested fault. o We pass the address of the EPC page in ar.k3. We don't have to worry about PAL clobbering the value, because we only need it for syscalls, which don't use exceptions. We have to make sure we restore ar.k3 when we return to user space though. There are probably a lot of loose ends... Affected files ... .. //depot/projects/ia64_epc/sys/conf/files.ia64#5 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/context.s#6 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/db_interface.c#3 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/exception.s#6 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/genassym.c#6 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/locore.s#5 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/machdep.c#6 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/swtch.s#3 delete .. //depot/projects/ia64_epc/sys/ia64/ia64/syscall.s#3 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/trap.c#7 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/vm_machdep.c#4 edit .. //depot/projects/ia64_epc/sys/ia64/include/_regset.h#5 edit .. //depot/projects/ia64_epc/sys/ia64/include/asm.h#2 edit .. //depot/projects/ia64_epc/sys/ia64/include/cpu.h#4 edit .. //depot/projects/ia64_epc/sys/ia64/include/db_machdep.h#3 edit .. //depot/projects/ia64_epc/sys/ia64/include/pcb.h#4 edit Differences ... ==== //depot/projects/ia64_epc/sys/conf/files.ia64#5 (text+ko) ==== @@ -57,7 +57,6 @@ ia64/ia64/support.s standard ia64/ia64/ssc.c optional ski ia64/ia64/sscdisk.c optional ski -ia64/ia64/swtch.s standard ia64/ia64/sys_machdep.c standard ia64/ia64/syscall.s standard ia64/ia64/trap.c standard ==== //depot/projects/ia64_epc/sys/ia64/ia64/context.s#6 (text+ko) ==== @@ -32,6 +32,302 @@ .section .text.context, "ax" /* + * void restorectx(struct pcb *) + */ +ENTRY(restorectx, 1) +{ .mmi + invala + mov ar.rsc=0 + add r31=8,r32 + ;; +} +{ .mmi + ld8 r12=[r32] // sp + ld8 r16=[r31],16 // unat (before) + add r30=16,r32 + ;; +} +{ .mmi + ld8 r17=[r30],16 // rp + ld8 r18=[r31],16 // pr + add r32=SIZEOF_SPECIAL,r32 + ;; +} +{ .mmi + ld8 r19=[r30],16 // pfs + ld8 r20=[r31],16 // bspstore + mov rp=r17 + ;; +} +{ .mmi + loadrs + ld8 r21=[r30],16 // rnat + mov pr=r18,0x1fffe + ;; +} +{ .mmi + ld8 r17=[r32],8 // unat (after) + mov ar.bspstore=r20 + mov ar.pfs=19 + ;; +} +{ .mmi + mov ar.unat=r17 + mov ar.rnat=r21 + add r31=8,r32 + ;; +} +{ .mmi + ld8.fill r4=[r32],16 // r4 + ld8.fill r5=[r31],16 // r5 + nop 0 + ;; +} +{ .mmi + ld8.fill r6=[r32],16 // r6 + ld8.fill r7=[r31],16 // r7 + nop 1 + ;; +} +{ .mmi + mov ar.unat=r16 + mov ar.rsc=3 + nop 2 +} +{ .mmi + ld8 r17=[r32],16 // b1 + ld8 r18=[r31],16 // b2 + nop 3 + ;; +} +{ .mmi + ld8 r19=[r32],16 // b3 + ld8 r20=[r31],16 // b4 + mov b1=r17 + ;; +} +{ .mmi + ld8 r16=[r32],24 // b5 + ld8 r17=[r31],32 // lc + mov b2=r18 + ;; +} +{ .mmi + ldf.fill f2=[r32],32 + ldf.fill f3=[r31],32 + mov b3=r19 + ;; +} +{ .mmi + ldf.fill f4=[r32],32 + ldf.fill f5=[r31],32 + mov b4=r20 + ;; +} +{ .mmi + ldf.fill f16=[r32],32 + ldf.fill f17=[r31],32 + mov b5=r16 + ;; +} +{ .mmi + ldf.fill f18=[r32],32 + ldf.fill f19=[r31],32 + mov ar.lc=r17 + ;; +} + ldf.fill f20=[r32],32 + ldf.fill f21=[r31],32 + ;; + ldf.fill f22=[r32],32 + ldf.fill f23=[r31],32 + ;; + ldf.fill f24=[r32],32 + ldf.fill f25=[r31],32 + ;; + ldf.fill f26=[r32],32 + ldf.fill f27=[r31],32 + ;; + ldf.fill f28=[r32],32 + ldf.fill f29=[r31],32 + ;; +{ .mmb + ldf.fill f30=[r32] + ldf.fill f31=[r31] + br.ret.sptk rp + ;; +} +END(restorectx) + +/* + * void savectx(struct pcb *) + * void swapctx(struct pcb *old, struct pcb *new) + */ + +ENTRY(savectx,1) +{ .mmi + alloc r16=ar.pfs,1,1,0,0 + ;; + add r33=0,r0 + nop 0 +} + /* FALLTHROUGH */ + +ENTRY(swapctx, 2) +{ .mmi + flushrs + mov r16=ar.unat + add r31=8,r32 + ;; +} +{ .mmi + st8 [r32]=sp,16 // sp + mov ar.rsc=0 + mov r17=rp + ;; +} +{ .mmi + st8 [r31]=r16,16 // unat (before) + st8 [r32]=r17,16 // rp + mov r16=pr + ;; +} +{ .mmi + st8 [r31]=r16,16 // pr + mov r17=ar.bspstore + mov r16=ar.pfs + ;; +} +{ .mmi + st8 [r32]=r16,16 // pfs + st8 [r31]=r17,16 // bspstore + cmp.eq p15,p0=0,r33 + ;; +} +{ .mmi + mov r16=ar.rnat +(p15) mov ar.rsc=3 + add r30=SIZEOF_SPECIAL-(6*8),r32 + ;; +} +{ .mmi + st8 [r32]=r16,SIZEOF_SPECIAL-(4*8) // rnat + st8 [r31]=r0,SIZEOF_SPECIAL-(6*8) // __spare + mov r16=b1 + ;; +} + /* callee_saved */ +{ .mmi + .mem.offset 8,0 + st8.spill [r31]=r4,16 // r4 + .mem.offset 16,0 + st8.spill [r32]=r5,16 // r5 + mov r17=b2 + ;; +} +{ .mmi + .mem.offset 24,0 + st8.spill [r31]=r6,16 // r6 + .mem.offset 32,0 + st8.spill [r32]=r7,16 // r7 + mov r18=b3 + ;; +} +{ .mmi + st8 [r31]=r16,16 // b1 + mov r16=ar.unat + mov r19=b4 + ;; +} +{ .mmi + st8 [r30]=r16 // unat (after) + st8 [r32]=r17,16 // b2 + mov r16=b5 + ;; +} +{ .mmi + st8 [r31]=r18,16 // b3 + st8 [r32]=r19,16 // b4 + mov r17=ar.lc + ;; +} + st8 [r31]=r16,16 // b5 + st8 [r32]=r17,16 // lc + ;; + st8 [r31]=r0,24 // __spare + stf.spill [r32]=f2,32 + ;; + stf.spill [r31]=f3,32 + stf.spill [r32]=f4,32 + ;; + stf.spill [r31]=f5,32 + stf.spill [r32]=f16,32 + ;; + stf.spill [r31]=f17,32 + stf.spill [r32]=f18,32 + ;; + stf.spill [r31]=f19,32 + stf.spill [r32]=f20,32 + ;; + stf.spill [r31]=f21,32 + stf.spill [r32]=f22,32 + ;; + stf.spill [r31]=f23,32 + stf.spill [r32]=f24,32 + ;; + stf.spill [r31]=f25,32 + stf.spill [r32]=f26,32 + ;; + stf.spill [r31]=f27,32 + stf.spill [r32]=f28,32 + ;; + stf.spill [r31]=f29,32 + stf.spill [r32]=f30 + ;; +{ .mfb + stf.spill [r31]=f31 + nop 0 +(p15) br.ret.sptk rp + ;; +} +{ .mfb + mov r32=r33 + nop 0 + br.sptk restorectx + ;; +} +END(swapctx) + +/* + * fork_trampoline() + * + * Arrange for a function to be invoked neatly, after a cpu_switch(). + * + * Invokes fork_exit() passing in three arguments: a callout function, an + * argument to the callout, and a trapframe pointer. For child processes + * returning from fork(2), the argument is a pointer to the child process. + * + * The callout function is in r4, the address to return to after executing + * fork_exit() is in r5, and the argument is in r6. + */ +ENTRY(fork_trampoline, 0) + .prologue + .save rp,r0 + .body + alloc r14=ar.pfs,0,0,3,0 + ;; + mov b0=r5 + mov out0=r4 + mov out1=r6 + add out2=16,sp + ;; + br.call.sptk.few rp=fork_exit + ;; + br.cond.sptk.many exception_restore + ;; +END(fork_trampoline) + +/* * _getcontext(ucontext_t *ucp) */ ENTRY(_getcontext, 1) ==== //depot/projects/ia64_epc/sys/ia64/ia64/db_interface.c#3 (text+ko) ==== @@ -79,7 +79,7 @@ #define DB_MISC_REGS 13 /* make sure this is correct */ {"pc", (db_expr_t*) 0, db_get_pc_reg}, - {"ip", (db_expr_t*) &ddb_regs.tf_special.ip, FCN_NULL}, + {"ip", (db_expr_t*) &ddb_regs.tf_special.iip, FCN_NULL}, {"psr", (db_expr_t*) &ddb_regs.tf_special.psr, FCN_NULL}, {"cr.isr", (db_expr_t*) &ddb_regs.tf_special.isr, FCN_NULL}, {"cr.ifa", (db_expr_t*) &ddb_regs.tf_special.ifa, FCN_NULL}, ==== //depot/projects/ia64_epc/sys/ia64/ia64/exception.s#6 (text+ko) ==== @@ -31,12 +31,498 @@ #include /* - * ar.k7 = address of gateway page - * ar.k6 = ksp - * ar.k5 = kbsp - * ar.k4 = pcpup + * ar.k7 = kernel memory stack + * ar.k6 = kernel register stack + * ar.k4 = PCPU data + */ + + .text + +/* + * exception_save: save interrupted state + * + * Arguments: + * r16 address of bundle that contains the branch. The + * return address will be the next bundle. + */ +ENTRY(exception_save, 0) +{ .mii + mov r17=sp + mov r18=pr + extr.u r31=sp,61,3 + ;; +} +{ .mmi + cmp.le p14,p15=5,r31 + ;; +(p15) mov r31=ar.k7 // kernel memory stack +(p14) mov r31=sp + ;; +} +{ .mmi + add r30=-SIZEOF_TRAPFRAME,r31 + ;; + mov r20=ar.unat + dep sp=0,r30,0,10 + ;; +} +{ .mmi + mov r21=ar.rsc + mov ar.rsc=0 + sub r19=r31,sp + ;; +} + + /* + * We have a 1KB aligned trapframe, pointed to by sp. If we write + * to the trapframe, we may trigger a data nested TLB fault. By + * aligning the trapframe on a 1KB boundary, we guarantee that if + * we get a data nested TLB fault, it will be on the very first + * write. Since the data nested TLB fault does not preserve any + * state, we have to be careful what we clobber. Consequently, we + * have to be careful what we use here. The registers that must + * not be clobbered by the data nested TLB fault handler on top + * of any interrupted state we haven't saved yet (ie almost all + * of it) are: p14, p15, sp and r16-r21. + */ +exception_save_restart: +{ .mmi + st8 [sp]=r19 // length + mov r22=cr.iip + add r31=8,sp + ;; +} +{ .mmi + st8 [r31]=r0,16 // flags + mov r29=ar.bspstore + add r30=16,sp + ;; +} +{ .mmi + st8.spill [r30]=r17,16 // sp + st8 [r31]=r20,16 // unat + mov r27=b0 + ;; +} +{ .mmi + st8 [r30]=r27,16 // rp + st8 [r31]=r18,16 // pr + mov r27=ar.pfs + ;; +} +{ .mmb + st8 [r30]=r27,16 // pfs + st8 [r31]=r29,16 // bspstore + cover + ;; +} +{ .mmi + mov r17=ar.rnat + mov r18=ar.fpsr + extr.u r28=r29,61,3 + ;; +} +{ .mmi + st8 [r30]=r17,16 // rnat + st8 [r31]=r0,16 // __spare + cmp.le p12,p13=5,r28 + ;; +} +{ .mmi + st8.spill [r30]=r13,16 // tp + st8 [r31]=r21,16 // rsc + nop 0 + ;; +} +{ .mmi + mov r17=cr.ipsr +(p13) mov r29=ar.k6 // kernel register stack + nop 0 + ;; +} +{ .mmi + st8 [r30]=r18,16 // fpsr + st8 [r31]=r17,16 // psr + nop 0 + ;; +} +{ .mmi + mov ar.bspstore=r29 + ;; + mov r18=ar.bsp + nop 0 + ;; +} +{ .mmi + st8.spill [r30]=gp,16 // gp + mov r19=cr.ifs + sub r18=r18,r29 + ;; +} +{ .mmi + st8 [r31]=r18,16 // ndirty + mov r20=cr.ifa + nop 0 + ;; +} +{ .mmi + st8 [r30]=r19,16 // cfm + st8 [r31]=r22,16 // iip + nop 0 + ;; +} +{ .mmi + st8 [r30]=r20 // ifa + mov r18=cr.isr + add r29=16,r30 + ;; +} +{ .mmi + st8 [r31]=r18 // isr + add r30=8,r29 + add r31=16,r29 + ;; +} +{ .mmi + .mem.offset 0,0 + st8.spill [r30]=r2,16 // r2 + .mem.offset 8,0 + st8.spill [r31]=r3,16 // r3 + add r2=9*8,r29 + ;; +} +{ .mmi + .mem.offset 0,0 + st8.spill [r30]=r8,16 // r8 + .mem.offset 8,0 + st8.spill [r31]=r9,16 // r9 + add r3=8,r2 + ;; +} +{ .mmi + .mem.offset 0,0 + st8.spill [r30]=r10,16 // r10 + .mem.offset 8,0 + st8.spill [r31]=r11,16 // r11 + add r8=16,r16 + ;; +} +{ .mmi + .mem.offset 0,0 + st8.spill [r30]=r14 // r14 + .mem.offset 8,0 + st8.spill [r31]=r15 // r15 + mov r9=r29 +} +{ .mmb + mov r10=ar.csd + mov r11=ar.ssd + bsw.1 + ;; +} +{ .mmi + .mem.offset 0,0 + st8.spill [r2]=r16,16 // r16 + .mem.offset 8,0 + st8.spill [r3]=r17,16 // r17 + mov r14=b6 + ;; +} +{ .mmi + .mem.offset 0,0 + st8.spill [r2]=r18,16 // r18 + .mem.offset 8,0 + st8.spill [r3]=r19,16 // r19 + mov r15=b7 + ;; +} +{ .mmi + .mem.offset 0,0 + st8.spill [r2]=r20,16 // r20 + .mem.offset 8,0 + st8.spill [r3]=r21,16 // r21 + mov b7=r8 + ;; +} +{ .mmi + .mem.offset 0,0 + st8.spill [r2]=r22,16 // r22 + .mem.offset 8,0 + st8.spill [r3]=r23,16 // r23 + ;; +} + + .mem.offset 0,0 + st8.spill [r2]=r24,16 // r24 + .mem.offset 8,0 + st8.spill [r3]=r25,16 // r25 + ;; + .mem.offset 0,0 + st8.spill [r2]=r26,16 // r26 + .mem.offset 8,0 + st8.spill [r3]=r27,16 // r27 + ;; + .mem.offset 0,0 + st8.spill [r2]=r28,16 // r28 + .mem.offset 8,0 + st8.spill [r3]=r29,16 // r29 + ;; + .mem.offset 0,0 + st8.spill [r2]=r30,16 // r30 + .mem.offset 8,0 + st8.spill [r3]=r31,16 // r31 + ;; + +{ .mmi + st8 [r2]=r14,16 // b6 + mov r17=ar.unat + nop 0 + ;; +} +{ .mmi + st8 [r3]=r15,16 // b7 + mov r16=ar.ccv + nop 0 + ;; +} +{ .mmi + st8 [r2]=r16,16 // ccv + st8 [r3]=r10,16 // csd + nop 0 + ;; +} +{ .mmi + st8 [r2]=r11,24 // ssd + st8 [r9]=r17 + nop 0 + ;; +} + + stf.spill [r3]=f6,32 // f6 + stf.spill [r2]=f7,32 // f7 + ;; + stf.spill [r3]=f8,32 // f8 + stf.spill [r2]=f9,32 // f9 + ;; + stf.spill [r3]=f10,32 // f10 + stf.spill [r2]=f11,32 // f11 + ;; + stf.spill [r3]=f12,32 // f12 + stf.spill [r2]=f13,32 // f13 + ;; + stf.spill [r3]=f14 // f14 + stf.spill [r2]=f15 // f15 + ;; +{ .mmi + mov ar.rsc=3 + mov r13=ar.k4 + nop 0 + ;; +} +{ .mlx + ssm psr.ic + movl gp=__gp + ;; +} +{ .mfb + srlz.d + nop 0 + br.sptk b7 + ;; +} +END(exception_save) + +/* + * exception_restore: restore interrupted state + * + * Arguments: + * sp+16 trapframe pointer */ +ENTRY(exception_restore, 0) + /* + * Read the length of the trapframe with interrupts enabled and + * interrupt collection enabled. That way we can safely trap on + * the load in case the address translation of the trapframe has + * been flushed. + */ +{ .mmi + add sp=16,sp + ;; + ld8 r9=[sp] // length + add r3=SIZEOF_TRAPFRAME-32,sp + ;; +} +{ .mmi + rsm psr.ic|psr.i + ;; + srlz.d + add r2=16,r3 + ;; +} +{ .mmi + ldf.fill f15=[r2],-32 // f15 + ldf.fill f14=[r3],-32 // f14 + add r8=SIZEOF_SPECIAL+16,sp + ;; +} +{ .mmi + ldf.fill f13=[r2],-32 // f13 + ldf.fill f12=[r3],-32 // f12 + add r9=r9,sp + ;; +} + + ldf.fill f11=[r2],-32 // f11 + ldf.fill f10=[r3],-32 // f10 + ;; + ldf.fill f9=[r2],-32 // f9 + ldf.fill f8=[r3],-32 // f8 + ;; + ldf.fill f7=[r2],-24 // f7 + ldf.fill f6=[r3],-16 // f6 + ;; + +{ .mmi + ld8 r8=[r8] // unat (after) + mov ar.k7=r9 + nop 0 + ;; +} +{ .mmi + ld8 r10=[r2],-16 // ssd + ld8 r11=[r3],-16 // csd + nop 0 + ;; +} +{ .mmi + mov ar.unat=r8 + mov ar.ssd=r10 + nop 0 +} +{ .mmi + ld8 r14=[r2],-16 // ccv + ld8 r15=[r3],-16 // b7 + nop 0 + ;; +} +{ .mmi + mov ar.csd=r11 + mov ar.ccv=r14 + mov b7=r15 + ;; +} +{ .mmi + ld8 r8=[r2],-16 // b6 + ld8.fill r31=[r3],-16 // r31 + nop 0 + ;; +} +{ .mmi + ld8.fill r30=[r2],-16 // r30 + ld8.fill r29=[r3],-16 // r29 + mov b6=r8 + ;; +} + + ld8.fill r28=[r2],-16 // r28 + ld8.fill r27=[r3],-16 // r27 + ;; + ld8.fill r26=[r2],-16 // r26 + ld8.fill r25=[r3],-16 // r25 + ;; + ld8.fill r24=[r2],-16 // r24 + ld8.fill r23=[r3],-16 // r23 + ;; + ld8.fill r22=[r2],-16 // r22 + ld8.fill r21=[r3],-16 // r21 + ;; + ld8.fill r20=[r2],-16 // r20 + ld8.fill r19=[r3],-16 // r19 + ;; + ld8.fill r18=[r2],-16 // r18 + ld8.fill r17=[r3],-16 // r17 + ;; + +{ .mmb + ld8.fill r16=[r2],-16 // r16 + ld8.fill r15=[r3],-16 // r15 + bsw.0 + ;; +} +{ .mmi + ld8.fill r14=[r2],-16 // r14 + ld8.fill r11=[r3],-16 // r11 + add r31=16,sp + ;; +} +{ .mmi + ld8.fill r10=[r2],-16 // r10 + ld8.fill r9=[r3],-16 // r9 + add r30=24,sp + ;; +} + + ld8.fill r8=[r2],-16 // r8 + ld8.fill r3=[r3] // r3 + ;; + ld8.fill r2=[r2] // r2 + ld8.fill sp=[r31],16 // sp + ;; + ld8 r16=[r30],16 // unat + ld8 r17=[r31],16 // rp + ;; + ld8 r18=[r30],16 // pr + ld8 r19=[r31],16 // pfs + mov rp=r17 + ;; + ld8 r20=[r30],24 // bspstore + ld8 r21=[r31],24 // rnat + ;; + ld8.fill r29=[r30],16 // tp + ld8 r22=[r31],16 // rsc + ;; + ld8 r23=[r30],16 // fpsr + ld8 r24=[r31],16 // psr + ;; + ld8.fill r1=[r30],16 // gp + ld8 r25=[r31],16 // ndirty + ;; + ld8 r26=[r30] // cfm + ld8 r27=[r31] // ip + ;; + // Switch register stack +#if 0 + alloc r31=ar.pfs,0,0,0,0 // discard current frame + shl r30=r25,16 // value for ar.rsc + ;; + mov ar.rsc=r30 // setup for loadrs + ;; + loadrs // load user regs + ;; + mov ar.bspstore=r20 + ;; + mov ar.rnat=r21 +#endif + + // Don't restore r13 if returning to kernel + + mov ar.unat=r16 + mov ar.pfs=r19 + mov ar.fpsr=r23 + mov cr.ipsr=r24 + mov cr.ifs=r26 + mov cr.iip=r27 + ;; + +{ .mib + mov ar.rsc=r22 + mov pr=r18,0x1fffe + rfi + ;; +} +END(exception_restore) + /* * Call exception_save_regs to preserve the interrupted state in a * trapframe. Note that we don't use a call instruction because we @@ -47,12 +533,12 @@ * resume it. */ #define TRAP(_n_) \ -1: mov r17=ip;; \ - add r17=2f-1b,r17; \ - mov r16=b6;; \ - mov b6=r17; \ - br.sptk.few exception_save; \ -2: (p3) ssm psr.i; \ +{ .mib ; \ + nop _n_ ; \ + mov r16=ip ; \ + br.sptk.few exception_save ; \ +} ; \ +(p3) ssm psr.i; \ alloc r15=ar.pfs,0,0,3,0; \ mov out0=_n_; \ mov out1=r14; \ @@ -519,16 +1005,17 @@ IVT_END(Break_Instruction) IVT_ENTRY(External_Interrupt, 0x3000) - mov r16=b6 // save user's b6 -1: mov r17=ip;; // construct return address - add r17=2f-1b,r17;; // for exception_save - mov b6=r17 - br.sptk.few exception_save // 'call' exception_save - +{ .mib + nop 12 + mov r16=ip + br.sptk exception_save + ;; +} +{ .mmi 2: alloc r14=ar.pfs,0,0,2,0 // make a frame for calling with - - mov out1=sp;; - add sp=-16,sp;; + mov out1=sp + add sp=-16,sp +} 3: mov out0=cr.ivr // find interrupt vector ;; @@ -538,17 +1025,16 @@ ssm psr.i // re-enable interrupts ;; // now that we are in-progress srlz.d + br.call.sptk.many rp=interrupt // call high-level handler ;; - br.call.sptk.many rp=interrupt // call high-level handler - rsm psr.i // disable interrupts ;; srlz.d - ;; mov cr.eoi=r0 // and ack the interrupt ;; srlz.d br.sptk.few 3b // loop for more + ;; IVT_END(External_Interrupt) IVT_ENTRY(Reserved_3400, 0x3400) @@ -770,705 +1256,3 @@ IVT_ENTRY(Reserved_7f00, 0x7f00) TRAP(67) IVT_END(Reserved_7f00) - - .text - -/* - * exception_restore: restore interrupted state - * - * Arguments: - * sp+16 trapframe pointer - * r4 ar.pfs before the alloc in TRAP() - * - */ -ENTRY(exception_restore, 0) -{ .mfi - alloc r14=ar.pfs,0,0,1,0 // in case we call ast() - nop 1 - add r3=TF_SPECIAL_PSR+16,sp - ;; -} -{ .mmi - ld8 r30=[r3] // ipsr - ;; - nop 2 - extr.u r16=r30,32,2 // extract ipsr.cpl - ;; -} -{ .mfb - cmp.eq p1,p2=r0,r16 // test for return to kernel mode - nop 3 -(p1) br.cond.dpnt 2f // no ast check for returns to kernel -} -3: -{ .mmi - add r3=PC_CURTHREAD,r13 // &curthread - ;; - ld8 r3=[r3] // curthread - add r2=(TDF_ASTPENDING|TDF_NEEDRESCHED),r0 - ;; -} -{ .mmb - mov r15=psr // save interrupt enable status - nop 4 - ;; -} -{ .mmi - ;; - rsm psr.i // disable interrupts - add r3=TD_FLAGS,r3 // &curthread->td_flags - ;; -} -{ .mmi - ld4 r14=[r3] // fetch curthread->td_flags - ;; - and r14=r2,r14 // flags & (TDF_ASTPENDING|TDF_NEEDRESCHED) - nop 5 - ;; -} -{ .mfb >>> TRUNCATED FOR MAIL (1000 lines) <<<