patch-2.2.0-pre2 linux/arch/ppc/kernel/head.S

Next file: linux/arch/ppc/kernel/idle.c
Previous file: linux/arch/ppc/defconfig
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.0-pre1/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
@@ -1,7 +1,7 @@
 /*
  *  arch/ppc/kernel/head.S
  *
- *  $Id: head.S,v 1.113 1998/12/02 18:41:00 cort Exp $
+ *  $Id: head.S,v 1.114 1998/12/28 10:28:45 paulus Exp $
  *
  *  PowerPC version 
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -532,9 +532,10 @@
 
 	stw	r3,(_CCR+4)(r21);
 #endif
-	addi	r3,r1,STACK_FRAME_OVERHEAD;
-	li	r20,MSR_KERNEL;
-	bl	transfer_to_handler;
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	li	r4,0
+	bl	transfer_to_handler
 	.long	do_IRQ;
 	.long	int_return
 	
@@ -1199,12 +1200,6 @@
  * physical address of the hash table are known.  These definitions
  * of Hash_base and Hash_bits below are just an example.
  */
-/*
- * Note that the 603s won't come here, since the 603
- * loads tlb directly into the tlb from the linux tables, while
- * others (601, 604, etc.) call hash_page() to load entries from
- * the linux tables into the hash table.  -- Cort
- */	
 Hash_base = 0x180000
 Hash_bits = 12				/* e.g. 256kB hash table */
 Hash_msk = (((1 << Hash_bits) - 1) * 64)
@@ -1219,11 +1214,19 @@
 	lis	r2,hash_table_lock@h
 	ori	r2,r2,hash_table_lock@l
 	tophys(r2,r2,r6)
+	lis	r6,100000000@h
+	mtctr	r6
+	lwz	r0,PROCESSOR-TSS(r5)
+	or	r0,r0,r6
 10:	lwarx	r6,0,r2
-	stwcx.	r2,0,r2
-	bne-	10b
-	cmpi	0,0,r6,0
-	bne	10b
+	cmpi	0,r6,0
+	bne-	12f
+	stwcx.	r0,0,r2
+	beq+	11f
+12:	cmpw	r6,r0
+	bdnzf	2,10b
+	tw	31,31,31
+11:
 #endif
 	/* Get PTE (linux-style) and check access */
 	lwz	r5,PG_TABLES(r5)		
@@ -1271,6 +1274,9 @@
 	li	r2,8			/* PTEs/group */
 	bne	10f			/* no PTE: go look for an empty slot */
 	tlbie	r3			/* invalidate TLB entry */
+#ifdef __SMP__
+	tlbsync
+#endif
 
 	/* Search the primary PTEG for a PTE whose 1st word matches r5 */
 	mtctr	r2
@@ -1315,7 +1321,6 @@
 	bdnzf	2,2b
 	beq+	found_empty
 
-#if 1
 	/*
 	 * Choose an arbitrary slot in the primary PTEG to overwrite.
 	 * Since both the primary and secondary PTEGs are full, and we
@@ -1331,26 +1336,6 @@
 	andi.	r2,r2,0x38
 	stw	r2,next_slot@l(0)
 	add	r3,r4,r2
-#else
-	/* now, allow 2nd hash as well as 1st */
-	lwz	r2,next_slot@l(0)
-	addi	r2,r2,8
-	andi.	r2,r2,0x78
-	stw	r2,next_slot@l(0)
-	cmpi	0,0,r2,0x38             /* if it's the 2nd hash */
-	bgt	second_evict
-first_evict:
-	xori	r5,r5,0x40		/* clear H bit again */
-	add	r3,r4,r2
-	b	11f
-second_evict:
-	.globl	hash_page_patch_D
-hash_page_patch_D:	
-	xoris	r3,r4,Hash_msk>>16	/* compute secondary hash */
-	xori	r3,r3,0xffc0
-	subi	r2,r2,0x40
-	addi	r3,r3,r2
-#endif
 11:		
 	/* update counter of evicted pages */
 	lis	r2,htab_evicts@h
@@ -1390,6 +1375,13 @@
 	addi	r3,r3,1
 	stw	r3,0(r2)
 
+#ifdef __SMP__
+	lis	r2,hash_table_lock@ha
+	tophys(r2,r2,r6)
+	li	r0,0
+	stw	r0,hash_table_lock@l(r2)
+#endif
+
 	/* Return from the exception */
 	lwz	r3,_CCR(r21)
 	lwz	r4,_LINK(r21)
@@ -1397,13 +1389,6 @@
 	mtcrf	0xff,r3
 	mtlr	r4
 	mtctr	r5
-#ifdef __SMP__
-	lis	r2,hash_table_lock@h
-	ori	r2,r2,hash_table_lock@l
-	tophys(r2,r2,r6)
-	li	r6,0
-	stw	r6,0(r2)
-#endif		
 	REST_GPR(0, r21)
 	REST_2GPRS(1, r21)
 	REST_4GPRS(3, r21)
@@ -1418,11 +1403,10 @@
 	
 hash_page_out:
 #ifdef __SMP__
-	lis	r2,hash_table_lock@h
-	ori	r2,r2,hash_table_lock@l
+	lis	r2,hash_table_lock@ha
 	tophys(r2,r2,r6)
-	li	r6,0
-	stw	r6,0(r2)
+	li	r0,0
+	stw	r0,hash_table_lock@l(r2)
 #endif		
 	blr
 next_slot:
@@ -1741,6 +1725,9 @@
 2:
 	SYNC			/* Force all PTE updates to finish */
 	tlbia			/* Clear all TLB entries */
+#ifdef __SMP__
+	tlbsync
+#endif
 #ifndef CONFIG_8xx
 	mtspr	SDR1,r6
 	li	r0,16		/* load up segment register values */
@@ -2012,16 +1999,13 @@
 
 /* FALL THROUGH into int_return */
 #ifdef __SMP__
-	/* drop scheduler_lock since we weren't called by schedule() */
+	/* call schedule_tail if this is the first time for a child process */
 	lwz	r5,TSS_SMP_FORK_RET(r4)
 	cmpi	0,r5,0
 	beq+	int_return
 	li	r3,0
-	lis	r5,scheduler_lock@ha
 	stw	r3,TSS_SMP_FORK_RET(r4)
-	stw	r3,scheduler_lock@l+4(r5)	/* owner_pc */
-	stw	r3,scheduler_lock@l+8(r5)	/* owner_cpu */
-	stw	r3,scheduler_lock@l(r5)		/* lock */
+	bl	schedule_tail
 #endif /* __SMP__ */
 
 /*
@@ -2121,6 +2105,7 @@
 	li	r0,0x0fac
 	stw	r0,TRAP(r1)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r4,1
 	bl	do_IRQ
 	addi	r1,r1,INT_FRAME_SIZE+STACK_UNDERHEAD
 	lwz	r0,4(r1)
@@ -2227,15 +2212,6 @@
  */
 #ifndef CONFIG_8xx	
 _GLOBAL(flush_hash_segments)
-#ifdef __SMP__
-	lis	r9,hash_table_lock@h
-	ori	r9,r9,hash_table_lock@l
-10:	lwarx	r6,0,r9
-	stwcx.	r9,0,r9
-	bne-	10b
-	cmpi	0,0,r6,0
-	bne	10b
-#endif
 #ifdef NO_RELOAD_HTAB
 /*
  * Bitmask of PVR numbers of 603-like chips,
@@ -2247,8 +2223,31 @@
 	rlwinm	r0,r0,16,27,31
 	lis	r9,PVR_603_LIKE@h
 	rlwnm.	r0,r9,r0,0,0
-	bne	99f
+	beq+	99f
+	tlbia
+	isync
+	blr
+99:
 #endif /* NO_RELOAD_HTAB */
+#ifdef __SMP__
+	/* Note - we had better not do anything which could generate
+	   a hash table miss while we have the hash table locked,
+	   or we'll get a deadlock.  -paulus */
+	mfmsr	r10
+	sync
+	rlwinm	r0,r10,0,17,15	/* clear bit 16 (MSR_EE) */
+	mtmsr	r0
+	SYNC
+	lis	r9,hash_table_lock@h
+	ori	r9,r9,hash_table_lock@l
+	lwz	r8,PROCESSOR(r2)
+	oris	r8,r8,8
+10:	lwarx	r6,0,r9
+	cmpi	0,r6,0
+	bne-	10b
+	stwcx.	r8,0,r9
+	bne-	10b
+#endif
 	rlwinm	r3,r3,7,1,24		/* put VSID lower limit in position */
 	oris	r3,r3,0x8000		/* set V bit */
 	rlwinm	r4,r4,7,1,24		/* put VSID upper limit in position */
@@ -2270,14 +2269,16 @@
 	stw	r0,0(r5)		/* invalidate entry */
 2:	bdnz	1b			/* continue with loop */
 	sync
-99:	tlbia
+	tlbia
 	isync
 #ifdef __SMP__
-	lis	r3,hash_table_lock@h
-	ori	r3,r3,hash_table_lock@l
-	li	r6,0
-	stw	r6,0(r3)
-#endif		
+	tlbsync
+	lis	r3,hash_table_lock@ha
+	li	r0,0
+	stw	r0,hash_table_lock@l(r3)
+	mtmsr	r10
+	SYNC
+#endif
 	blr
 
 /*
@@ -2286,22 +2287,36 @@
  * flush_hash_page(unsigned context, unsigned long va)
  */
 _GLOBAL(flush_hash_page)
-#ifdef __SMP__
-	lis	r9,hash_table_lock@h
-	ori	r9,r9,hash_table_lock@l
-10:	lwarx	r6,0,r9
-	stwcx.	r9,0,r9
-	bne-	10b
-	cmpi	0,0,r6,0
-	bne	10b
-#endif
 #ifdef NO_RELOAD_HTAB
 	mfspr	r0,PVR
 	rlwinm	r0,r0,16,27,31
 	lis	r9,PVR_603_LIKE@h
 	rlwnm.	r0,r9,r0,0,0
-	bne	99f
+	beq+	99f
+	tlbie	r4			/* in hw tlb too */
+	isync
+	blr
+99:
 #endif /* NO_RELOAD_HTAB */		
+#ifdef __SMP__
+	/* Note - we had better not do anything which could generate
+	   a hash table miss while we have the hash table locked,
+	   or we'll get a deadlock.  -paulus */
+	mfmsr	r10
+	sync
+	rlwinm	r0,r10,0,17,15		/* clear bit 16 (MSR_EE) */
+	mtmsr	r0
+	SYNC
+	lis	r9,hash_table_lock@h
+	ori	r9,r9,hash_table_lock@l
+	lwz	r8,PROCESSOR(r2)
+	oris	r8,r8,9
+10:	lwarx	r6,0,r9
+	cmpi	0,r6,0
+	bne-	10b
+	stwcx.	r8,0,r9
+	bne-	10b
+#endif
 	rlwinm	r3,r3,11,1,20		/* put context into vsid */
 	rlwimi	r3,r4,11,21,24		/* put top 4 bits of va into vsid */
 	oris	r3,r3,0x8000		/* set V (valid) bit */
@@ -2334,16 +2349,19 @@
 3:	li	r0,0
 	stw	r0,0(r7)		/* invalidate entry */
 4:	sync
-99:	tlbie	r4			/* in hw tlb too */
+	tlbie	r4			/* in hw tlb too */
 	isync
 #ifdef __SMP__
+	tlbsync
 	lis	r3,hash_table_lock@h
-	ori	r3,r3,hash_table_lock@l
-	li	r6,0
-	stw	r6,0(r3)
-#endif		
+	li	r0,0
+	stw	r0,hash_table_lock@l(r3)
+	mtmsr	r10
+	SYNC
+#endif
 	blr
 #endif /* CONFIG_8xx */
+
 /*
  * This routine is just here to keep GCC happy - sigh...
  */	

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov