1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <linux/init.h>
  11 #include <linux/linkage.h>
  12 #include <linux/threads.h>
  13 #include <asm/assembler.h>
  14 #include <asm/memory.h>
  15 
  16 #define SCTLR_MMU       0x01
  17 #define BOOTROM_ADDRESS 0xE6340000
  18 #define RWTCSRA_ADDRESS 0xE6020004
  19 #define RWTCSRA_WOVF    0x10
  20 
  21 
  22 
  23 
  24 
  25 
  26         .arm
  27         .align  12
  28 ENTRY(shmobile_boot_vector)
  29         ldr     r1, 1f
  30         bx      r1
  31 
  32 ENDPROC(shmobile_boot_vector)
  33 
  34         .align  2
  35         .globl  shmobile_boot_fn
  36 shmobile_boot_fn:
  37 1:      .space  4
  38         .globl  shmobile_boot_size
  39 shmobile_boot_size:
  40         .long   . - shmobile_boot_vector
  41 
  42 #ifdef CONFIG_ARCH_RCAR_GEN2
  43 
  44 
  45 
  46 
  47 ENTRY(shmobile_boot_vector_gen2)
  48         mrc     p15, 0, r0, c0, c0, 5           @ r0 = MPIDR
  49         ldr     r1, shmobile_boot_cpu_gen2
  50         cmp     r0, r1
  51         bne     shmobile_smp_continue_gen2
  52 
  53         mrc     p15, 0, r1, c1, c0, 0           @ r1 = SCTLR
  54         and     r0, r1, #SCTLR_MMU
  55         cmp     r0, #SCTLR_MMU
  56         beq     shmobile_smp_continue_gen2
  57 
  58         ldr     r0, rwtcsra
  59         mov     r1, #0
  60         ldrb    r1, [r0]
  61         and     r0, r1, #RWTCSRA_WOVF
  62         cmp     r0, #RWTCSRA_WOVF
  63         bne     shmobile_smp_continue_gen2
  64 
  65         ldr     r0, bootrom
  66         bx      r0
  67 
  68 shmobile_smp_continue_gen2:
  69         ldr     r1, shmobile_boot_fn_gen2
  70         bx      r1
  71 
  72 ENDPROC(shmobile_boot_vector_gen2)
  73 
  74         .align  4
  75 rwtcsra:
  76         .word   RWTCSRA_ADDRESS
  77 bootrom:
  78         .word   BOOTROM_ADDRESS
  79         .globl  shmobile_boot_cpu_gen2
  80 shmobile_boot_cpu_gen2:
  81         .word   0x00000000
  82 
  83         .align  2
  84         .globl  shmobile_boot_fn_gen2
  85 shmobile_boot_fn_gen2:
  86         .space  4
  87         .globl  shmobile_boot_size_gen2
  88 shmobile_boot_size_gen2:
  89         .long   . - shmobile_boot_vector_gen2
  90 #endif 
  91 
  92 
  93 
  94 
  95 
  96 ENTRY(shmobile_smp_boot)
  97         mrc     p15, 0, r1, c0, c0, 5           @ r1 = MPIDR
  98         and     r0, r1, #0xffffff               @ MPIDR_HWID_BITMASK
  99                                                 @ r0 = cpu_logical_map() value
 100         mov     r1, #0                          @ r1 = CPU index
 101         adr     r2, 1f
 102         ldmia   r2, {r5, r6, r7}
 103         add     r5, r5, r2                      @ array of per-cpu mpidr values
 104         add     r6, r6, r2                      @ array of per-cpu functions
 105         add     r7, r7, r2                      @ array of per-cpu arguments
 106 
 107 shmobile_smp_boot_find_mpidr:
 108         ldr     r8, [r5, r1, lsl #2]
 109         cmp     r8, r0
 110         bne     shmobile_smp_boot_next
 111 
 112         ldr     r9, [r6, r1, lsl #2]
 113         cmp     r9, #0
 114         bne     shmobile_smp_boot_found
 115 
 116 shmobile_smp_boot_next:
 117         add     r1, r1, #1
 118         cmp     r1, #NR_CPUS
 119         blo     shmobile_smp_boot_find_mpidr
 120 
 121         b       shmobile_smp_sleep
 122 
 123 shmobile_smp_boot_found:
 124         ldr     r0, [r7, r1, lsl #2]
 125         ret     r9
 126 ENDPROC(shmobile_smp_boot)
 127 
 128 ENTRY(shmobile_smp_sleep)
 129         wfi
 130         b       shmobile_smp_boot
 131 ENDPROC(shmobile_smp_sleep)
 132 
 133         .align  2
 134 1:      .long   shmobile_smp_mpidr - .
 135         .long   shmobile_smp_fn - 1b
 136         .long   shmobile_smp_arg - 1b
 137 
 138         .bss
 139         .globl  shmobile_smp_mpidr
 140 shmobile_smp_mpidr:
 141         .space  NR_CPUS * 4
 142         .globl  shmobile_smp_fn
 143 shmobile_smp_fn:
 144         .space  NR_CPUS * 4
 145         .globl  shmobile_smp_arg
 146 shmobile_smp_arg:
 147         .space  NR_CPUS * 4