headsmp.S 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. * SMP support for R-Mobile / SH-Mobile
  3. *
  4. * Copyright (C) 2010 Magnus Damm
  5. * Copyright (C) 2010 Takashi Yoshii
  6. *
  7. * Based on vexpress, Copyright (c) 2003 ARM Limited, All Rights Reserved
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #include <linux/init.h>
  14. #include <linux/linkage.h>
  15. #include <linux/threads.h>
  16. #include <asm/assembler.h>
  17. #include <asm/memory.h>
  18. /*
  19. * Reset vector for secondary CPUs.
  20. * This will be mapped at address 0 by SBAR register.
  21. * We need _long_ jump to the physical address.
  22. */
  23. .arm
  24. .align 12
  25. ENTRY(shmobile_boot_vector)
  26. ldr r1, 1f
  27. bx r1
  28. ENDPROC(shmobile_boot_vector)
  29. .align 2
  30. .globl shmobile_boot_fn
  31. shmobile_boot_fn:
  32. 1: .space 4
  33. .globl shmobile_boot_size
  34. shmobile_boot_size:
  35. .long . - shmobile_boot_vector
  36. /*
  37. * Per-CPU SMP boot function/argument selection code based on MPIDR
  38. */
  39. ENTRY(shmobile_smp_boot)
  40. mrc p15, 0, r1, c0, c0, 5 @ r1 = MPIDR
  41. and r0, r1, #0xffffff @ MPIDR_HWID_BITMASK
  42. @ r0 = cpu_logical_map() value
  43. mov r1, #0 @ r1 = CPU index
  44. adr r2, 1f
  45. ldmia r2, {r5, r6, r7}
  46. add r5, r5, r2 @ array of per-cpu mpidr values
  47. add r6, r6, r2 @ array of per-cpu functions
  48. add r7, r7, r2 @ array of per-cpu arguments
  49. shmobile_smp_boot_find_mpidr:
  50. ldr r8, [r5, r1, lsl #2]
  51. cmp r8, r0
  52. bne shmobile_smp_boot_next
  53. ldr r9, [r6, r1, lsl #2]
  54. cmp r9, #0
  55. bne shmobile_smp_boot_found
  56. shmobile_smp_boot_next:
  57. add r1, r1, #1
  58. cmp r1, #NR_CPUS
  59. blo shmobile_smp_boot_find_mpidr
  60. b shmobile_smp_sleep
  61. shmobile_smp_boot_found:
  62. ldr r0, [r7, r1, lsl #2]
  63. ret r9
  64. ENDPROC(shmobile_smp_boot)
  65. ENTRY(shmobile_smp_sleep)
  66. wfi
  67. b shmobile_smp_boot
  68. ENDPROC(shmobile_smp_sleep)
  69. .align 2
  70. 1: .long shmobile_smp_mpidr - .
  71. .long shmobile_smp_fn - 1b
  72. .long shmobile_smp_arg - 1b
  73. .bss
  74. .globl shmobile_smp_mpidr
  75. shmobile_smp_mpidr:
  76. .space NR_CPUS * 4
  77. .globl shmobile_smp_fn
  78. shmobile_smp_fn:
  79. .space NR_CPUS * 4
  80. .globl shmobile_smp_arg
  81. shmobile_smp_arg:
  82. .space NR_CPUS * 4