diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-06-13 16:29:25 +0000 |
commit | db7d4daea91e105e3859cf461d7e53b9b77454b2 (patch) | |
tree | 9bb65b95440af09e8aca63abe56970dd3360cc57 /arch/ppc/kernel/misc.S | |
parent | 9c1c01ead627bdda9211c9abd5b758d6c687d8ac (diff) |
Merge with Linux 2.2.8.
Diffstat (limited to 'arch/ppc/kernel/misc.S')
-rw-r--r-- | arch/ppc/kernel/misc.S | 71 |
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 |