1 /*
2 * Copyright (c) 2012-2015 Texas Instruments Incorporated - http://www.ti.com
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 * ======== MultiProc.xdc ========
34 *
35 */
37 import xdc.rov.ViewInfo;
39 import xdc.runtime.Assert;
41 /*!
42 * ======== MultiProc ========
43 * Processor Id Module Manager
44 *
45 * Many IPC modules require identifying processors in a
46 * multi-processor environment. The MultiProc module centralizes
47 * processor id management into one module. Since this configuration
48 * is almost always universally required, most IPC applications
49 * require supplying configuration of this module.
50 *
51 * Each processor in the MultiProc module may be uniquely identified by
52 * either a name string or an integer ranging from 0 to MAXPROCESSORS - 1.
53 * Configuration is supplied using the {@link #setConfig} meta function,
54 * the {@link #numProcessors} and {@link #baseIdOfCluster}.
55 *
56 * The setConfig function tells the MultiProc module:
57 * @p(blist)
58 * - The specific processor for which the application is being built
59 * - The number of processors in the cluster
60 * @p
61 *
62 * A cluster is a set of processors within a system which share some share
63 * shared memory and supports notifications. Typically most systems contain
64 * one cluster. When there are multiple clusters in the system, the
65 * {@link #numProcessors} and {@link #baseIdOfCluster} configuration
66 * paramaters are required to be set before calling {@link #setConfig}
67 *
68 * For examle in a system with 2 C6678 devices [each C6678 contains 8
69 * homogeneuous cores]. For first C6678 device:
70 * @p(code)
71 * var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
72 * MultiProc.baseIdOfCluster = 0;
73 * MultiProc.numProcessors = 16;
74 * MultiProc.setConfig(null, ["CORE0", "CORE1", "CORE2", "CORE3",
75 * "CORE4", "CORE5", "CORE6", "CORE7"]);
76 * @p
77 *
78 * For second C6678 device:
79 * @p(code)
80 * var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
81 * MultiProc.baseIdOfCluster = 8;
82 * MultiProc.numProcessors = 16;
83 * MultiProc.setConfig(null, ["CORE0", "CORE1", "CORE2", "CORE3",
84 * "CORE4", "CORE5", "CORE6", "CORE7"]);
85 * @p
86 *
87 * Using the information supplied using the {@link #setConfig} meta function
88 * and the {@link #baseIdOfCluster} module configuration, the processor IDs
89 * are internally set. Please refer to the documentation for
90 * {@link #setConfig} and {@link #baseIdOfCluster} for more details.
91 *
92 * At runtime, the {@link #getId} call returns the MultiProc id of those
93 * processors within its cluster. At config-time, the {@link #getIdMeta}
94 * call returns the the same value.
95 *
96 */
98 module MultiProc
99 {
100 metaonly struct ModuleView {
101 UInt16 id; /* Own ID */
102 UInt16 numProcessors; /* # of processors */
103 String nameList[]; /* Proc names ordered by procId */
104 }
106 @Facet
107 metaonly config ViewInfo.Instance rovViewInfo =
108 ViewInfo.create({
109 viewMap: [
110 [
111 'Module',
112 {
113 type: ViewInfo.MODULE,
114 viewInitFxn: 'viewInitModule',
115 structName: 'ModuleView'
116 }
117 ],
118 ]
119 });
121 /*!
122 * Assert raised when an invalid processor id is used
123 */
124 config Assert.Id A_invalidMultiProcId = {
125 msg: "A_invalidMultiProcId: Invalid MultiProc id"
126 };
128 /*!
129 * Assert raised when a NULL processor name is encountered
130 */
131 config Assert.Id A_invalidProcName = {
132 msg: "A_invalidProcName: NULL MultiProc name encountered"
133 };
135 /*!
136 * Invalid processor id constant
137 *
138 * This constant denotes that the processor id is not valid.
139 */
140 const UInt16 INVALIDID = 0xFFFF;
142 /*! @_nodoc
143 * ======== nameList ========
144 * Unique name for the each processor used in a multi-processor app
145 *
146 * This array should never be set or read directly by the MultiProc user.
147 * The nameList is used to store names configuration supplied via the
148 * {@link #setConfig} static function.
149 *
150 * At runtime, the {@link #getName} function may be used to retrieve
151 * the name of any processor given it's MultiProc id.
152 */
153 config String nameList[];
155 /*! @_nodoc
156 * ======== id ========
157 * Unique software id number for the processor
158 *
159 * This value should never be set or read directly by the MultiProc user.
160 * Instead, the {@link #getId}, {@link #getIdMeta}, and
161 * {@link #setLocalId} calls should be used to respectively retrieve any
162 * processors' MultiProc ids or set the local processor's MultiProc id.
163 */
164 metaonly config UInt16 id = 0;
166 /*! @_nodoc
167 * ======== numProcsInCluster ========
168 * Number of processors in a cluster
169 *
170 * This parameter should never be set: numProcsInCluster is
171 * internally set by the {@link #setConfig} meta function.
172 * setConfig statically sets the value of this configuration to the
173 * length of the supplied nameList array.
174 */
175 config UInt16 numProcsInCluster = 1;
177 /*!
178 * ======== baseIdOfCluster ========
179 * The base processor ID of the cluster.
180 *
181 * The ID of each processor in a cluster is computed by adding
182 * its position in the name list of {@link #setConfig} to the
183 * base ID of the cluster. When more than one cluster exists in
184 * the system, this parameter must be set before calling
185 * {@link #setConfig}.
186 */
187 metaonly config UInt16 baseIdOfCluster = 0;
189 /*!
190 * ======== numProcessors ========
191 * Number of processors in the system
192 *
193 * This configuration should only be set when there is more than one
194 * cluster in the system. It must be set before calling
195 * {@link #setConfig}. If the system contains only one cluster,
196 * it is internally set by the {@link #setConfig} meta function to the
197 * length of the supplied nameList array.
198 * After {@link #setConfig} has been called, it is possible to
199 * retrive the maximum # of processors by reading this module config
200 * either at run-time or at config time.
201 */
202 config UInt16 numProcessors = 1;
204 /*!
205 * ======== ProcAddrMode ========
206 * Enumerate the Processor Addressing Modes
207 *
208 * This enumeration defines the various processor addressing modes
209 * which might impact the behavior and resource allocations of modules
210 * that communicate with other processors in the system (i.e. IPC).
211 *
212 * It is a way for the system integrator to control the internal
213 * behavior and resource allocations of various module to suit the
214 * needs of the program. However, it is at the discretion of each
215 * module on how to respond to these processor addressing modes.
216 *
217 * For example, the NameServer module reflects on this mode when
218 * constructing its internal data structures. For the 'Global' mode,
219 * it will allocate a resource for every processor in the system.
220 * When using 'Cluster' mode, resources are only allocated for
221 * processors in the cluster. A side-effect is that when using
222 * Cluster mode, name queries cannot be addressed to processors
223 * outside of the cluster.
224 *
225 * Specify the addressing mode by setting the
226 * {@link #procAddrMode MultiProc.procAddrMode} configuration
227 * parameter.
228 *
229 * @field(ProcAddrMode_Global) Every processor in the system must
230 * be directly addressable. Usually, this requires a resource
231 * allocation for each processor. This might require a dedicated
232 * hardware resource and/or a memory allocation on behalf of every
233 * processor in the sytem. For large systems, this might result in
234 * significant memory requirements. Use with caution.
235 *
236 * @field(ProcAddrMode_Cluster) Direct addressing is required
237 * only for the processors in your cluster. Processors outside of
238 * the cluster may share resources. This mode limits the per processor
239 * resource allocations to just the processors within your cluster.
240 * This address mode is typically used for large processor systems.
241 *
242 * @see #procAddrMode
243 */
244 enum ProcAddrMode {
245 ProcAddrMode_Global,
246 ProcAddrMode_Cluster
247 };
249 /*!
250 * ======== procAddrMode ========
251 * Define which processor addressing mode is in operation
252 *
253 * This configuration parameter is reflected upon by various system
254 * components whose implementation is impacted by the processor
255 * addressing mode currently in effect. It allows modules to optimize
256 * their behavior and resource allocations for any given processor
257 * address mode.
258 *
259 * The MultiProc module has no specific behavior associated with
260 * this configuration parameter. It is simply a convenient location
261 * for such a configuration parameter as most processor aware
262 * modules already depend on MultiProc.
263 *
264 * @see #ProcAddrMode
265 */
266 config ProcAddrMode procAddrMode = MultiProc.ProcAddrMode_Global;
268 /*! @_nodoc
269 * ======== getClusterId ========
270 */
271 UInt16 getClusterId(UInt16 procId);
273 /*!
274 * ======== getIdMeta ========
275 * Meta version of {@link #getId}
276 *
277 * Statically returns the internally set ID based on configuration
278 * supplied via {@link #setConfig}.
279 *
280 * @param(name) MultiProc procName
281 */
282 metaonly UInt16 getIdMeta(String name);
284 /*!
285 * ======== getDeviceProcNames ========
286 * Returns an array of all possible processor names on the build device
287 *
288 * @(return) Array of valid MultiProc processor names
289 */
290 metaonly Any getDeviceProcNames();
292 /*!
293 * ======== setConfig ========
294 * Configure the MultiProc module
295 *
296 * Configuration of the MultiProc module is primarily accomplished using
297 * the setConfig API at config time. The setConfig API allows the
298 * MultiProc module to identify:
299 * @p(blist)
300 * - Which is the local processor
301 * - Which processors are being used
302 * - Which processors can synchronize
303 * @p
304 * The second of these two pieces of information is supplied via the
305 * nameList argument. The nameList is a non-empty set of distinct
306 * processors valid for the particular device. For a list of valid
307 * processor names for a given device, please refer to the :
308 * {@link ./../ipc/family/doc-files/procNames.html Table of
309 * Valid Names for Each Device}.
310 *
311 * The local processor is identified by using a single name from
312 * nameList. A MultiProc id is internally set to the index of
313 * 'name' in the supplied 'nameList'. I.e. in the example:
314 *
315 * @p(code)
316 * MultiProc.setConfig("DSP", ["HOST", "DSP", "OTHERCORE"]);
317 * @p
318 *
319 * The processors, "HOST", "DSP" and "OTHERCORE" get assigned MultiProc
320 * IDs 0, 1, and 2, respectively. The local processor, "DSP" is assigned
321 * an ID of '1'.
322 *
323 * If the local processor is not known at static time, it is possible to
324 * supply a null name. MultiProc will set the local id to
325 * {@link #INVALIDID} until it is set at runtime using
326 * MultiProc_setLocalId.
327 *
328 * @param(name) MultiProc name for the local processor
329 * @param(nameList) Array of all processors used by the application
330 */
331 metaonly Void setConfig(String name, String nameList[]);
333 /*! @_nodoc
334 * ======== getName$view ========
335 * ROV-time version of {@link #getName}
336 */
337 metaonly String getName$view(UInt id);
339 /*! @_nodoc
340 * ======== self$view ========
341 * ROV-time version of {@link #self}
342 */
343 metaonly UInt self$view();
345 /*! @_nodoc
346 * This is needed to prevent the MultiProc module from being optimized away
347 * during the whole_program[_debug] partial link.
348 */
349 Void dummy();
351 internal:
353 /* Store these elements in the module state (instead of config) to
354 * support boot-time assignment (for single image reuse).
355 */
356 struct Module_State {
357 UInt16 id;
358 UInt16 baseIdOfCluster;
359 UInt16 clusterProcList[]; /* list of procIds in cluster */
360 };
361 }