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
- Lines: 329
- Date:
Wed Dec 30 10:55:07 1998
- Orig file:
v2.2.0-pre1/linux/arch/ppc/kernel/head.S
- Orig date:
Tue Dec 22 14:16:54 1998
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