Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / arch / arm / mm / proc-v6.S
index c22cc36..ee6f152 100644 (file)
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <asm/constants.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/arm_scu.h>
 #include <asm/procinfo.h>
+#include <asm/pgtable-hwdef.h>
 #include <asm/pgtable.h>
 
 #include "proc-macros.S"
 
 #define D_CACHE_LINE_SIZE      32
 
+#define TTB_C          (1 << 0)
+#define TTB_S          (1 << 1)
+#define TTB_IMP                (1 << 2)
+#define TTB_RGN_NC     (0 << 3)
+#define TTB_RGN_WBWA   (1 << 3)
+#define TTB_RGN_WT     (2 << 3)
+#define TTB_RGN_WB     (3 << 3)
+
        .macro  cpsie, flags
        .ifc \flags, f
        .long   0xf1080040
@@ -55,7 +65,14 @@ ENTRY(cpu_v6_proc_init)
        mov     pc, lr
 
 ENTRY(cpu_v6_proc_fin)
-       mov     pc, lr
+       stmfd   sp!, {lr}
+       cpsid   if                              @ disable interrupts
+       bl      v6_flush_kern_cache_all
+       mrc     p15, 0, r0, c1, c0, 0           @ ctrl register
+       bic     r0, r0, #0x1000                 @ ...i............
+       bic     r0, r0, #0x0006                 @ .............ca.
+       mcr     p15, 0, r0, c1, c0, 0           @ disable caches
+       ldmfd   sp!, {pc}
 
 /*
  *     cpu_v6_reset(loc)
@@ -105,17 +122,15 @@ ENTRY(cpu_v6_dcache_clean_area)
 ENTRY(cpu_v6_switch_mm)
        mov     r2, #0
        ldr     r1, [r1, #MM_CONTEXT_ID]        @ get mm->context.id
+#ifdef CONFIG_SMP
+       orr     r0, r0, #TTB_RGN_WBWA|TTB_S     @ mark PTWs shared, outer cacheable
+#endif
+       mcr     p15, 0, r2, c7, c5, 6           @ flush BTAC/BTB
        mcr     p15, 0, r2, c7, c10, 4          @ drain write buffer
        mcr     p15, 0, r0, c2, c0, 0           @ set TTB 0
        mcr     p15, 0, r1, c13, c0, 1          @ set context ID
        mov     pc, lr
 
-#define nG     (1 << 11)
-#define APX    (1 << 9)
-#define AP1    (1 << 5)
-#define AP0    (1 << 4)
-#define XN     (1 << 0)
-
 /*
  *     cpu_v6_set_pte(ptep, pte)
  *
@@ -131,31 +146,31 @@ ENTRY(cpu_v6_switch_mm)
  *       100x   1   0   1      r/o     no acc
  *       10x0   1   0   1      r/o     no acc
  *       1011   0   0   1      r/w     no acc
- *       110x   1   1   0      r/o     r/o
- *       11x0   1   1   0      r/o     r/o
+ *       110x   0   1   0      r/w     r/o
+ *       11x0   0   1   0      r/w     r/o
  *       1111   0   1   1      r/w     r/w
  */
 ENTRY(cpu_v6_set_pte)
        str     r1, [r0], #-2048                @ linux version
 
-       bic     r2, r1, #0x00000ff0
+       bic     r2, r1, #0x000003f0
        bic     r2, r2, #0x00000003
-       orr     r2, r2, #AP0 | 2
+       orr     r2, r2, #PTE_EXT_AP0 | 2
 
        tst     r1, #L_PTE_WRITE
        tstne   r1, #L_PTE_DIRTY
-       orreq   r2, r2, #APX
+       orreq   r2, r2, #PTE_EXT_APX
 
        tst     r1, #L_PTE_USER
-       orrne   r2, r2, #AP1 | nG
-       tstne   r2, #APX
-       eorne   r2, r2, #AP0
+       orrne   r2, r2, #PTE_EXT_AP1
+       tstne   r2, #PTE_EXT_APX
+       bicne   r2, r2, #PTE_EXT_APX | PTE_EXT_AP0
 
        tst     r1, #L_PTE_YOUNG
-       biceq   r2, r2, #APX | AP1 | AP0
+       biceq   r2, r2, #PTE_EXT_APX | PTE_EXT_AP_MASK
 
-@      tst     r1, #L_PTE_EXEC
-@      orreq   r2, r2, #XN
+       tst     r1, #L_PTE_EXEC
+       orreq   r2, r2, #PTE_EXT_XN
 
        tst     r1, #L_PTE_PRESENT
        moveq   r2, #0
@@ -189,24 +204,44 @@ cpu_v6_name:
  *     - cache type register is implemented
  */
 __v6_setup:
-       mrc     p15, 0, r10, c0, c0, 1          @ read cache type register
-       tst     r10, #1 << 24                   @ Harvard cache?
-       mov     r10, #0
-       mcrne   p15, 0, r10, c7, c14, 0         @ clean+invalidate D cache
-       mcrne   p15, 0, r10, c7, c5, 0          @ invalidate I cache
-       mcreq   p15, 0, r10, c7, c15, 0         @ clean+invalidate cache
-       mcr     p15, 0, r10, c7, c10, 4         @ drain write buffer
-       mcr     p15, 0, r10, c8, c7, 0          @ invalidate I + D TLBs
-       mcr     p15, 0, r10, c2, c0, 2          @ TTB control register
-       mcr     p15, 0, r4, c2, c0, 0           @ load TTB0
+#ifdef CONFIG_SMP
+       /* Set up the SCU on core 0 only */
+       mrc     p15, 0, r0, c0, c0, 5           @ CPU core number
+       ands    r0, r0, #15
+       moveq   r0, #0x10000000 @ SCU_BASE
+       orreq   r0, r0, #0x00100000
+       ldreq   r5, [r0, #SCU_CTRL]
+       orreq   r5, r5, #1
+       streq   r5, [r0, #SCU_CTRL]
+
+#ifndef CONFIG_CPU_DCACHE_DISABLE
+       mrc     p15, 0, r0, c1, c0, 1           @ Enable SMP/nAMP mode
+       orr     r0, r0, #0x20
+       mcr     p15, 0, r0, c1, c0, 1
+#endif
+#endif
+
+       mov     r0, #0
+       mcr     p15, 0, r0, c7, c14, 0          @ clean+invalidate D cache
+       mcr     p15, 0, r0, c7, c5, 0           @ invalidate I cache
+       mcr     p15, 0, r0, c7, c15, 0          @ clean+invalidate cache
+       mcr     p15, 0, r0, c7, c10, 4          @ drain write buffer
+       mcr     p15, 0, r0, c8, c7, 0           @ invalidate I + D TLBs
+       mcr     p15, 0, r0, c2, c0, 2           @ TTB control register
+#ifdef CONFIG_SMP
+       orr     r4, r4, #TTB_RGN_WBWA|TTB_S     @ mark PTWs shared, outer cacheable
+#endif
        mcr     p15, 0, r4, c2, c0, 1           @ load TTB1
-       mov     r10, #0x1f                      @ domains 0, 1 = manager
-       mcr     p15, 0, r10, c3, c0, 0          @ load domain access register
+#ifdef CONFIG_VFP
+       mrc     p15, 0, r0, c1, c0, 2
+       orr     r0, r0, #(0xf << 20)
+       mcr     p15, 0, r0, c1, c0, 2           @ Enable full access to VFP
+#endif
        mrc     p15, 0, r0, c1, c0, 0           @ read control register
-       ldr     r10, cr1_clear                  @ get mask for bits to clear
-       bic     r0, r0, r10                     @ clear bits them
-       ldr     r10, cr1_set                    @ get mask for bits to set
-       orr     r0, r0, r10                     @ set them
+       ldr     r5, v6_cr1_clear                @ get mask for bits to clear
+       bic     r0, r0, r                     @ clear bits them
+       ldr     r5, v6_cr1_set                  @ get mask for bits to set
+       orr     r0, r0, r                     @ set them
        mov     pc, lr                          @ return to head.S:__ret
 
        /*
@@ -215,11 +250,11 @@ __v6_setup:
         * rrrr rrrx xxx0 0101 xxxx xxxx x111 xxxx < forced
         *         0 110       0011 1.00 .111 1101 < we want
         */
-       .type   cr1_clear, #object
-       .type   cr1_set, #object
-cr1_clear:
-       .word   0x0120c302
-cr1_set:
+       .type   v6_cr1_clear, #object
+       .type   v6_cr1_set, #object
+v6_cr1_clear:
+       .word   0x01e0fb7f
+v6_cr1_set:
        .word   0x00c0387d
 
        .type   v6_processor_functions, #object
@@ -245,20 +280,24 @@ cpu_elf_name:
        .size   cpu_elf_name, . - cpu_elf_name
        .align
 
-       .section ".proc.info", #alloc, #execinstr
+       .section ".proc.info.init", #alloc, #execinstr
 
        /*
         * Match any ARMv6 processor core.
         */
        .type   __v6_proc_info, #object
 __v6_proc_info:
-       .long   0x00070000
-       .long   0x00ff0000
-       .long   0x00000c0e
+       .long   0x0007b000
+       .long   0x0007f000
+       .long   PMD_TYPE_SECT | \
+               PMD_SECT_BUFFERABLE | \
+               PMD_SECT_CACHEABLE | \
+               PMD_SECT_AP_WRITE | \
+               PMD_SECT_AP_READ
        b       __v6_setup
        .long   cpu_arch_name
        .long   cpu_elf_name
-       .long   HWCAP_SWP | HWCAP_HALF | HWCAP_FAST_MULT | HWCAP_VFP
+       .long   HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_VFP|HWCAP_EDSP|HWCAP_JAVA
        .long   cpu_v6_name
        .long   v6_processor_functions
        .long   v6wbi_tlb_fns