summaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel/misc.S
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-06-13 16:29:25 +0000
commitdb7d4daea91e105e3859cf461d7e53b9b77454b2 (patch)
tree9bb65b95440af09e8aca63abe56970dd3360cc57 /arch/ppc/kernel/misc.S
parent9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff)
Merge with Linux 2.2.8.
Diffstat (limited to 'arch/ppc/kernel/misc.S')
-rw-r--r--arch/ppc/kernel/misc.S71
1 files changed, 66 insertions, 5 deletions
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index e4589b1e0..cbeb4ffce 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -36,6 +36,7 @@
* Returns (address we're running at) - (address we were linked at)
* for use before the text and data are mapped to KERNELBASE.
*/
+
_GLOBAL(reloc_offset)
mflr r0
bl 1f
@@ -72,8 +73,8 @@ _GLOBAL(_enable_interrupts)
beqlr /* nothing to do if state == 0 */
_GLOBAL(__sti)
_GLOBAL(_hard_sti)
- lis r4,n_lost_interrupts@ha
- lwz r4,n_lost_interrupts@l(r4)
+ lis r4,ppc_n_lost_interrupts@ha
+ lwz r4,ppc_n_lost_interrupts@l(r4)
mfmsr r3 /* Get current state */
ori r3,r3,MSR_EE /* Turn on 'EE' bit */
cmpi 0,r4,0 /* lost interrupts to process first? */
@@ -93,8 +94,8 @@ do_lost_interrupts:
stw r0,20(r1)
stw r3,8(r1)
1: bl fake_interrupt
- lis r4,n_lost_interrupts@ha
- lwz r4,n_lost_interrupts@l(r4)
+ lis r4,ppc_n_lost_interrupts@ha
+ lwz r4,ppc_n_lost_interrupts@l(r4)
cmpi 0,r4,0
bne- 1b
lwz r3,8(r1)
@@ -105,11 +106,31 @@ do_lost_interrupts:
addi r1,r1,16
blr
+
+/*
+ * complement mask on the msr then "or" some values on.
+ * _nmask_and_or_msr(nmask, value_to_or)
+ */
+ _GLOBAL(_nmask_and_or_msr)
+ mfmsr r0 /* Get current msr */
+ andc r0,r0,r3 /* And off the bits set in r3 (first parm) */
+ or r0,r0,r4 /* Or on the bits in r4 (second parm) */
+ sync /* Some chip revs have problems here... */
+ mtmsr r0 /* Update machine state */
+ blr /* Done */
+
+
/*
* Flush MMU TLB
*/
_GLOBAL(_tlbia)
+ sync
tlbia
+ sync
+#ifdef __SMP__
+ tlbsync
+ sync
+#endif
blr
/*
@@ -117,11 +138,17 @@ _GLOBAL(_tlbia)
*/
_GLOBAL(_tlbie)
tlbie r3
+ sync
+#ifdef __SMP__
+ tlbsync
+ sync
+#endif
blr
+
/*
* Atomic [test&set] exchange
*
- * void *xchg_u32(void *ptr, unsigned long val)
+ * unsigned long xchg_u32(void *ptr, unsigned long val)
* Changes the memory location '*ptr' to be val and returns
* the previous value stored there.
*/
@@ -133,6 +160,27 @@ _GLOBAL(xchg_u32)
blr
/*
+ * Try to acquire a spinlock.
+ * Only does the stwcx. if the load returned 0 - the Programming
+ * Environments Manual suggests not doing unnecessary stcwx.'s
+ * since they may inhibit forward progress by other CPUs in getting
+ * a lock.
+ */
+_GLOBAL(__spin_trylock)
+ mr r4,r3
+ eieio /* prevent reordering of stores */
+ li r5,-1
+ lwarx r3,0,r4 /* fetch old value, establish reservation */
+ cmpwi 0,r3,0 /* is it 0? */
+ bnelr- /* return failure if not */
+ stwcx. r5,0,r4 /* try to update with new value */
+ bne- 1f /* if we failed */
+ eieio /* prevent reordering of stores */
+ blr
+1: li r3,1 /* return non-zero for failure */
+ blr
+
+/*
* Atomic add/sub/inc/dec operations
*
* void atomic_add(int c, int *v)
@@ -590,6 +638,16 @@ cvt_df:
stfd 0,-4(r5)
blr
+ .globl __clear_msr_me
+__clear_msr_me:
+ mfmsr r0 /* Get current interrupt state */
+ lis r3,0
+ ori r3,r3,MSR_ME
+ andc r0,r0,r3 /* Clears bit in (r4) */
+ sync /* Some chip revs have problems here */
+ mtmsr r0 /* Update machine state */
+ blr
+
/*
* Fetch the current SR register
* get_SR(int index)
@@ -608,6 +666,8 @@ _GLOBAL(__kernel_thread)
sc
cmpi 0,r3,0 /* parent or child? */
bnelr /* return if parent */
+ li r0,0 /* clear out p->tss.regs */
+ stw r0,TSS+PT_REGS(r2) /* since we don't have user ctx */
mtlr r4 /* fn addr in lr */
mr r3,r5 /* load arg and call fn */
blrl
@@ -836,4 +896,5 @@ sys_call_table:
.long sys_sendfile
.long sys_ni_syscall /* streams1 */
.long sys_ni_syscall /* streams2 */
+ .long sys_vfork
.space (NR_syscalls-183)*4