sec_entry_cpu1.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* SPDX-License-Identifier: GPL-2.0+ */
  2. /*
  3. * Secure entry function for CPU Core #1
  4. *
  5. * (C) Copyright 2016
  6. * Texas Instruments, <www.ti.com>
  7. *
  8. * Author :
  9. * Harinarayan Bhatta <harinarayan@ti.com>
  10. */
  11. #include <config.h>
  12. #include <asm/arch/omap.h>
  13. #include <asm/omap_common.h>
  14. #include <linux/linkage.h>
  15. .arch_extension sec
  16. #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
  17. .global flush_dcache_range
  18. #endif
  19. #define AUX_CORE_BOOT_0 0x48281800
  20. #define AUX_CORE_BOOT_1 0x48281804
  21. #ifdef CONFIG_DRA7XX
  22. /* DRA7xx ROM code function "startup_BootSlave". This function is where CPU1
  23. * waits on WFE, polling on AUX_CORE_BOOT_x registers.
  24. * This address is same for J6 and J6 Eco.
  25. */
  26. #define ROM_FXN_STARTUP_BOOTSLAVE 0x00038a64
  27. #endif
  28. /* Assembly core where CPU1 is woken up into
  29. * No need to save-restore registers, does not use stack.
  30. */
  31. LENTRY(cpu1_entry)
  32. ldr r4, =omap_smc_sec_cpu1_args
  33. ldm r4, {r0,r1,r2,r3} @ Retrieve args
  34. mov r6, #0xFF @ Indicate new Task call
  35. mov r12, #0x00 @ Secure Service ID in R12
  36. dsb
  37. dmb
  38. smc 0 @ SMC #0 to enter monitor mode
  39. b .Lend @ exit at end of the service execution
  40. nop
  41. @ In case of IRQ happening in Secure, then ARM will branch here.
  42. @ At that moment, IRQ will be pending and ARM will jump to Non Secure
  43. @ IRQ handler
  44. mov r12, #0xFE
  45. dsb
  46. dmb
  47. smc 0 @ SMC #0 to enter monitor mode
  48. .Lend:
  49. ldr r4, =omap_smc_sec_cpu1_args
  50. str r0, [r4, #0x10] @ save return value
  51. ldr r4, =AUX_CORE_BOOT_0
  52. mov r5, #0x0
  53. str r5, [r4]
  54. ldr r4, =ROM_FXN_STARTUP_BOOTSLAVE
  55. sev @ Tell CPU0 we are done
  56. bx r4 @ Jump back to ROM
  57. END(cpu1_entry)
  58. /*
  59. * u32 omap_smc_sec_cpu1(u32 service, u32 proc_id, u32 flag, u32 *params);
  60. *
  61. * Makes a secure ROM/PPA call on CPU Core #1 on supported platforms.
  62. * Assumes that CPU #1 is waiting in ROM code and not yet woken up or used by
  63. * u-boot.
  64. */
  65. ENTRY(omap_smc_sec_cpu1)
  66. push {r4, r5, lr}
  67. ldr r4, =omap_smc_sec_cpu1_args
  68. stm r4, {r0,r1,r2,r3} @ Save args to memory
  69. #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
  70. mov r0, r4
  71. mov r1, #CONFIG_SYS_CACHELINE_SIZE
  72. add r1, r0, r1 @ dcache is not enabled on CPU1, so
  73. blx flush_dcache_range @ flush the cache on args buffer
  74. #endif
  75. ldr r4, =AUX_CORE_BOOT_1
  76. ldr r5, =cpu1_entry
  77. str r5, [r4] @ Setup CPU1 entry function
  78. ldr r4, =AUX_CORE_BOOT_0
  79. mov r5, #0x10
  80. str r5, [r4] @ Tell ROM to exit while loop
  81. sev @ Wake up CPU1
  82. .Lwait:
  83. wfe @ Wait for CPU1 to finish
  84. nop
  85. ldr r5, [r4] @ Check if CPU1 is done
  86. cmp r5, #0
  87. bne .Lwait
  88. ldr r4, =omap_smc_sec_cpu1_args
  89. ldr r0, [r4, #0x10] @ Retrieve return value
  90. pop {r4, r5, pc}
  91. ENDPROC(omap_smc_sec_cpu1)
  92. /*
  93. * Buffer to save function arguments and return value for omap_smc_sec_cpu1
  94. */
  95. .section .data
  96. omap_smc_sec_cpu1_args:
  97. #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
  98. .balign CONFIG_SYS_CACHELINE_SIZE
  99. .rept CONFIG_SYS_CACHELINE_SIZE/4
  100. .word 0
  101. .endr
  102. #else
  103. .rept 5
  104. .word 0
  105. .endr
  106. #endif
  107. END(omap_smc_sec_cpu1_args)