9ec68390b491912cd5d558e80974526a4677fe6d
1 /*
2 * Copyright (c) 2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * ======== NameServerRemoteRpmsg.c ========
34 */
36 #include <xdc/std.h>
37 #include <string.h>
39 #include <xdc/runtime/Assert.h>
40 #include <xdc/runtime/Error.h>
41 #include <xdc/runtime/Log.h>
42 #include <xdc/runtime/Diags.h>
43 #include <xdc/runtime/knl/ISync.h>
45 #include <ti/sysbios/gates/GateMutex.h>
46 #include <ti/sysbios/knl/Semaphore.h>
47 #include <ti/sdo/utils/_NameServer.h>
48 #include <ti/sdo/utils/INameServerRemote.h>
49 #include <ti/ipc/MultiProc.h>
50 #include <ti/ipc/namesrv/_NameServerRemoteRpmsg.h>
51 #include <ti/ipc/rpmsg/RPMessage.h>
53 #include "package/internal/NameServerRemoteRpmsg.xdc.h"
55 /* Storage for NameServer message replies. Protected by gateMutex: */
56 static NameServerRemote_Msg NameServer_msg;
58 /*
59 *************************************************************************
60 * Instance functions
61 *************************************************************************
62 */
63 #define FXNN "NameServerRemoteRpmsg_Instance_init"
64 Void NameServerRemoteRpmsg_Instance_init(NameServerRemoteRpmsg_Object *obj,
65 UInt16 remoteProcId,
66 const NameServerRemoteRpmsg_Params *params)
67 {
69 Log_print1(Diags_INFO, FXNN": remoteProc: %d", remoteProcId);
71 obj->remoteProcId = remoteProcId;
73 NameServerRemoteRpmsg_module->nsMsg = &NameServer_msg;
75 /* register the remote driver with NameServer */
76 ti_sdo_utils_NameServer_registerRemoteDriver(
77 NameServerRemoteRpmsg_Handle_upCast(obj), remoteProcId);
78 }
79 #undef FXNN
81 /*
82 * ======== NameServerRemoteRpmsg_Instance_finalize ========
83 */
84 Void NameServerRemoteRpmsg_Instance_finalize(NameServerRemoteRpmsg_Object *obj)
85 {
86 /* unregister remote driver from NameServer module */
87 ti_sdo_utils_NameServer_unregisterRemoteDriver(obj->remoteProcId);
88 }
90 /*
91 *************************************************************************
92 * Module functions
93 *************************************************************************
94 */
96 /*
97 * ======== NameServerRemoteRpmsg_attach ========
98 *
99 * Typically called from Ipc_attach(), but since Rpmsg doesn't use Ipc
100 * module, this may need to be called manually.
101 */
102 #define FXNN "NameServerRemoteRpmsg_attach"
103 Int NameServerRemoteRpmsg_attach(UInt16 remoteProcId, Ptr sharedAddr)
104 {
105 Int status = NameServerRemoteRpmsg_E_FAIL;
106 NameServerRemoteRpmsg_Handle handle;
108 Log_print1(Diags_INFO, FXNN": remoteProcId: %d", remoteProcId);
110 handle = NameServerRemoteRpmsg_create(remoteProcId, NULL, NULL);
111 if (handle != NULL) {
112 status = NameServerRemoteRpmsg_S_SUCCESS;
113 }
115 return (status);
116 }
117 #undef FXNN
119 /*
120 * ======== NameServerRemoteRpmsg_detach ========
121 *
122 * Typically called from Ipc_detach(), but since Rpmsg doesn't use Ipc
123 * module, this may need to be called manually.
124 */
125 #define FXNN "NameServerRemoteRpmsg_detach"
126 Int NameServerRemoteRpmsg_detach(UInt16 remoteProcId)
127 {
128 NameServerRemoteRpmsg_Handle handle;
129 Int status = NameServerRemoteRpmsg_S_SUCCESS;
131 Log_print1(Diags_INFO, FXNN": remoteProcId: %d", remoteProcId);
133 for (handle = NameServerRemoteRpmsg_Object_first(); handle != NULL;
134 handle = NameServerRemoteRpmsg_Object_next(handle)) {
135 if (handle->remoteProcId == remoteProcId) {
136 break;
137 }
138 }
140 if (handle == NULL) {
141 status = NameServerRemoteRpmsg_E_FAIL;
142 }
143 else {
144 NameServerRemoteRpmsg_delete(&handle);
145 }
147 return (status);
148 }
149 #undef FXNN
151 /*
152 * ======== NameServerRemoteRpmsg_get ========
153 */
154 #define FXNN "NameServerRemoteRpmsg_get"
155 Int NameServerRemoteRpmsg_get(NameServerRemoteRpmsg_Object *obj,
156 String instanceName, String name, Ptr value, UInt32 *valueLen,
157 ISync_Handle syncHandle, Error_Block *eb)
158 {
159 Int status = NameServer_E_NOTFOUND;
160 Int len;
161 IArg key;
162 NameServerRemote_Msg msg;
163 NameServerRemote_Msg *replyMsg;
164 Semaphore_Handle semRemoteWait =
165 NameServerRemoteRpmsg_module->semRemoteWait;
167 GateMutex_Handle gateMutex = NameServerRemoteRpmsg_module->gateMutex;
169 /* enter gate - prevent multiple threads from entering */
170 key = GateMutex_enter(gateMutex);
172 /* Check that host NameServer is alive to avoid pinging the host: */
173 if (NameServerRemoteRpmsg_module->nsPort == NAME_SERVER_PORT_INVALID) {
174 status = NameServer_E_NOTFOUND;
175 goto exit;
176 }
178 Log_print1(Diags_INFO, FXNN": name: %s", (IArg)name);
180 /* Create request message and send to remote processor: */
181 msg.request = NameServerRemoteRpmsg_REQUEST;
182 msg.requestStatus = 0;
183 msg.valueLen = *valueLen;
185 len = strlen(instanceName);
186 Assert_isTrue(len < MAXNAMEINCHAR, NameServerRemoteRpmsg_A_nameIsTooLong);
187 strncpy((Char *)msg.instanceName, instanceName, MAXNAMEINCHAR);
188 ((Char *)msg.instanceName)[MAXNAMEINCHAR - 1] = '\0';
190 len = strlen(name);
191 Assert_isTrue(len < MAXNAMEINCHAR, NameServerRemoteRpmsg_A_nameIsTooLong);
192 strncpy((Char *)msg.name, name, MAXNAMEINCHAR);
193 ((Char *)msg.name)[MAXNAMEINCHAR - 1] = '\0';
195 Log_print3(Diags_INFO, FXNN": Requesting from procId %d, %s:%s...\n",
196 obj->remoteProcId, (IArg)msg.instanceName, (IArg)msg.name);
197 RPMessage_send(obj->remoteProcId, NameServerRemoteRpmsg_module->nsPort,
198 RPMSG_MESSAGEQ_PORT, (Ptr)&msg, sizeof(msg));
200 /* Now pend for response */
201 status = Semaphore_pend(semRemoteWait, NameServerRemoteRpmsg_timeout);
203 if (status == FALSE) {
204 Log_print0(Diags_INFO, FXNN": Wait for NS reply timed out\n");
205 /* return timeout failure */
206 return (NameServer_E_TIMEOUT);
207 }
209 /* get the message */
210 replyMsg = NameServerRemoteRpmsg_module->nsMsg;
212 if (replyMsg->requestStatus) {
213 /* name is found */
215 /* set length to amount of data that was copied */
216 *valueLen = replyMsg->valueLen;
218 /* set the contents of value */
219 if (*valueLen <= sizeof (Bits32)) {
220 memcpy(value, &(replyMsg->value), sizeof(Bits32));
221 }
222 else {
223 memcpy(value, replyMsg->valueBuf, *valueLen);
224 }
226 /* set the status to success */
227 status = NameServer_S_SUCCESS;
228 Log_print4(Diags_INFO, FXNN": Reply from: %d, %s:%s, value: 0x%x...\n",
229 obj->remoteProcId, (IArg)msg.instanceName, (IArg)msg.name,
230 *(UInt32 *)value);
231 }
232 else {
233 /* name is not found */
234 Log_print2(Diags_INFO, FXNN": value for %s:%s not found.\n",
235 (IArg)msg.instanceName, (IArg)msg.name);
237 /* set status to not found */
238 status = NameServer_E_NOTFOUND;
239 }
241 exit:
242 /* leave the gate */
243 GateMutex_leave(gateMutex, key);
245 return (status);
246 }
247 #undef FXNN
249 /*
250 * ======== NameServerRemoteRpmsg_sharedMemReq ========
251 */
252 SizeT NameServerRemoteRpmsg_sharedMemReq(Ptr sharedAddr)
253 {
254 return (0);
255 }
257 #define FXNN "NameServerRemote_processMessage"
258 void NameServerRemote_processMessage(NameServerRemote_Msg * msg)
259 {
260 NameServer_Handle handle;
261 Int status = NameServer_E_FAIL;
262 Semaphore_Handle semRemoteWait =
263 NameServerRemoteRpmsg_module->semRemoteWait;
264 UInt16 dstProc = MultiProc_getId("HOST");
266 Assert_isTrue(msg != NULL, NULL);
267 Assert_isTrue(msg->valueLen <= MAXVALUELEN, NULL);
269 if (msg->request == NameServerRemoteRpmsg_REQUEST) {
270 Log_print1(Diags_INFO, FXNN": Request from procId %d.\n", dstProc);
272 /*
273 * Message is a request. Lookup name in NameServer table.
274 * Send a response message back to source processor.
275 */
276 handle = NameServer_getHandle((String)msg->instanceName);
278 if (handle != NULL) {
279 /* Search for the NameServer entry */
280 if (msg->valueLen <= sizeof (Bits32)) {
281 status = NameServer_getLocalUInt32(handle,
282 (String)msg->name, &msg->value);
283 }
284 else {
285 status = NameServer_getLocal(handle, (String)msg->name,
286 (Ptr)msg->valueBuf, &msg->valueLen);
287 }
288 }
290 /* set the request status */
291 if (status < 0) {
292 Log_print2(Diags_INFO, FXNN": Replying with: %s:%s not found\n",
293 (IArg)msg->instanceName, (IArg)msg->name);
294 msg->requestStatus = 0;
295 }
296 else {
297 Log_print3(Diags_INFO, FXNN": Replying with: %s:%s, value: 0x%x\n",
298 (IArg)msg->instanceName, (IArg)msg->name, msg->value);
299 msg->requestStatus = 1;
300 }
302 /* specify message as a response */
303 msg->request = NameServerRemoteRpmsg_RESPONSE;
305 /* send response message to remote processor */
306 RPMessage_send(dstProc, NameServerRemoteRpmsg_module->nsPort,
307 RPMSG_MESSAGEQ_PORT, (Ptr)msg, sizeof(NameServerRemote_Msg));
308 }
309 else {
310 Log_print0(Diags_INFO, FXNN": NameServer Reply. Posting Sem...\n");
312 /* Save the response message. */
313 memcpy(NameServerRemoteRpmsg_module->nsMsg, msg,
314 sizeof (NameServerRemote_Msg));
315 /* Post the semaphore upon which NameServer_get() is waiting */
316 Semaphore_post(semRemoteWait);
317 }
318 }
319 #undef FXNN
321 #define FXNN "NameServerRemote_SetNameServerPort"
322 void NameServerRemote_SetNameServerPort(UInt port)
323 {
324 Log_print1(Diags_INFO, FXNN": nsPort: %d", port);
325 NameServerRemoteRpmsg_module->nsPort = port;
326 }
327 #undef FXNN