]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - qnx/src/ipc3x_dev/ti/syslink/utils/hlos/knl/MultiProc.c
5aa8281c0887b5b21f6a5f64d97b25fac7f9f823
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / utils / hlos / knl / MultiProc.c
1 /*
2  *  @file   MultiProc.c
3  *
4  *  @brief      Handles processor id management in multi processor systems.Used
5  *              by all modules which need processor ids for their oprations.
6  *
7  *
8  *  @ver        02.00.00.46_alpha1
9  *
10  *  ============================================================================
11  *
12  *  Copyright (c) 2008-2015, Texas Instruments Incorporated
13  *
14  *  Redistribution and use in source and binary forms, with or without
15  *  modification, are permitted provided that the following conditions
16  *  are met:
17  *
18  *  *  Redistributions of source code must retain the above copyright
19  *     notice, this list of conditions and the following disclaimer.
20  *
21  *  *  Redistributions in binary form must reproduce the above copyright
22  *     notice, this list of conditions and the following disclaimer in the
23  *     documentation and/or other materials provided with the distribution.
24  *
25  *  *  Neither the name of Texas Instruments Incorporated nor the names of
26  *     its contributors may be used to endorse or promote products derived
27  *     from this software without specific prior written permission.
28  *
29  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
30  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
31  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
33  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
34  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
35  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
36  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
37  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
38  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
39  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *  Contact information for paper mail:
41  *  Texas Instruments
42  *  Post Office Box 655303
43  *  Dallas, Texas 75265
44  *  Contact information:
45  *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
46  *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
47  *  ============================================================================
48  *
49  */
52 /* Standard headers */
53 #include <ti/syslink/Std.h>
55 /* OSAL & Utils headers */
56 #include <ti/syslink/utils/Trace.h>
57 #include <ti/syslink/utils/Memory.h>
58 #include <ti/syslink/utils/String.h>
59 #include <Bitops.h>
61 /* Module level headers */
62 #include <_MultiProc.h>
63 #include <ti/ipc/MultiProc.h>
66 #if defined (__cplusplus)
67 extern "C" {
68 #endif
71 /* =============================================================================
72  *  Macros and types
73  * =============================================================================
74  */
75 /* Macro to make a correct module magic number with refCount */
76 #define MultiProc_MAKE_MAGICSTAMP(x) ((MultiProc_MODULEID << 12u) | (x))
78 /*!
79  *  @brief  MultiProc Module state object
80  */
81 typedef struct MultiProc_ModuleObject_tag {
82     MultiProc_Config cfg;
83     /*!< Notify configuration structure */
84     MultiProc_Config defCfg;
85     /*!< Default module configuration */
86     Atomic           refCount;
87     /* Reference count */
88     UInt16           id;
89     /* Local processor ID */
90 } MultiProc_ModuleObject;
93 /* =============================================================================
94  *  Extern declarations
95  * =============================================================================
96  */
97 #if !defined(IPC_BUILD_DEBUG)
98 static
99 #endif /* if !defined(IPC_BUILD_DEBUG) */
100 MultiProc_ModuleObject MultiProc_state = {
101     .defCfg.numProcessors     = 1u,
102     .defCfg.id                = 0u,
103     .id                       = MultiProc_INVALIDID
104 };
106 /*!
107  *  @var    MultiProc_module
108  *
109  *  @brief  Pointer to the MultiProc module state.
110  */
111 #if !defined(IPC_BUILD_DEBUG)
112 static
113 #endif /* if !defined(IPC_BUILD_DEBUG) */
114 MultiProc_ModuleObject * MultiProc_module = &MultiProc_state;
117 /* =============================================================================
118  *  APIs
119  * =============================================================================
120  */
121 /* Get the default configuration for the MultiProc module. */
122 Void
123 MultiProc_getConfig (MultiProc_Config * cfg)
125     GT_1trace (curTrace, GT_ENTER, "MultiProc_getConfig", cfg);
127     GT_assert (curTrace, (cfg != NULL));
129 #if !defined(IPC_BUILD_OPTIMIZE)
130     if (EXPECT_FALSE (cfg == NULL)) {
131         GT_setFailureReason (curTrace,
132                              GT_4CLASS,
133                              "MultiProc_getConfig",
134                              MultiProc_E_INVALIDARG,
135                              "Argument of type (MultiProc_Config *) passed "
136                              "is null!");
137     }
138     else {
139 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
140         if (EXPECT_TRUE (  Atomic_cmpmask_and_lt (&(MultiProc_module->refCount),
141                                                   MultiProc_MAKE_MAGICSTAMP(0),
142                                                   MultiProc_MAKE_MAGICSTAMP(1))
143                         == TRUE)) {
144             /* (If setup has not yet been called) */
145             Memory_copy (cfg,
146                          &MultiProc_module->defCfg,
147                          sizeof (MultiProc_Config));
148         }
149         else {
150             Memory_copy (cfg,
151                          &MultiProc_module->cfg,
152                          sizeof (MultiProc_Config));
153         }
154 #if !defined(IPC_BUILD_OPTIMIZE)
155     }
156 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
158     GT_0trace (curTrace, GT_LEAVE, "MultiProc_getConfig");
162 /* Setup the MultiProc module. */
163 Int
164 MultiProc_setup (MultiProc_Config * cfg)
166     Int              status = MultiProc_S_SUCCESS;
167     MultiProc_Config tmpCfg;
169     GT_1trace (curTrace, GT_ENTER, "MultiProc_setup", cfg);
171     /* This sets the refCount variable is not initialized, upper 16 bits is
172      * written with module Id to ensure correctness of refCount variable.
173      */
174     Atomic_cmpmask_and_set (&MultiProc_module->refCount,
175                             MultiProc_MAKE_MAGICSTAMP(0),
176                             MultiProc_MAKE_MAGICSTAMP(0));
178     if (   Atomic_inc_return (&MultiProc_module->refCount)
179         != MultiProc_MAKE_MAGICSTAMP(1u)) {
180         status = MultiProc_S_ALREADYSETUP;
181         GT_0trace (curTrace,
182                    GT_2CLASS,
183                    "MultiProc Module already initialized!");
184     }
185     else {
186         if (cfg == NULL) {
187             MultiProc_getConfig (&tmpCfg);
188             cfg = &tmpCfg;
189         }
191         Memory_copy (&MultiProc_module->cfg, cfg, sizeof (MultiProc_Config));
192         MultiProc_module->id = cfg->id;
193     }
195     GT_1trace (curTrace, GT_LEAVE, "MultiProc_setup", status);
197     /*! @retval MultiProc_S_SUCCESS Operation successful */
198     return (status);
202 /* Destroy the MultiProc module. */
203 Int
204 MultiProc_destroy (Void)
206     Int status = MultiProc_S_SUCCESS;
208     GT_0trace (curTrace, GT_ENTER, "MultiProc_destroy");
210 #if !defined(IPC_BUILD_OPTIMIZE)
211     if (   Atomic_cmpmask_and_lt (&(MultiProc_module->refCount),
212                                   MultiProc_MAKE_MAGICSTAMP(0),
213                                   MultiProc_MAKE_MAGICSTAMP(1))
214         == TRUE) {
215         /*! @retval MultiProc_E_INVALIDSTATE Module was not initialized */
216         status = MultiProc_E_INVALIDSTATE;
217         GT_setFailureReason (curTrace,
218                              GT_4CLASS,
219                              "MultiProc_destroy",
220                              status,
221                              "Module was not initialized!");
222     }
223     else {
224 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
225         Atomic_dec_return (&MultiProc_module->refCount);
226 #if !defined(IPC_BUILD_OPTIMIZE)
227     }
228 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
230     GT_1trace (curTrace, GT_LEAVE, "MultiProc_destroy", status);
232     /*! @retval MultiProc_S_SUCCESS Operation successful */
233     return (status);
237 /* Function to set Local processor Id */
238 Int
239 MultiProc_setLocalId (UInt16 id)
241     Int status = MultiProc_S_SUCCESS;
243     GT_1trace (curTrace, GT_ENTER, "MultiProc_setLocalId", id);
245 #if !defined(IPC_BUILD_OPTIMIZE)
246     if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(MultiProc_module->refCount),
247                                                 MultiProc_MAKE_MAGICSTAMP(0),
248                                                 MultiProc_MAKE_MAGICSTAMP(1))
249                       == TRUE)) {
250         status = MultiProc_E_INVALIDSTATE;
251         GT_setFailureReason (curTrace,
252                              GT_4CLASS,
253                              "MultiProc_setLocalId",
254                              status,
255                              "Module was not initialized!");
256     }
257     else if (EXPECT_FALSE (id >= MultiProc_module->cfg.numProcessors)) {
258         status = MultiProc_E_INVALIDARG;
259         GT_setFailureReason (curTrace,
260                              GT_4CLASS,
261                              "MultiProc_setLocalId",
262                              MultiProc_E_INVALIDARG,
263                              "ID cannot be greater than or equal to"
264                              " numProcessors");
265     }
266     else if (EXPECT_FALSE (MultiProc_module->id != MultiProc_INVALIDID)) {
267         status = MultiProc_E_INVALIDARG;
268         GT_setFailureReason (curTrace,
269                              GT_4CLASS,
270                              "MultiProc_setLocalId",
271                              MultiProc_E_INVALIDARG,
272                              "Cannot change the ID after module"
273                              " startup");
274     }
275     else {
276 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
277         MultiProc_module->id = id;
278 #if !defined(IPC_BUILD_OPTIMIZE)
279     }
280 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
282     GT_1trace (curTrace, GT_LEAVE, "MultiProc_setLocalId", status);
284     return (status);
288 /* Function to get proccesor Id from proccessor name. */
289 UInt16
290 MultiProc_getId (String name)
292     Bool   found = FALSE;
293     UInt32 id    = MultiProc_INVALIDID;
294     Int    i;
296     GT_1trace (curTrace, GT_ENTER, "MultiProc_getId", name);
298 #if !defined(IPC_BUILD_OPTIMIZE)
299     if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(MultiProc_module->refCount),
300                                                  MultiProc_MAKE_MAGICSTAMP(0),
301                                                  MultiProc_MAKE_MAGICSTAMP(1))
302                        == TRUE)) {
303         GT_setFailureReason (curTrace,
304                              GT_4CLASS,
305                              "MultiProc_getId",
306                              MultiProc_E_INVALIDSTATE,
307                              "Module was not initialized!");
308     }
309     else {
310 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
311         /* If the name is NULL, simply return the local id */
312         if (EXPECT_FALSE (name == NULL)) {
313 #if !defined(IPC_BUILD_OPTIMIZE)
314             if (EXPECT_FALSE (MultiProc_module->id == MultiProc_INVALIDID)) {
315                 GT_setFailureReason (curTrace,
316                                  GT_4CLASS,
317                                  "MultiProc_getId",
318                                  MultiProc_E_INVALIDSTATE,
319                                  "MultiProc_localId not set to proper value");
320             }
321             else {
322 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
323                 GT_assert (curTrace,
324                            (MultiProc_module->id != MultiProc_INVALIDID));
325                 id = MultiProc_module->id;
326                 found = TRUE;
327 #if !defined(IPC_BUILD_OPTIMIZE)
328             }
329 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
330         }
331         else {
332             for (i = 0; i < MultiProc_module->cfg.numProcessors ; i++) {
333                 if (   String_cmp (name, &MultiProc_module->cfg.nameList [i][0])
334                     == 0) {
335                     id = i;
336                     found = TRUE;
337                     break;
338                 }
339             }
341 #if !defined(IPC_BUILD_OPTIMIZE)
342             if (EXPECT_FALSE (!found)) {
343                 GT_setFailureReason (curTrace,
344                                      GT_4CLASS,
345                                      "MultiProc_getId",
346                                      MultiProc_E_NOTFOUND,
347                                      "Processor name not found");
348             }
349 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
350         }
351 #if !defined(IPC_BUILD_OPTIMIZE)
352     }
353 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
355     GT_assert (curTrace, (found == TRUE));
357     GT_1trace (curTrace, GT_LEAVE, "MultiProc_getId", id);
359     return (id);
363 /* Function to get name from processor id. */
364 String
365 MultiProc_getName (UInt16 id)
367     String name = NULL;
369     GT_1trace (curTrace, GT_ENTER, "MultiProc_getName", id);
371     GT_assert (curTrace, (id < MultiProc_module->cfg.numProcessors));
373 #if !defined(IPC_BUILD_OPTIMIZE)
374     if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(MultiProc_module->refCount),
375                                                 MultiProc_MAKE_MAGICSTAMP(0),
376                                                 MultiProc_MAKE_MAGICSTAMP(1))
377                       == TRUE)) {
378         GT_setFailureReason (curTrace,
379                              GT_4CLASS,
380                              "MultiProc_getName",
381                              MultiProc_E_INVALIDSTATE,
382                              "Module was not initialized!");
383     }
384     else if (EXPECT_FALSE (id >= MultiProc_module->cfg.numProcessors)) {
385         GT_setFailureReason (curTrace,
386                     GT_4CLASS,
387                     "MultiProc_getName",
388                     MultiProc_E_INVALIDARG,
389                     "Processor id is not less than numProcessors");
390     }
391     else {
392 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
393         name = MultiProc_module->cfg.nameList [id];
394         GT_1trace (curTrace, GT_1CLASS, "MultiProc_getName [%s]", name);
395 #if !defined(IPC_BUILD_OPTIMIZE)
396     }
397 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
399     GT_0trace (curTrace, GT_LEAVE, "MultiProc_getName");
401     return (name);
405 /* Function to get maximum proc Id in the system. */
406 UInt16
407 MultiProc_getNumProcessors (Void)
409     GT_0trace (curTrace, GT_ENTER, "MultiProc_getNumProcessors");
410     GT_1trace (curTrace,
411                GT_LEAVE,
412                "MultiProc_getNumProcessors",
413                MultiProc_module->cfg.numProcessors);
415     /* Don't put any checks here, since this needs to be very fast. */
417     return (MultiProc_module->cfg.numProcessors);
421 /* Return Id of current processor */
422 UInt16
423 MultiProc_self (Void)
425     GT_0trace (curTrace, GT_ENTER, "MultiProc_self");
427     GT_1trace (curTrace, GT_LEAVE, "MultiProc_self", MultiProc_module->id);
429     /* Don't put any checks here, since this needs to be very fast. */
431     return (MultiProc_module->id);
435 /* Determines the offset for any two processors. */
436 UInt
437 MultiProc_getSlot (UInt16 remoteProcId)
439     UInt slot = 0u;
440     UInt i;
441     UInt j;
442     UInt smallId;
443     UInt largeId;
445     GT_1trace (curTrace, GT_ENTER, "MultiProc_getSlot", remoteProcId);
447 #if !defined(IPC_BUILD_OPTIMIZE)
448     if (EXPECT_FALSE (   Atomic_cmpmask_and_lt (&(MultiProc_module->refCount),
449                                                 MultiProc_MAKE_MAGICSTAMP(0),
450                                                 MultiProc_MAKE_MAGICSTAMP(1))
451                       == TRUE)) {
452         GT_setFailureReason (curTrace,
453                              GT_4CLASS,
454                              "MultiProc_getSlot",
455                              MultiProc_E_INVALIDSTATE,
456                              "Module was not initialized!");
457     }
458     else if (EXPECT_FALSE (   remoteProcId
459                            >= MultiProc_module->cfg.numProcessors)) {
460         GT_setFailureReason (curTrace,
461                     GT_4CLASS,
462                     "MultiProc_getSlot",
463                     MultiProc_E_INVALIDARG,
464                     "Processor id is not less than numProcessors");
465     }
466     else {
467 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
468         if (remoteProcId > MultiProc_self ()) {
469             smallId = MultiProc_self ();
470             largeId = remoteProcId;
471         }
472         else {
473             largeId = MultiProc_self ();
474             smallId = remoteProcId;
475         }
477         /* determine what offset to create for the remote Proc Id */
478         for (i = 0; i < MultiProc_module->cfg.numProcessors; i++) {
479             for (j = i + 1; j < MultiProc_module->cfg.numProcessors; j++) {
480                 if ((smallId == i) && (largeId == j)) {
481                     break;
482                 }
483                 slot++;
484             }
485         }
486 #if !defined(IPC_BUILD_OPTIMIZE)
487     }
488 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
490     GT_1trace (curTrace, GT_LEAVE, "MultiProc_getSlot", slot);
492     return (slot);
496 #if defined (__cplusplus)
498 #endif /* defined (__cplusplus) */