patch-2.4.0-test2 linux/arch/ia64/kernel/ivt.S

Next file: linux/arch/ia64/kernel/mca.c
Previous file: linux/arch/ia64/kernel/irq_ia64.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/arch/ia64/kernel/ivt.S linux/arch/ia64/kernel/ivt.S
@@ -170,9 +170,31 @@
 	 * The ITLB basically does the same as the VHPT handler except
 	 * that we always insert exactly one instruction TLB entry.
 	 */
+#if 0
+	/*
+	 * This code works, but I don't want to enable it until I have numbers
+	 * that prove this to be a win.
+	 */
+	mov r31=pr				// save predicates
+	;;
+	thash r17=r16				// compute virtual address of L3 PTE
+	;;
+	ld8.s r18=[r17]				// try to read L3 PTE
+	;;
+	tnat.nz p6,p0=r18			// did read succeed?
+(p6)	br.cond.spnt.many 1f
+	;;
+	itc.i r18
+	;;
+	mov pr=r31,-1
+	rfi
+
+1:	rsm psr.dt				// use physical addressing for data
+#else
 	mov r16=cr.ifa				// get address that caused the TLB miss
 	;;
 	rsm psr.dt				// use physical addressing for data
+#endif
 	mov r31=pr				// save the predicate registers
 	mov r19=ar.k7				// get page table base address
 	shl r21=r16,3				// shift bit 60 into sign bit
@@ -222,9 +244,31 @@
 	 * that we always insert exactly one data TLB entry.
 	 */
 	mov r16=cr.ifa				// get address that caused the TLB miss
+#if 0
+	/*
+	 * This code works, but I don't want to enable it until I have numbers
+	 * that prove this to be a win.
+	 */
+	mov r31=pr				// save predicates
+	;;
+	thash r17=r16				// compute virtual address of L3 PTE
+	;;
+	ld8.s r18=[r17]				// try to read L3 PTE
+	;;
+	tnat.nz p6,p0=r18			// did read succeed?
+(p6)	br.cond.spnt.many 1f
+	;;
+	itc.d r18
 	;;
+	mov pr=r31,-1
+	rfi
+
+1:	rsm psr.dt				// use physical addressing for data
+#else
 	rsm psr.dt				// use physical addressing for data
 	mov r31=pr				// save the predicate registers
+	;;
+#endif
 	mov r19=ar.k7				// get page table base address
 	shl r21=r16,3				// shift bit 60 into sign bit
 	shr.u r17=r16,61			// get the region number into r17
@@ -265,37 +309,6 @@
 	mov pr=r31,-1				// restore predicate registers
 	rfi
 
-	//-----------------------------------------------------------------------------------
-	// call do_page_fault (predicates are in r31, psr.dt is off, r16 is faulting address)
-page_fault:
-	SAVE_MIN_WITH_COVER
-	//
-	// Copy control registers to temporary registers, then turn on psr bits,
-	// then copy the temporary regs to the output regs.  We have to do this
-	// because the "alloc" can cause a mandatory store which could lead to
-	// an "Alt DTLB" fault which we can handle only if psr.ic is on.
-	//
-	mov r8=cr.ifa
-	mov r9=cr.isr
-	adds r3=8,r2				// set up second base pointer
-	;;
-	ssm psr.ic | psr.dt
-	;;
-	srlz.i					// guarantee that interrupt collection is enabled
-	;;
-(p15)	ssm psr.i				// restore psr.i
-	movl r14=ia64_leave_kernel
-	;;
-	alloc r15=ar.pfs,0,0,3,0		// must be first in insn group
-	mov out0=r8
-	mov out1=r9
-	;;
-	SAVE_REST
-	mov rp=r14
-	;;
-	adds out2=16,r12			// out2 = pointer to pt_regs
-	br.call.sptk.few b6=ia64_do_page_fault	// ignore return address
-
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19)
@@ -303,7 +316,7 @@
 	movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RX
 	;;
 	shr.u r18=r16,57	// move address bit 61 to bit 4
-	dep r16=0,r16,IA64_PHYS_BITS,(64-IA64_PHYS_BITS) // clear ed, resvd, and unimpl. phys bits
+	dep r16=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS)	// clear ed & reserved bits
 	;;
 	andcm r18=0x10,r18	// bit 4=~address-bit(61)
 	dep r16=r17,r16,0,12	// insert PTE control bits into r16
@@ -318,18 +331,58 @@
 // 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46)
 	mov r16=cr.ifa		// get address that caused the TLB miss
 	movl r17=__DIRTY_BITS|_PAGE_PL_0|_PAGE_AR_RW
+	mov r20=cr.isr
+	mov r21=cr.ipsr
+	mov r19=pr
 	;;
+	tbit.nz p6,p7=r20,IA64_ISR_SP_BIT	// is speculation bit on?
 	shr.u r18=r16,57	// move address bit 61 to bit 4
-	dep r16=0,r16,IA64_PHYS_BITS,(64-IA64_PHYS_BITS) // clear ed, resvd, and unimpl. phys bits
+	dep r16=0,r16,IA64_MAX_PHYS_BITS,(64-IA64_MAX_PHYS_BITS) // clear ed & reserved bits
 	;;
+	dep r21=-1,r21,IA64_PSR_ED_BIT,1
 	andcm r18=0x10,r18	// bit 4=~address-bit(61)
 	dep r16=r17,r16,0,12	// insert PTE control bits into r16
 	;;
 	or r16=r16,r18		// set bit 4 (uncached) if the access was to region 6
+(p6)	mov cr.ipsr=r21
 	;;
-	itc.d r16		// insert the TLB entry
+(p7)	itc.d r16		// insert the TLB entry
+	mov pr=r19,-1
 	rfi
 
+	;;
+
+	//-----------------------------------------------------------------------------------
+	// call do_page_fault (predicates are in r31, psr.dt is off, r16 is faulting address)
+page_fault:
+	SAVE_MIN_WITH_COVER
+	//
+	// Copy control registers to temporary registers, then turn on psr bits,
+	// then copy the temporary regs to the output regs.  We have to do this
+	// because the "alloc" can cause a mandatory store which could lead to
+	// an "Alt DTLB" fault which we can handle only if psr.ic is on.
+	//
+	mov r8=cr.ifa
+	mov r9=cr.isr
+	adds r3=8,r2				// set up second base pointer
+	;;
+	ssm psr.ic | psr.dt
+	;;
+	srlz.i					// guarantee that interrupt collection is enabled
+	;;
+(p15)	ssm psr.i				// restore psr.i
+	movl r14=ia64_leave_kernel
+	;;
+	alloc r15=ar.pfs,0,0,3,0		// must be first in insn group
+	mov out0=r8
+	mov out1=r9
+	;;
+	SAVE_REST
+	mov rp=r14
+	;;
+	adds out2=16,r12			// out2 = pointer to pt_regs
+	br.call.sptk.few b6=ia64_do_page_fault	// ignore return address
+
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45)
@@ -338,7 +391,7 @@
 	// Access-bit, or Data Access-bit faults cause a nested fault because the
 	// dTLB entry for the virtual page table isn't present.  In such a case,
 	// we lookup the pte for the faulting address by walking the page table
-	// and return to the contination point passed in register r30.
+	// and return to the continuation point passed in register r30.
 	// In accessing the page tables, we don't need to check for NULL entries
 	// because if the page tables didn't map the faulting address, it would not
 	// be possible to receive one of the above faults.
@@ -441,9 +494,6 @@
 	tbit.z p6,p0=r17,IA64_PSR_IS_BIT	// IA64 instruction set?
 	;;
 (p6)	mov r16=r18				// if so, use cr.iip instead of cr.ifa
-#if 0
-	;;
-#endif
 	mov pr=r31,-1
 #endif /* CONFIG_ITANIUM */
 	movl r30=1f				// load continuation point in case of nested fault
@@ -489,7 +539,6 @@
 	;;
 	srlz.d			// ensure everyone knows psr.dt is off...
 	cmp.eq p0,p7=r16,r17	// is this a system call? (p7 <- false, if so)
-
 #if 1
 	// Allow syscalls via the old system call number for the time being.  This is
 	// so we can transition to the new syscall number in a relatively smooth
@@ -498,7 +547,6 @@
 	;;
 (p7)	cmp.eq.or.andcm p0,p7=r16,r17		// is this the old syscall number?
 #endif
-
 (p7)	br.cond.spnt.many non_syscall
 
 	SAVE_MIN				// uses r31; defines r2:
@@ -575,13 +623,12 @@
 	ssm psr.ic | psr.dt	// turn interrupt collection and data translation back on
 	;;
 	adds r3=8,r2		// set up second base pointer for SAVE_REST
-	cmp.eq pEOI,p0=r0,r0	// set pEOI flag so that ia64_leave_kernel writes cr.eoi
 	srlz.i			// ensure everybody knows psr.ic and psr.dt are back on
 	;;
 	SAVE_REST
 	;;
 	alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group
-#ifdef	CONFIG_ITANIUM_ASTEP_SPECIFIC
+#ifdef CONFIG_ITANIUM_A1_SPECIFIC
 	mov out0=r0		// defer reading of cr.ivr to handle_irq...
 #else
 	mov out0=cr.ivr		// pass cr.ivr as first arg
@@ -609,6 +656,50 @@
 // 0x3c00 Entry 15 (size 64 bundles) Reserved
 	FAULT(15)
 
+//
+//  Squatting in this space ...
+//
+//  This special case dispatcher for illegal operation faults
+//  allows preserved registers to be modified through a 
+//  callback function (asm only) that is handed back from
+//  the fault handler in r8. Up to three arguments can be
+//  passed to the callback function by returning an aggregate
+//  with the callback as its first element, followed by the
+//  arguments.
+//
+dispatch_illegal_op_fault:
+	SAVE_MIN_WITH_COVER
+	//
+	// The "alloc" can cause a mandatory store which could lead to
+	// an "Alt DTLB" fault which we can handle only if psr.ic is on.
+	//
+	ssm psr.ic | psr.dt
+	;;
+	srlz.i		// guarantee that interrupt collection is enabled
+	;;
+(p15)	ssm psr.i	// restore psr.i
+	adds r3=8,r2	// set up second base pointer for SAVE_REST
+	;;
+	alloc r14=ar.pfs,0,0,1,0	// must be first in insn group
+	mov out0=ar.ec
+	;;
+	SAVE_REST
+	;;
+	br.call.sptk.few rp=ia64_illegal_op_fault
+	;;
+	alloc r14=ar.pfs,0,0,3,0	// must be first in insn group
+	mov out0=r9
+	mov out1=r10
+	mov out2=r11
+	movl r15=ia64_leave_kernel
+	;;
+	mov rp=r15
+	mov b6=r8
+	;;
+	cmp.ne p6,p0=0,r8
+(p6)	br.call.dpnt b6=b6		// call returns to ia64_leave_kernel
+	br.sptk ia64_leave_kernel
+
 	.align 1024
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4000 Entry 16 (size 64 bundles) Reserved
@@ -643,14 +734,17 @@
 (p6)    br.call.dpnt.few b6=non_ia32_syscall
 
 	adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp	// 16 byte hole per SW conventions
-
+	adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
+	;;
+	cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
+	st8 [r15]=r8		// save orignal EAX in r1 (IA32 procs don't use the GP)
 	;;
 	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
 	;; 
 	ld4 r8=[r14],8          // r8 == EAX (syscall number)
-	mov r15=0xff
+	mov r15=190		// sys_vfork - last implemented system call
 	;;
-	cmp.ltu.unc p6,p7=r8,r15
+	cmp.leu.unc p6,p7=r8,r15
 	ld4 out1=[r14],8        // r9 == ecx
 	;;
 	ld4 out2=[r14],8         // r10 == edx
@@ -868,7 +962,16 @@
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x5400 Entry 24 (size 16 bundles) General Exception (5,32,34,36,38,39)
-	FAULT(24)
+	mov r16=cr.isr
+	mov r31=pr
+	rsm psr.dt		// avoid nested faults due to TLB misses...
+	;;
+	srlz.d			// ensure everyone knows psr.dt is off...
+	cmp4.eq p6,p0=0,r16
+(p6)	br.sptk dispatch_illegal_op_fault
+	;;
+	mov r19=24		// fault number
+	br.cond.sptk.many dispatch_to_fault_handler
 
 	.align 256
 /////////////////////////////////////////////////////////////////////////////////////////
@@ -939,7 +1042,6 @@
 	mov r31=pr		// prepare to save predicates
 	;;									
 	srlz.d			// ensure everyone knows psr.dt is off
-	mov r19=30		// error vector for fault_handler (when kernel)
 	br.cond.sptk.many dispatch_unaligned_handler
 
 	.align 256

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)