1 /**
2 ******************************************************************************
3 * @file openamp.c
4 * @author MCD Application Team
5 * @brief Code for openamp applications
6 ******************************************************************************
7 * @attention
8 *
9 * <h2><center>© 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