linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / powerpc / kernel / misc_64.S
index e3ed21c..2778cce 100644 (file)
@@ -1,12 +1,14 @@
 /*
+ *  arch/powerpc/kernel/misc64.S
+ *
  * This file contains miscellaneous low-level functions.
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
  * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
  * and Paul Mackerras.
  * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
- * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
- *
+ * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) 
+ * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version
@@ -14,6 +16,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/sys.h>
 #include <asm/unistd.h>
 #include <asm/errno.h>
 
        .text
 
+/*
+ * Returns (address we are 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
+1:     mflr    r3
+       LOAD_REG_IMMEDIATE(r4,1b)
+       subf    r3,r4,r3
+       mtlr    r0
+       blr
+
+/*
+ * add_reloc_offset(x) returns x + reloc_offset().
+ */
+_GLOBAL(add_reloc_offset)
+       mflr    r0
+       bl      1f
+1:     mflr    r5
+       LOAD_REG_IMMEDIATE(r4,1b)
+       subf    r5,r4,r5
+       add     r3,r3,r5
+       mtlr    r0
+       blr
+
 _GLOBAL(get_msr)
        mfmsr   r3
        blr
 
+_GLOBAL(get_dar)
+       mfdar   r3
+       blr
+
 _GLOBAL(get_srr0)
        mfsrr0  r3
        blr
@@ -38,6 +72,10 @@ _GLOBAL(get_srr0)
 _GLOBAL(get_srr1)
        mfsrr1  r3
        blr
+       
+_GLOBAL(get_sp)
+       mr      r3,r1
+       blr
 
 #ifdef CONFIG_IRQSTACKS
 _GLOBAL(call_do_softirq)
@@ -51,20 +89,60 @@ _GLOBAL(call_do_softirq)
        mtlr    r0
        blr
 
-_GLOBAL(call_handle_irq)
-       ld      r8,0(r7)
+_GLOBAL(call___do_IRQ)
        mflr    r0
        std     r0,16(r1)
-       mtctr   r8
-       stdu    r1,THREAD_SIZE-112(r6)
-       mr      r1,r6
-       bctrl
+       stdu    r1,THREAD_SIZE-112(r5)
+       mr      r1,r5
+       bl      .__do_IRQ
        ld      r1,0(r1)
        ld      r0,16(r1)
        mtlr    r0
        blr
 #endif /* CONFIG_IRQSTACKS */
 
+       /*
+ * To be called by C code which needs to do some operations with MMU
+ * disabled. Note that interrupts have to be disabled by the caller
+ * prior to calling us. The code called _MUST_ be in the RMO of course
+ * and part of the linear mapping as we don't attempt to translate the
+ * stack pointer at all. The function is called with the stack switched
+ * to this CPU emergency stack
+ *
+ * prototype is void *call_with_mmu_off(void *func, void *data);
+ *
+ * the called function is expected to be of the form
+ *
+ * void *called(void *data); 
+ */
+_GLOBAL(call_with_mmu_off)
+       mflr    r0                      /* get link, save it on stackframe */
+       std     r0,16(r1)
+       mr      r1,r5                   /* save old stack ptr */
+       ld      r1,PACAEMERGSP(r13)     /* get emerg. stack */
+       subi    r1,r1,STACK_FRAME_OVERHEAD
+       std     r0,16(r1)               /* save link on emerg. stack */
+       std     r5,0(r1)                /* save old stack ptr in backchain */
+       ld      r3,0(r3)                /* get to real function ptr (assume same TOC) */
+       bl      2f                      /* we need LR to return, continue at label 2 */
+
+       ld      r0,16(r1)               /* we return here from the call, get LR and */
+       ld      r1,0(r1)                /* .. old stack ptr */
+       mtspr   SPRN_SRR0,r0            /* and get back to virtual mode with these */
+       mfmsr   r4
+       ori     r4,r4,MSR_IR|MSR_DR
+       mtspr   SPRN_SRR1,r4
+       rfid
+
+2:     mtspr   SPRN_SRR0,r3            /* coming from above, enter real mode */
+       mr      r3,r4                   /* get parameter */
+       mfmsr   r0
+       ori     r0,r0,MSR_IR|MSR_DR
+       xori    r0,r0,MSR_IR|MSR_DR
+       mtspr   SPRN_SRR1,r0
+       rfid
+
+
        .section        ".toc","aw"
 PPC64_CACHES:
        .tc             ppc64_caches[TC],ppc64_caches
@@ -245,6 +323,144 @@ _GLOBAL(__flush_dcache_icache)
        bdnz    1b
        isync
        blr
+       
+/*
+ * I/O string operations
+ *
+ * insb(port, buf, len)
+ * outsb(port, buf, len)
+ * insw(port, buf, len)
+ * outsw(port, buf, len)
+ * insl(port, buf, len)
+ * outsl(port, buf, len)
+ * insw_ns(port, buf, len)
+ * outsw_ns(port, buf, len)
+ * insl_ns(port, buf, len)
+ * outsl_ns(port, buf, len)
+ *
+ * The *_ns versions don't do byte-swapping.
+ */
+_GLOBAL(_insb)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,1
+       blelr-
+00:    lbz     r5,0(r3)
+       eieio
+       stbu    r5,1(r4)
+       bdnz    00b
+       twi     0,r5,0
+       isync
+       blr
+
+_GLOBAL(_outsb)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,1
+       blelr-
+00:    lbzu    r5,1(r4)
+       stb     r5,0(r3)
+       bdnz    00b
+       sync
+       blr     
+
+_GLOBAL(_insw)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,2
+       blelr-
+00:    lhbrx   r5,0,r3
+       eieio
+       sthu    r5,2(r4)
+       bdnz    00b
+       twi     0,r5,0
+       isync
+       blr
+
+_GLOBAL(_outsw)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,2
+       blelr-
+00:    lhzu    r5,2(r4)
+       sthbrx  r5,0,r3 
+       bdnz    00b
+       sync
+       blr     
+
+_GLOBAL(_insl)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,4
+       blelr-
+00:    lwbrx   r5,0,r3
+       eieio
+       stwu    r5,4(r4)
+       bdnz    00b
+       twi     0,r5,0
+       isync
+       blr
+
+_GLOBAL(_outsl)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,4
+       blelr-
+00:    lwzu    r5,4(r4)
+       stwbrx  r5,0,r3
+       bdnz    00b
+       sync
+       blr     
+
+/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */
+_GLOBAL(_insw_ns)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,2
+       blelr-
+00:    lhz     r5,0(r3)
+       eieio
+       sthu    r5,2(r4)
+       bdnz    00b
+       twi     0,r5,0
+       isync
+       blr
+
+/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */
+_GLOBAL(_outsw_ns)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,2
+       blelr-
+00:    lhzu    r5,2(r4)
+       sth     r5,0(r3)
+       bdnz    00b
+       sync
+       blr     
+
+_GLOBAL(_insl_ns)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,4
+       blelr-
+00:    lwz     r5,0(r3)
+       eieio
+       stwu    r5,4(r4)
+       bdnz    00b
+       twi     0,r5,0
+       isync
+       blr
+
+_GLOBAL(_outsl_ns)
+       cmpwi   0,r5,0
+       mtctr   r5
+       subi    r4,r4,4
+       blelr-
+00:    lwzu    r5,4(r4)
+       stw     r5,0(r3)
+       bdnz    00b
+       sync
+       blr     
 
 /*
  * identify_cpu and calls setup_cpu
@@ -266,9 +482,7 @@ _GLOBAL(identify_cpu)
        sub     r0,r3,r5
        std     r0,0(r4)
        ld      r4,CPU_SPEC_SETUP(r3)
-       cmpdi   0,r4,0
        add     r4,r4,r5
-       beqlr
        ld      r4,0(r4)
        add     r4,r4,r5
        mtctr   r4
@@ -389,7 +603,6 @@ _GLOBAL(real_writeb)
        blr
 #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
 
-#ifdef CONFIG_CPU_FREQ_PMAC64
 /*
  * SCOM access functions for 970 (FX only for now)
  *
@@ -458,7 +671,6 @@ _GLOBAL(scom970_write)
        /* restore interrupts */
        mtmsrd  r5,1
        blr
-#endif /* CONFIG_CPU_FREQ_PMAC64 */
 
 
 /*
@@ -556,6 +768,9 @@ _GLOBAL(giveup_altivec)
 
 #endif /* CONFIG_ALTIVEC */
 
+_GLOBAL(__setup_cpu_power3)
+       blr
+
 _GLOBAL(execve)
        li      r0,__NR_execve
        sc
@@ -687,7 +902,7 @@ _GLOBAL(kexec_sequence)
        /* clear out hardware hash page table and tlb */
        ld      r5,0(r27)               /* deref function descriptor */
        mtctr   r5
-       bctrl                           /* ppc_md.hpte_clear_all(void); */
+       bctrl                           /* ppc_md.hash_clear_all(void); */
 
 /*
  *   kexec image calling is: