a5ds_helpers.S 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /*
  2. * Copyright (c) 2019, Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <arch.h>
  7. #include <asm_macros.S>
  8. #include <platform_def.h>
  9. .globl plat_secondary_cold_boot_setup
  10. .globl plat_get_my_entrypoint
  11. .globl plat_is_my_cpu_primary
  12. /* -----------------------------------------------------
  13. * void plat_secondary_cold_boot_setup (void);
  14. *
  15. * This function performs any platform specific actions
  16. * needed for a secondary cpu after a cold reset e.g
  17. * mark the cpu's presence, mechanism to place it in a
  18. * holding pen etc.
  19. * -----------------------------------------------------
  20. */
  21. func plat_secondary_cold_boot_setup
  22. /* Calculate address of our hold entry */
  23. bl plat_my_core_pos
  24. lsl r0, r0, #A5DS_HOLD_ENTRY_SHIFT
  25. mov_imm r2, A5DS_HOLD_BASE
  26. /* Clear the value stored in the hold address for the specific core */
  27. mov_imm r3, A5DS_HOLD_STATE_WAIT
  28. str r3, [r2, r0]
  29. dmb ish
  30. /* Wait until we have a go */
  31. poll_mailbox:
  32. ldr r1, [r2, r0]
  33. cmp r1, #A5DS_HOLD_STATE_WAIT
  34. beq 1f
  35. mov_imm r0, A5DS_TRUSTED_MAILBOX_BASE
  36. ldr r1, [r0]
  37. bx r1
  38. 1:
  39. wfe
  40. b poll_mailbox
  41. endfunc plat_secondary_cold_boot_setup
  42. /* ---------------------------------------------------------------------
  43. * unsigned long plat_get_my_entrypoint (void);
  44. *
  45. * Main job of this routine is to distinguish between a cold and warm
  46. * boot.
  47. * ---------------------------------------------------------------------
  48. */
  49. func plat_get_my_entrypoint
  50. /* TODO support warm boot */
  51. /* Cold reset */
  52. mov r0, #0
  53. bx lr
  54. endfunc plat_get_my_entrypoint
  55. /* -----------------------------------------------------
  56. * unsigned int plat_is_my_cpu_primary (void);
  57. *
  58. * Find out whether the current cpu is the primary
  59. * cpu.
  60. * -----------------------------------------------------
  61. */
  62. func plat_is_my_cpu_primary
  63. ldcopr r0, MPIDR
  64. ldr r1, =MPIDR_AFFINITY_MASK
  65. and r0, r1
  66. cmp r0, #0
  67. moveq r0, #1
  68. movne r0, #0
  69. bx lr
  70. endfunc plat_is_my_cpu_primary
  71. /* ---------------------------------------------------------------------
  72. * Loads MPIDR in r0 and calls plat_arm_calc_core_pos
  73. * ---------------------------------------------------------------------
  74. */
  75. func plat_my_core_pos
  76. ldcopr r0, MPIDR
  77. b plat_arm_calc_core_pos
  78. endfunc plat_my_core_pos
  79. /* ---------------------------------------------------------------------
  80. * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
  81. *
  82. * Function to calculate the core position on A5DS.
  83. *
  84. * (ClusterId * A5DS_MAX_CPUS_PER_CLUSTER * A5DS_MAX_PE_PER_CPU) +
  85. * (CPUId * A5DS_MAX_PE_PER_CPU) +
  86. * ThreadId
  87. *
  88. * which can be simplified as:
  89. *
  90. * ((ClusterId * A5DS_MAX_CPUS_PER_CLUSTER + CPUId) * A5DS_MAX_PE_PER_CPU)
  91. * + ThreadId
  92. * ---------------------------------------------------------------------
  93. */
  94. func plat_arm_calc_core_pos
  95. mov r3, r0
  96. /*
  97. * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
  98. * look as if in a multi-threaded implementation
  99. */
  100. tst r0, #MPIDR_MT_MASK
  101. lsleq r3, r0, #MPIDR_AFFINITY_BITS
  102. /* Extract individual affinity fields from MPIDR */
  103. ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
  104. ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
  105. ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
  106. /* Compute linear position */
  107. mov r3, #A5DS_MAX_CPUS_PER_CLUSTER
  108. mla r1, r2, r3, r1
  109. mov r3, #A5DS_MAX_PE_PER_CPU
  110. mla r0, r1, r3, r0
  111. bx lr
  112. endfunc plat_arm_calc_core_pos