mbox_ipcc.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /**
  2. ******************************************************************************
  3. * @file mbox_ipcc.c
  4. * @author MCD Application Team
  5. * @brief This file provides code for the configuration
  6. * of the mailbox_ipcc_if.c MiddleWare.
  7. ******************************************************************************
  8. * @attention
  9. *
  10. * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  11. * All rights reserved.</center></h2>
  12. *
  13. * This software component is licensed by ST under BSD 3-Clause license,
  14. * the "License"; You may not use this file except in compliance with the
  15. * License. You may obtain a copy of the License at:
  16. * opensource.org/licenses/BSD-3-Clause
  17. *
  18. ******************************************************************************
  19. */
  20. /*
  21. * Channel direction and usage:
  22. *
  23. * ======== <-- new msg ---=============--------<------ =======
  24. * || || || CHANNEL 1 || || ||
  25. * || A7 || ------->-------=============--- buf free--> || M4 ||
  26. * || || || ||
  27. * ||master|| <-- buf free---=============--------<------ ||slave||
  28. * || || || CHANNEL 2 || || ||
  29. * ======== ------->-------=============----new msg --> =======
  30. */
  31. /* Includes ------------------------------------------------------------------*/
  32. #include "openamp/open_amp.h"
  33. #include "stm32mp1xx_hal.h"
  34. #include "openamp_conf.h"
  35. /* Within 'USER CODE' section, code will be kept by default at each generation */
  36. /* USER CODE BEGIN 0 */
  37. /* USER CODE END 0 */
  38. /* Private define ------------------------------------------------------------*/
  39. #define MASTER_CPU_ID 0
  40. #define REMOTE_CPU_ID 1
  41. #define IPCC_CPU_A7 MASTER_CPU_ID
  42. #define IPCC_CPU_M4 REMOTE_CPU_ID
  43. #define RX_NO_MSG 0
  44. #define RX_NEW_MSG 1
  45. #define RX_BUF_FREE 2
  46. /* Private variables ---------------------------------------------------------*/
  47. extern IPCC_HandleTypeDef hipcc;
  48. int msg_received_ch1 = RX_NO_MSG;
  49. int msg_received_ch2 = RX_NO_MSG;
  50. uint32_t vring0_id = 0; /* used for channel 1 */
  51. uint32_t vring1_id = 1; /* used for channel 2 */
  52. /* Private function prototypes -----------------------------------------------*/
  53. void IPCC_channel1_callback(IPCC_HandleTypeDef * hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir);
  54. void IPCC_channel2_callback(IPCC_HandleTypeDef * hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir);
  55. /**
  56. * @brief Initialize MAILBOX with IPCC peripheral
  57. * @param None
  58. * @retval : Operation result
  59. */
  60. int MAILBOX_Init(void)
  61. {
  62. if (HAL_IPCC_ActivateNotification(&hipcc, IPCC_CHANNEL_1, IPCC_CHANNEL_DIR_RX,
  63. IPCC_channel1_callback) != HAL_OK) {
  64. OPENAMP_log_err("%s: ch_1 RX fail\n", __func__);
  65. return -1;
  66. }
  67. if (HAL_IPCC_ActivateNotification(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_RX,
  68. IPCC_channel2_callback) != HAL_OK) {
  69. OPENAMP_log_err("%s: ch_2 RX fail\n", __func__);
  70. return -1;
  71. }
  72. return 0;
  73. }
  74. /**
  75. * @brief Initialize MAILBOX with IPCC peripheral
  76. * @param virtio device
  77. * @retval : Operation result
  78. */
  79. int MAILBOX_Poll(struct virtio_device *vdev)
  80. {
  81. /* If we got an interrupt, ask for the corresponding virtqueue processing */
  82. if (msg_received_ch1 == RX_BUF_FREE) {
  83. OPENAMP_log_dbg("Running virt0 (ch_1 buf free)\r\n");
  84. rproc_virtio_notified(vdev, VRING0_ID);
  85. msg_received_ch1 = RX_NO_MSG;
  86. return 0;
  87. }
  88. if (msg_received_ch2 == RX_NEW_MSG) {
  89. OPENAMP_log_dbg("Running virt1 (ch_2 new msg)\r\n");
  90. rproc_virtio_notified(vdev, VRING1_ID);
  91. msg_received_ch2 = RX_NO_MSG;
  92. /* The OpenAMP framework does not notify for free buf: do it here */
  93. rproc_virtio_notified(NULL, VRING1_ID);
  94. return 0;
  95. }
  96. return -1;
  97. }
  98. /**
  99. * @brief Callback function called by OpenAMP MW to notify message processing
  100. * @param VRING id
  101. * @retval Operation result
  102. */
  103. int MAILBOX_Notify(void *priv, uint32_t id)
  104. {
  105. uint32_t channel;
  106. (void)priv;
  107. /* Called after virtqueue processing: time to inform the remote */
  108. if (id == VRING0_ID) {
  109. channel = IPCC_CHANNEL_1;
  110. OPENAMP_log_dbg("Send msg on ch_1\r\n");
  111. }
  112. else if (id == VRING1_ID) {
  113. /* Note: the OpenAMP framework never notifies this */
  114. channel = IPCC_CHANNEL_2;
  115. OPENAMP_log_dbg("Send 'buff free' on ch_2\r\n");
  116. }
  117. else {
  118. OPENAMP_log_err("invalid vring (%d)\r\n", (int)id);
  119. return -1;
  120. }
  121. /* Check that the channel is free (otherwise wait until it is) */
  122. if (HAL_IPCC_GetChannelStatus(&hipcc, channel, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED) {
  123. OPENAMP_log_dbg("Waiting for channel to be freed\r\n");
  124. while (HAL_IPCC_GetChannelStatus(&hipcc, channel, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED)
  125. ;
  126. }
  127. /* Inform A7 (either new message, or buf free) */
  128. HAL_IPCC_NotifyCPU(&hipcc, channel, IPCC_CHANNEL_DIR_TX);
  129. return 0;
  130. }
  131. /* Private function ---------------------------------------------------------*/
  132. /* Callback from IPCC Interrupt Handler: Master Processor informs that there are some free buffers */
  133. void IPCC_channel1_callback(IPCC_HandleTypeDef * hipcc,
  134. uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
  135. {
  136. if (msg_received_ch1 != RX_NO_MSG)
  137. OPENAMP_log_dbg("IPCC_channel1_callback: previous IRQ not treated (status = %d)\r\n", msg_received_ch1);
  138. msg_received_ch1 = RX_BUF_FREE;
  139. /* Inform A7 that we have received the 'buff free' msg */
  140. OPENAMP_log_dbg("Ack 'buff free' message on ch1\r\n");
  141. HAL_IPCC_NotifyCPU(hipcc, ChannelIndex, IPCC_CHANNEL_DIR_RX);
  142. }
  143. /* Callback from IPCC Interrupt Handler: new message received from Master Processor */
  144. void IPCC_channel2_callback(IPCC_HandleTypeDef * hipcc,
  145. uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
  146. {
  147. if (msg_received_ch2 != RX_NO_MSG)
  148. OPENAMP_log_dbg("IPCC_channel2_callback: previous IRQ not treated (status = %d)\r\n", msg_received_ch2);
  149. msg_received_ch2 = RX_NEW_MSG;
  150. /* Inform A7 that we have received the new msg */
  151. OPENAMP_log_dbg("Ack new message on ch2\r\n");
  152. HAL_IPCC_NotifyCPU(hipcc, ChannelIndex, IPCC_CHANNEL_DIR_RX);
  153. }
  154. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/