1 /**
2   ******************************************************************************
3   * @file   openamp.c
4   * @author  MCD Application Team
5   * @brief  Code for openamp applications
6   ******************************************************************************
7   * @attention
8   *
9   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
10   * All rights reserved.</center></h2>
11   *
12   * This software component is licensed by ST under BSD 3-Clause license,
13   * the "License"; You may not use this file except in compliance with the
14   * License. You may obtain a copy of the License at:
15   *                       opensource.org/licenses/BSD-3-Clause
16   *
17   ******************************************************************************
18   */
19 
20 #include "openamp.h"
21 #include "rsc_table.h"
22 #include "metal/sys.h"
23 #include "metal/device.h"
24 /* Private define ------------------------------------------------------------*/
25 
26 #define SHM_DEVICE_NAME         "STM32_SHM"
27 
28 /* Globals */
29 
30 static struct metal_io_region *shm_io;
31 static struct metal_io_region *rsc_io;
32 static struct shared_resource_table *rsc_table;
33 static struct rpmsg_virtio_shm_pool shpool;
34 static struct rpmsg_virtio_device rvdev;
35 
36 static metal_phys_addr_t shm_physmap;
37 
38 struct metal_device shm_device = {
39   .name = SHM_DEVICE_NAME,
40   .num_regions = 2,
41   .regions = {
42       {.virt = NULL}, /* shared memory */
43       {.virt = NULL}, /* rsc_table memory */
44   },
45   .node = { NULL },
46   .irq_num = 0,
47   .irq_info = NULL
48 };
49 
OPENAMP_shmem_init(int RPMsgRole)50 static int OPENAMP_shmem_init(int RPMsgRole)
51 {
52   int status = 0;
53   struct metal_device *device;
54   struct metal_init_params metal_params = METAL_INIT_DEFAULTS;
55   void* rsc_tab_addr;
56   int rsc_size;
57 
58   metal_init(&metal_params);
59 
60   status = metal_register_generic_device(&shm_device);
61   if (status != 0) {
62     return status;
63   }
64 
65   status = metal_device_open("generic", SHM_DEVICE_NAME, &device);
66   if (status != 0) {
67     return status;
68   }
69 
70   shm_physmap = SHM_START_ADDRESS;
71   metal_io_init(&device->regions[0], (void *)SHM_START_ADDRESS, &shm_physmap,
72                 SHM_SIZE, -1, 0, NULL);
73 
74   shm_io = metal_device_io_region(device, 0);
75   if (shm_io == NULL) {
76     return -1;
77   }
78 
79   /* Initialize resources table variables */
80   resource_table_init(RPMsgRole, &rsc_tab_addr, &rsc_size);
81   rsc_table = (struct shared_resource_table *)rsc_tab_addr;
82   if (!rsc_table)
83   {
84     return -1;
85   }
86 
87   metal_io_init(&device->regions[1], rsc_table,
88                (metal_phys_addr_t *)rsc_table, rsc_size, -1U, 0, NULL);
89 
90   rsc_io = metal_device_io_region(device, 1);
91   if (rsc_io == NULL) {
92     return -1;
93   }
94 
95   return 0;
96 }
97 
MX_OPENAMP_Init(int RPMsgRole,rpmsg_ns_bind_cb ns_bind_cb)98 int MX_OPENAMP_Init(int RPMsgRole, rpmsg_ns_bind_cb ns_bind_cb)
99 {
100   struct fw_rsc_vdev_vring *vring_rsc;
101   struct virtio_device *vdev;
102   int status = 0;
103 
104   MAILBOX_Init();
105 
106   /* Libmetal Initilalization */
107   status = OPENAMP_shmem_init(RPMsgRole);
108   if(status)
109   {
110     return status;
111   }
112 
113   vdev = rproc_virtio_create_vdev(RPMsgRole, VDEV_ID, &rsc_table->vdev,
114                                   rsc_io, NULL, MAILBOX_Notify, NULL);
115   if (vdev == NULL)
116   {
117     return -1;
118   }
119 
120   rproc_virtio_wait_remote_ready(vdev);
121   vring_rsc = &rsc_table->vring0;
122   status = rproc_virtio_init_vring(vdev, 0, vring_rsc->notifyid,
123                                    (void *)vring_rsc->da, shm_io,
124                                    vring_rsc->num, vring_rsc->align);
125   if (status != 0)
126   {
127     return status;
128   }
129   vring_rsc = &rsc_table->vring1;
130   status = rproc_virtio_init_vring(vdev, 1, vring_rsc->notifyid,
131                                    (void *)vring_rsc->da, shm_io,
132                                    vring_rsc->num, vring_rsc->align);
133   if (status != 0)
134   {
135     return status;
136   }
137 
138   rpmsg_virtio_init_shm_pool(&shpool, (void *)VRING_BUFF_ADDRESS,
139                              (size_t)SHM_SIZE);
140   rpmsg_init_vdev(&rvdev, vdev, ns_bind_cb, shm_io, &shpool);
141 
142   return 0;
143 }
144 
OPENAMP_DeInit()145 void OPENAMP_DeInit()
146 {
147   rpmsg_deinit_vdev(&rvdev);
148 
149   metal_finish();
150 }
151 
OPENAMP_init_ept(struct rpmsg_endpoint * ept)152 void OPENAMP_init_ept(struct rpmsg_endpoint *ept)
153 {
154   rpmsg_init_ept(ept, "", RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, NULL, NULL);
155 }
156 
OPENAMP_create_endpoint(struct rpmsg_endpoint * ept,const char * name,uint32_t dest,rpmsg_ept_cb cb,rpmsg_ns_unbind_cb unbind_cb)157 int OPENAMP_create_endpoint(struct rpmsg_endpoint *ept, const char *name,
158                             uint32_t dest, rpmsg_ept_cb cb,
159                             rpmsg_ns_unbind_cb unbind_cb)
160 {
161   return rpmsg_create_ept(ept, &rvdev.rdev, name, RPMSG_ADDR_ANY, dest, cb,
162 		          unbind_cb);
163 }
164 
OPENAMP_check_for_message(void)165 void OPENAMP_check_for_message(void)
166 {
167   MAILBOX_Poll(rvdev.vdev);
168 }
169 
OPENAMP_Wait_EndPointready(struct rpmsg_endpoint * rp_ept)170 void OPENAMP_Wait_EndPointready(struct rpmsg_endpoint *rp_ept)
171 {
172   while(!is_rpmsg_ept_ready(rp_ept))
173   MAILBOX_Poll(rvdev.vdev);
174 }
175 
176 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
177