css_mhu.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <platform_def.h>
  8. #include <arch_helpers.h>
  9. #include <drivers/arm/css/css_mhu.h>
  10. #include <lib/bakery_lock.h>
  11. #include <lib/mmio.h>
  12. #include <plat/arm/common/plat_arm.h>
  13. /* SCP MHU secure channel registers */
  14. #define SCP_INTR_S_STAT 0x200
  15. #define SCP_INTR_S_SET 0x208
  16. #define SCP_INTR_S_CLEAR 0x210
  17. /* CPU MHU secure channel registers */
  18. #define CPU_INTR_S_STAT 0x300
  19. #define CPU_INTR_S_SET 0x308
  20. #define CPU_INTR_S_CLEAR 0x310
  21. ARM_INSTANTIATE_LOCK;
  22. /* Weak definition may be overridden in specific CSS based platform */
  23. #pragma weak plat_arm_pwrc_setup
  24. /*
  25. * Slot 31 is reserved because the MHU hardware uses this register bit to
  26. * indicate a non-secure access attempt. The total number of available slots is
  27. * therefore 31 [30:0].
  28. */
  29. #define MHU_MAX_SLOT_ID 30
  30. void mhu_secure_message_start(unsigned int slot_id)
  31. {
  32. assert(slot_id <= MHU_MAX_SLOT_ID);
  33. arm_lock_get();
  34. /* Make sure any previous command has finished */
  35. while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
  36. (1 << slot_id))
  37. ;
  38. }
  39. void mhu_secure_message_send(unsigned int slot_id)
  40. {
  41. assert(slot_id <= MHU_MAX_SLOT_ID);
  42. assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
  43. (1 << slot_id)));
  44. /* Send command to SCP */
  45. mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id);
  46. }
  47. uint32_t mhu_secure_message_wait(void)
  48. {
  49. /* Wait for response from SCP */
  50. uint32_t response;
  51. while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT)))
  52. ;
  53. return response;
  54. }
  55. void mhu_secure_message_end(unsigned int slot_id)
  56. {
  57. assert(slot_id <= MHU_MAX_SLOT_ID);
  58. /*
  59. * Clear any response we got by writing one in the relevant slot bit to
  60. * the CLEAR register
  61. */
  62. mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id);
  63. arm_lock_release();
  64. }
  65. void __init mhu_secure_init(void)
  66. {
  67. arm_lock_init();
  68. /*
  69. * The STAT register resets to zero. Ensure it is in the expected state,
  70. * as a stale or garbage value would make us think it's a message we've
  71. * already sent.
  72. */
  73. assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0);
  74. }
  75. void __init plat_arm_pwrc_setup(void)
  76. {
  77. mhu_secure_init();
  78. }