3636#include "openamp/open_amp.h"
3737#include "stm32_def.h"
3838#include "openamp_conf.h"
39+ #include "core_debug.h"
3940
4041/* Private define ------------------------------------------------------------*/
4142#define MASTER_CPU_ID 0
4243#define REMOTE_CPU_ID 1
4344#define IPCC_CPU_A7 MASTER_CPU_ID
4445#define IPCC_CPU_M4 REMOTE_CPU_ID
4546
46- #define RX_NO_MSG 0
47- #define RX_NEW_MSG 1
48- #define RX_BUF_FREE 2
47+ typedef enum {
48+ RX_NO_MSG = 0 ,
49+ RX_NEW_MSG = 1 ,
50+ RX_BUF_FREE = 2
51+ } rx_status_t ;
4952
5053/* Private variables ---------------------------------------------------------*/
5154IPCC_HandleTypeDef hipcc ;
52- extern struct rpmsg_virtio_device rvdev ;
53-
54-
55-
55+ rx_status_t msg_received_ch1 = RX_NO_MSG ;
56+ rx_status_t msg_received_ch2 = RX_NO_MSG ;
5657
5758/* Private function prototypes -----------------------------------------------*/
5859void IPCC_channel1_callback (IPCC_HandleTypeDef * hipcc , uint32_t ChannelIndex , IPCC_CHANNELDirTypeDef ChannelDir );
@@ -68,6 +69,7 @@ int MAILBOX_Init(void)
6869 __HAL_RCC_IPCC_CLK_ENABLE ();
6970 HAL_NVIC_SetPriority (IPCC_RX1_IRQn , IPCC_IRQ_PRIO , IPCC_IRQ_SUBPRIO );
7071 HAL_NVIC_EnableIRQ (IPCC_RX1_IRQn );
72+
7173 hipcc .Instance = IPCC ;
7274 if (HAL_IPCC_Init (& hipcc ) != HAL_OK ) {
7375 Error_Handler ();
@@ -89,19 +91,61 @@ int MAILBOX_Init(void)
8991}
9092
9193/**
92- * @brief Callback function called by OpenAMP MW to notify message processing
93- * @param VRING id
94+ * @brief Process vring messages received from IPCC ISR
95+ * @param vdev: virtio device
96+ * @param vring_id: Vring ID
97+ * @retval : Operation result
98+ */
99+ int MAILBOX_Poll (struct virtio_device * vdev , uint32_t vring_id )
100+ {
101+ int ret = -1 ;
102+
103+ switch (vring_id ) {
104+ case VRING0_ID :
105+ if (msg_received_ch1 == RX_BUF_FREE ) {
106+ /* This calls rpmsg_virtio_tx_callback(), which actually does nothing. */
107+ rproc_virtio_notified (vdev , VRING0_ID );
108+ msg_received_ch1 = RX_NO_MSG ;
109+ ret = 0 ;
110+ }
111+ break ;
112+ case VRING1_ID :
113+ if (msg_received_ch2 == RX_NEW_MSG ) {
114+ /**
115+ * This calls rpmsg_virtio_rx_callback(), which calls virt_uart rx callback
116+ * RING_NUM_BUFFS times at maximum.
117+ */
118+ rproc_virtio_notified (vdev , VRING1_ID );
119+ msg_received_ch2 = RX_NO_MSG ;
120+
121+ /* The OpenAMP framework does not notify for free buf: do it here */
122+ rproc_virtio_notified (NULL , VRING1_ID );
123+ ret = 0 ;
124+ }
125+ break ;
126+ default :
127+ break ;
128+ }
129+
130+ return ret ;
131+ }
132+
133+ /**
134+ * @brief Callback function called by OpenAMP MW to notify message processing (aka. kick)
135+ * @note This callback is called by virtqueue_kick() in rpmsg_virtio_send_offchannel_raw().
136+ * Therefore, it is only called while tx, but not rx.
137+ * @param Vring id
94138 * @retval Operation result
95139 */
96- int MAILBOX_Notify (void * priv , uint32_t id )
140+ int MAILBOX_Notify (void * priv , uint32_t vring_id )
97141{
98142 uint32_t channel ;
99143 (void )priv ;
100144
101145 /* Called after virtqueue processing: time to inform the remote */
102- if (id == VRING0_ID ) {
146+ if (vring_id == VRING0_ID ) {
103147 channel = IPCC_CHANNEL_1 ;
104- } else if (id == VRING1_ID ) {
148+ } else if (vring_id == VRING1_ID ) {
105149 /* Note: the OpenAMP framework never notifies this */
106150 channel = IPCC_CHANNEL_2 ;
107151 return -1 ;
@@ -121,37 +165,25 @@ int MAILBOX_Notify(void *priv, uint32_t id)
121165 return 0 ;
122166}
123167
124- /**
125- * @brief Notify Rx buffer is free to Master
126- */
127- void MAILBOX_Notify_Rx_Buf_Free ()
128- {
129- HAL_IPCC_NotifyCPU (& hipcc , IPCC_CHANNEL_2 , IPCC_CHANNEL_DIR_RX );
130- }
131-
132168/* Private function ---------------------------------------------------------*/
133169/* Callback from IPCC Interrupt Handler: Master Processor informs that there are some free buffers */
134170void IPCC_channel1_callback (IPCC_HandleTypeDef * hipcc ,
135171 uint32_t ChannelIndex , IPCC_CHANNELDirTypeDef ChannelDir )
136172{
173+ msg_received_ch1 = RX_BUF_FREE ;
174+
137175 /* Inform A7 that we have received the 'buff free' msg */
138176 HAL_IPCC_NotifyCPU (hipcc , ChannelIndex , IPCC_CHANNEL_DIR_RX );
139- rproc_virtio_notified (rvdev .vdev , VRING0_ID );
140177}
141178
142179/* Callback from IPCC Interrupt Handler: new message received from Master Processor */
143180void IPCC_channel2_callback (IPCC_HandleTypeDef * hipcc ,
144181 uint32_t ChannelIndex , IPCC_CHANNELDirTypeDef ChannelDir )
145182{
146- (void ) hipcc ;
147- (void ) ChannelIndex ;
148- (void ) ChannelDir ;
149- /* Don't inform A7 here, do it when the buffer has more than RPMSG_BUFFER_SIZE.
150- * See MAILBOX_Notify_Rx_Buf_Free() and VirIOSerial.cpp.
151- */
152- rproc_virtio_notified (rvdev .vdev , VRING1_ID );
153- /* The OpenAMP framework does not notify for free buf: do it here */
154- rproc_virtio_notified (NULL , VRING1_ID );
183+ msg_received_ch2 = RX_NEW_MSG ;
184+
185+ /* Don't inform A7 here */
186+ HAL_IPCC_NotifyCPU (hipcc , ChannelIndex , IPCC_CHANNEL_DIR_RX );
155187}
156188
157189/**
0 commit comments