b0f08e59c93e598ed22f89b1e4f626875ccd4045
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;
184 len = strlen(instanceName);
185 Assert_isTrue(len < MAXNAMEINCHAR, NameServerRemoteRpmsg_A_nameIsTooLong);
186 strncpy((Char *)msg.instanceName, instanceName, len);
188 len = strlen(name);
189 Assert_isTrue(len < MAXNAMEINCHAR, NameServerRemoteRpmsg_A_nameIsTooLong);
190 strncpy((Char *)msg.name, name, len);
192 Log_print3(Diags_INFO, FXNN": Requesting from procId %d, %s:%s...\n",
193 obj->remoteProcId, (IArg)msg.instanceName, (IArg)msg.name);
194 RPMessage_send(obj->remoteProcId, NameServerRemoteRpmsg_module->nsPort,
195 RPMSG_MESSAGEQ_PORT, (Ptr)&msg, sizeof(msg));
197 /* Now pend for response */
198 status = Semaphore_pend(semRemoteWait, NameServerRemoteRpmsg_timeout);
200 if (status == FALSE) {
201 Log_print0(Diags_INFO, FXNN": Wait for NS reply timed out\n");
202 /* return timeout failure */
203 return (NameServer_E_OSFAILURE);
204 }
206 /* get the message */
207 replyMsg = NameServerRemoteRpmsg_module->nsMsg;
209 if (replyMsg->requestStatus) {
210 /* name is found */
212 /* set length to amount of data that was copied */
213 *valueLen = sizeof(Bits32);
215 /* set the contents of value */
216 memcpy(value, &(replyMsg->value), sizeof(Bits32));
218 /* set the status to success */
219 status = NameServer_S_SUCCESS;
220 Log_print4(Diags_INFO, FXNN": Reply from: %d, %s:%s, value: 0x%x...\n",
221 obj->remoteProcId, (IArg)msg.instanceName, (IArg)msg.name,
222 *(UInt32 *)value);
223 }
224 else {
225 /* name is not found */
226 Log_print2(Diags_INFO, FXNN": value for %s:%s not found.\n",
227 (IArg)msg.instanceName, (IArg)msg.name);
229 /* set status to not found */
230 status = NameServer_E_NOTFOUND;
231 }
233 exit:
234 /* leave the gate */
235 GateMutex_leave(gateMutex, key);
237 return (status);
238 }
239 #undef FXNN
241 /*
242 * ======== NameServerRemoteRpmsg_sharedMemReq ========
243 */
244 SizeT NameServerRemoteRpmsg_sharedMemReq(Ptr sharedAddr)
245 {
246 return (0);
247 }
249 #define FXNN "NameServerRemote_processMessage"
250 void NameServerRemote_processMessage(NameServerRemote_Msg * msg)
251 {
252 NameServer_Handle handle;
253 Int status = NameServer_E_FAIL;
254 Semaphore_Handle semRemoteWait =
255 NameServerRemoteRpmsg_module->semRemoteWait;
256 UInt16 dstProc = MultiProc_getId("HOST");
258 Assert_isTrue(msg != NULL, NULL);
260 if (msg->request == NameServerRemoteRpmsg_REQUEST) {
261 Log_print1(Diags_INFO, FXNN": Request from procId %d.\n", dstProc);
263 /*
264 * Message is a request. Lookup name in NameServer table.
265 * Send a response message back to source processor.
266 */
267 handle = NameServer_getHandle((String)msg->instanceName);
269 if (handle != NULL) {
270 /* Search for the NameServer entry */
271 status = NameServer_getLocalUInt32(handle,
272 (String)msg->name, &msg->value);
273 }
275 /* set the request status */
276 if (status < 0) {
277 Log_print2(Diags_INFO, FXNN": Replying with: %s:%s not found\n",
278 (IArg)msg->instanceName, (IArg)msg->name);
279 msg->requestStatus = 0;
280 }
281 else {
282 Log_print3(Diags_INFO, FXNN": Replying with: %s:%s, value: 0x%x\n",
283 (IArg)msg->instanceName, (IArg)msg->name, msg->value);
284 msg->requestStatus = 1;
285 }
287 /* specify message as a response */
288 msg->request = NameServerRemoteRpmsg_RESPONSE;
290 /* send response message to remote processor */
291 RPMessage_send(dstProc, NameServerRemoteRpmsg_module->nsPort,
292 RPMSG_MESSAGEQ_PORT, (Ptr)msg, sizeof(NameServerRemote_Msg));
293 }
294 else {
295 Log_print0(Diags_INFO, FXNN": NameServer Reply. Posting Sem...\n");
297 /* Save the response message. */
298 memcpy(NameServerRemoteRpmsg_module->nsMsg, msg,
299 sizeof (NameServerRemote_Msg));
300 /* Post the semaphore upon which NameServer_get() is waiting */
301 Semaphore_post(semRemoteWait);
302 }
303 }
304 #undef FXNN
306 #define FXNN "NameServerRemote_SetNameServerPort"
307 void NameServerRemote_SetNameServerPort(UInt port)
308 {
309 Log_print1(Diags_INFO, FXNN": nsPort: %d", port);
310 NameServerRemoteRpmsg_module->nsPort = port;
311 }
312 #undef FXNN