f86734924676aabdd90dc6833478713266bd3fab
1 /*
2 * Copyright (c) 2013-2014, 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;
166 static UInt32 seqNum = 0;
167 Bool done = FALSE;
169 GateMutex_Handle gateMutex = NameServerRemoteRpmsg_module->gateMutex;
171 /* enter gate - prevent multiple threads from entering */
172 key = GateMutex_enter(gateMutex);
174 /* Check that host NameServer is alive to avoid pinging the host: */
175 if (NameServerRemoteRpmsg_module->nsPort == NAME_SERVER_PORT_INVALID) {
176 status = NameServer_E_NOTFOUND;
177 goto exit;
178 }
180 Log_print1(Diags_INFO, FXNN": name: %s", (IArg)name);
182 /* Create request message and send to remote processor: */
183 msg.request = NameServerRemoteRpmsg_REQUEST;
184 msg.requestStatus = 0;
185 msg.valueLen = *valueLen;
186 msg.seqNum = seqNum++;
188 len = strlen(instanceName);
189 Assert_isTrue(len < MAXNAMEINCHAR, NameServerRemoteRpmsg_A_nameIsTooLong);
190 strncpy((Char *)msg.instanceName, instanceName, MAXNAMEINCHAR - 1);
191 ((Char *)msg.instanceName)[MAXNAMEINCHAR - 1] = '\0';
193 len = strlen(name);
194 Assert_isTrue(len < MAXNAMEINCHAR, NameServerRemoteRpmsg_A_nameIsTooLong);
195 strncpy((Char *)msg.name, name, MAXNAMEINCHAR - 1);
196 ((Char *)msg.name)[MAXNAMEINCHAR - 1] = '\0';
198 Log_print3(Diags_INFO, FXNN": Requesting from procId %d, %s:%s...\n",
199 obj->remoteProcId, (IArg)msg.instanceName, (IArg)msg.name);
200 RPMessage_send(obj->remoteProcId, NameServerRemoteRpmsg_module->nsPort,
201 RPMSG_MESSAGEQ_PORT, (Ptr)&msg, sizeof(msg));
203 while (!done) {
204 /* Now pend for response */
205 status = Semaphore_pend(semRemoteWait, NameServerRemoteRpmsg_timeout);
207 if (status == FALSE) {
208 Log_print0(Diags_INFO, FXNN": Wait for NS reply timed out\n");
209 /* return timeout failure */
210 return (NameServer_E_TIMEOUT);
211 }
213 /* get the message */
214 replyMsg = NameServerRemoteRpmsg_module->nsMsg;
216 if (replyMsg->seqNum != seqNum - 1) {
217 /* Ignore responses without current sequence # */
218 continue;
219 }
221 if (replyMsg->requestStatus) {
222 /* name is found */
224 /* set length to amount of data that was copied */
225 *valueLen = replyMsg->valueLen;
227 /* set the contents of value */
228 if (*valueLen <= sizeof (Bits32)) {
229 memcpy(value, &(replyMsg->value), sizeof(Bits32));
230 }
231 else {
232 memcpy(value, replyMsg->valueBuf, *valueLen);
233 }
235 /* set the status to success */
236 status = NameServer_S_SUCCESS;
237 Log_print4(Diags_INFO, FXNN": Reply from: %d, %s:%s, value: 0x%x...\n",
238 obj->remoteProcId, (IArg)msg.instanceName, (IArg)msg.name,
239 *(UInt32 *)value);
240 }
241 else {
242 /* name is not found */
243 Log_print2(Diags_INFO, FXNN": value for %s:%s not found.\n",
244 (IArg)msg.instanceName, (IArg)msg.name);
246 /* set status to not found */
247 status = NameServer_E_NOTFOUND;
248 }
249 done = TRUE;
250 }
252 exit:
253 /* leave the gate */
254 GateMutex_leave(gateMutex, key);
256 return (status);
257 }
258 #undef FXNN
260 /*
261 * ======== NameServerRemoteRpmsg_sharedMemReq ========
262 */
263 SizeT NameServerRemoteRpmsg_sharedMemReq(Ptr sharedAddr)
264 {
265 return (0);
266 }
268 #define FXNN "NameServerRemote_processMessage"
269 void NameServerRemote_processMessage(NameServerRemote_Msg * msg)
270 {
271 NameServer_Handle handle;
272 Int status = NameServer_E_FAIL;
273 Semaphore_Handle semRemoteWait =
274 NameServerRemoteRpmsg_module->semRemoteWait;
275 UInt16 dstProc = MultiProc_getId("HOST");
277 Assert_isTrue(msg != NULL, NULL);
278 Assert_isTrue(msg->valueLen <= MAXVALUELEN, NULL);
280 if (msg->request == NameServerRemoteRpmsg_REQUEST) {
281 Log_print1(Diags_INFO, FXNN": Request from procId %d.\n", dstProc);
283 /*
284 * Message is a request. Lookup name in NameServer table.
285 * Send a response message back to source processor.
286 */
287 handle = NameServer_getHandle((String)msg->instanceName);
289 if (handle != NULL) {
290 /* Search for the NameServer entry */
291 if (msg->valueLen <= sizeof (Bits32)) {
292 status = NameServer_getLocalUInt32(handle,
293 (String)msg->name, &msg->value);
294 }
295 else {
296 status = NameServer_getLocal(handle, (String)msg->name,
297 (Ptr)msg->valueBuf, &msg->valueLen);
298 }
299 }
301 /* set the request status */
302 if (status < 0) {
303 Log_print2(Diags_INFO, FXNN": Replying with: %s:%s not found\n",
304 (IArg)msg->instanceName, (IArg)msg->name);
305 msg->requestStatus = 0;
306 }
307 else {
308 Log_print3(Diags_INFO, FXNN": Replying with: %s:%s, value: 0x%x\n",
309 (IArg)msg->instanceName, (IArg)msg->name, msg->value);
310 msg->requestStatus = 1;
311 }
313 /* specify message as a response */
314 msg->request = NameServerRemoteRpmsg_RESPONSE;
316 /* send response message to remote processor */
317 RPMessage_send(dstProc, NameServerRemoteRpmsg_module->nsPort,
318 RPMSG_MESSAGEQ_PORT, (Ptr)msg, sizeof(NameServerRemote_Msg));
319 }
320 else {
321 Log_print0(Diags_INFO, FXNN": NameServer Reply. Posting Sem...\n");
323 /* Save the response message. */
324 memcpy(NameServerRemoteRpmsg_module->nsMsg, msg,
325 sizeof (NameServerRemote_Msg));
326 /* Post the semaphore upon which NameServer_get() is waiting */
327 Semaphore_post(semRemoteWait);
328 }
329 }
330 #undef FXNN
332 #define FXNN "NameServerRemote_SetNameServerPort"
333 void NameServerRemote_SetNameServerPort(UInt port)
334 {
335 Log_print1(Diags_INFO, FXNN": nsPort: %d", port);
336 NameServerRemoteRpmsg_module->nsPort = port;
337 }
338 #undef FXNN