c17f203cc2ecfb63890e4ce43bb4a3a627bb8ed4
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / resources / RscTable.c
1 /*
2  *  @file       RscTable.c
3  *
4  *  @brief      Resource Table parser.
5  *
6  *  ============================================================================
7  *
8  *  Copyright (c) 2012, Texas Instruments Incorporated
9  *
10  *  Redistribution and use in source and binary forms, with or without
11  *  modification, are permitted provided that the following conditions
12  *  are met:
13  *
14  *  *  Redistributions of source code must retain the above copyright
15  *     notice, this list of conditions and the following disclaimer.
16  *
17  *  *  Redistributions in binary form must reproduce the above copyright
18  *     notice, this list of conditions and the following disclaimer in the
19  *     documentation and/or other materials provided with the distribution.
20  *
21  *  *  Neither the name of Texas Instruments Incorporated nor the names of
22  *     its contributors may be used to endorse or promote products derived
23  *     from this software without specific prior written permission.
24  *
25  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *  Contact information for paper mail:
37  *  Texas Instruments
38  *  Post Office Box 655303
39  *  Dallas, Texas 75265
40  *  Contact information:
41  *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
42  *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
43  *  ============================================================================
44  *
45  */
48 #if defined (__cplusplus)
49 extern "C" {
50 #endif
52 #include <ti/syslink/Std.h>
53 #include <ti/syslink/utils/List.h>
54 #include <ti/syslink/utils/Memory.h>
55 #include <ti/syslink/utils/Trace.h>
56 #include <RscTable.h>
57 #include <OsalKfile.h>
58 #include <_MultiProc.h>
59 #include <dload_api.h>
60 #include <ti/syslink/ProcMgr.h>
61 #include <Bitops.h>
62 #include <_MessageQCopyDefs.h>
63 #include <ProcDefs.h>
64 #include <sys/mman.h>
66 /* =============================================================================
67  *  Macros and types
68  * =============================================================================
69  */
71 #define RSC_TABLE_STRING ".resource_table"
72 #define DDR_MEM 0x80000000
74 typedef struct Carveout_Elem_tag {
75     List_Elem  elem;
76     UInt32     addr;
77     UInt32     size;
78 } Carveout_Elem;
80 typedef struct Carveout_Object_tag {
81     UInt32      addr;
82     UInt32      size;
83     List_Handle freeBlocks;
84 } Carveout_Object;
86 /*!
87  *  @brief  RscTable Header
88  */
89 typedef struct RscTable_Header_tag {
90     UInt32 ver;
91     UInt32 num;
92     UInt32 reserved[2];
93     UInt32 offset[];
94 } RscTable_Header;
96 /*!
97  *  @brief  RscTable Entry
98  */
99 typedef struct RscTable_MemEntry_tag {
100     UInt32 type;
101     UInt32 da;       /* Device Virtual Address */
102     UInt32 pa;       /* Physical Address */
103     UInt32 len;
104     UInt32 flags;
105     UInt32 reserved;
106     Char   name[32];
107 } RscTable_MemEntry;
109 /*!
110  *  @brief  RscTable Module state object
111  */
112 typedef struct RscTable_ModuleObject_tag {
113     RscTable_Handle       handles [MultiProc_MAXPROCESSORS];
114     /*!< Array of Handles of RscTable instances */
115 } RscTable_ModuleObject;
117 /*!
118  *  @brief  RscTable instance object
119  */
120 struct RscTable_Object_tag {
121     UInt16                 procId;
122     /*!< Processor ID associated with this RscTable. */
123     Char *                 fileName;
124     /*!< File name associated with this RscTable. */
125     Void *                 rscTable;
126     /*!< Pointer to the resource table. */
127     UInt32                 rscTableLen;
128     /*!< Resource table length. */
129     UInt32                 rscTableDA;
130     /*!< Resource table device address. */
131     Carveout_Object *      carveout[SYSLINK_MAX_MEMENTRIES];
132     /*!< Carveouts for this table. */
133     UInt32                 numCarveouts;
134     /*!< Carveouts for this table. */
135     SysLink_MemEntry       memEntries[SYSLINK_MAX_MEMENTRIES];
136     /*!< Memory Entries for the remote processor. */
137     UInt32                 numMemEntries;
138     /*!< Number of Memory Entries in the memEntries array. */
139     struct fw_rsc_vdev_vring * vrings;
140     /*!< Vring info for the remote processor. */
141     UInt32                 numVrings;
142     /*!< Number of vrings. */
143     UInt32                 vringPa;
144     /*!< PAddr of vrings space. */
145     UInt32                 vringBufsPa;
146     /*!< PAddr of vring bufs space. */
147     struct fw_rsc_trace    trace;
148     /*!< Trace info. */
149     List_Handle            chunks;
150     /*!< Allocated Chunks. */
151 } ;
153 /* Defines the RscTable_Object type. */
154 typedef struct RscTable_Object_tag RscTable_Object;
156 /* =============================================================================
157  *  Globals
158  * =============================================================================
159  */
160 /*!
161  *  @var    RscTable_state
162  *
163  *  @brief  RscTable state object variable
164  */
165 #if !defined(SYSLINK_BUILD_DEBUG)
166 static
167 #endif /* if !defined(SYSLINK_BUILD_DEBUG) */
168 RscTable_ModuleObject RscTable_state;
171 /* =============================================================================
172  *  APIs
173  * =============================================================================
174  */
176 RscTable_Handle
177 RscTable_alloc (Char * fileName, UInt16 procId)
179     Int status = 0;
180     RscTable_Object * obj = NULL;
181     OsalKfile_Handle fileDesc  = NULL;
182     UInt32 res_offs = 0, res_addr = 0, res_size = 0;
183     List_Params params;
185     // Check if this one is already registered
186     if (RscTable_state.handles[procId]) {
187         /* Not setting status here since this function does not return status.*/
188         GT_setFailureReason (curTrace,
189                              GT_4CLASS,
190                              "RscTable_alloc",
191                              RSCTABLE_E_INVALIDARG,
192                              "Invalid procId specified");
193         return NULL;
194     }
196     // Find the resource table in the file
197     status = OsalKfile_open (fileName, "r", &fileDesc);
198     if (status < 0) {
199         /* Not setting status here since this function does not return status.*/
200         GT_setFailureReason (curTrace,
201                              GT_4CLASS,
202                              "RscTable_alloc",
203                              RSCTABLE_E_INVALIDARG,
204                              "Invalid fileDesc specified");
205         return NULL;
206     }
208     status = DLOAD_get_section_offset((LOADER_FILE_DESC *)fileDesc,
209                                       RSC_TABLE_STRING, &res_offs, &res_size,
210                                       &res_addr);
211     if (status >= 0) {
212         obj = Memory_calloc(NULL, sizeof (RscTable_Object), 0, NULL);
213         if (obj != NULL) {
214             // Allocate memory to hold the table
215             obj->rscTable = Memory_alloc(NULL, res_size, 0, NULL);
216             if (obj->rscTable == NULL) {
217                 /* Not setting status here since this function does not return
218                  * status.*/
219                 GT_setFailureReason (curTrace,
220                                      GT_4CLASS,
221                                      "RscTable_alloc",
222                                      RSCTABLE_E_MEMORY,
223                                      "Unable to allocate rscTable");
224                 Memory_free(NULL, obj, sizeof (RscTable_Object));
225                 obj = NULL;
226             }
227             else {
228                 obj->rscTableLen = res_size;
229                 status = OsalKfile_seek(fileDesc, res_offs,
230                                         OsalKfile_Pos_SeekSet);
231                 if (status < 0) {
232                     /* Not setting status here since this function does not
233                      * return status.*/
234                     GT_setFailureReason (curTrace,
235                                          GT_4CLASS,
236                                          "RscTable_alloc",
237                                          RSCTABLE_E_FAIL,
238                                          "Unable to seek to rsctable in file");
239                     Memory_free(NULL, obj->rscTable, res_size);
240                     Memory_free(NULL, obj, sizeof (RscTable_Object));
241                     obj = NULL;
242                 }
243                 else {
244                     // Copy the table to the allocated memory
245                     status = OsalKfile_read(fileDesc, (char *)obj->rscTable, 1,
246                                             res_size);
247                     if (status < 0) {
248                         /* Not setting status here since this function does not
249                          * return status.*/
250                         GT_setFailureReason (curTrace,
251                                              GT_4CLASS,
252                                              "RscTable_alloc",
253                                              RSCTABLE_E_FAIL,
254                                              "Unable to read rsctable in file");
255                         Memory_free(NULL, obj->rscTable, res_size);
256                         Memory_free(NULL, obj, sizeof (RscTable_Object));
257                         obj = NULL;
258                     }
259                     else {
260                         obj->rscTableDA = res_addr;
261                         List_Params_init(&params);
262                         obj->chunks = List_create(&params);
263                         if (obj->chunks == NULL) {
264                             /* Not setting status here since this function does
265                              * not return status.*/
266                             GT_setFailureReason (curTrace,
267                                                  GT_4CLASS,
268                                                  "RscTable_alloc",
269                                                  RSCTABLE_E_FAIL,
270                                                  "Unable to create list");
271                             Memory_free(NULL, obj->rscTable, res_size);
272                             Memory_free(NULL, obj, sizeof (RscTable_Object));
273                             obj = NULL;
274                         }
275                     }
276                 }
277             }
278         }
279         else {
280             /* Not setting status here since this function does not return
281              * status.*/
282             GT_setFailureReason (curTrace,
283                                  GT_4CLASS,
284                                  "RscTable_alloc",
285                                  RSCTABLE_E_MEMORY,
286                                  "Unable to allocate obj");
287         }
288     }
289     else {
290         /* Not setting status here since this function does not return status.*/
291         GT_setFailureReason (curTrace,
292                              GT_4CLASS,
293                              "RscTable_alloc",
294                              RSCTABLE_E_FAIL,
295                              "Unable to find resource table in file");
296     }
298     OsalKfile_close(&fileDesc);
300     // If successful, save coreId-handle pair for later access
301     if (obj) {
302         obj->procId = procId;
303         RscTable_state.handles[procId] = (RscTable_Handle)obj;
304     }
306     return (RscTable_Handle)obj;
309 /* Helper functions for processing carveout */
310 Int Carveout_register (RscTable_Object *obj, UInt32 id, Ptr carveOut,
311                        UInt32 carveOutLen)
313     Int status = 0;
314     Carveout_Object * cout = NULL;
315     List_Params params;
317     cout = Memory_alloc(NULL, sizeof(Carveout_Object), 0, NULL);
318     if (cout) {
319         cout->addr = (UInt32)carveOut;
320         cout->size = carveOutLen;
321         List_Params_init(&params);
322         cout->freeBlocks = List_create(&params);
323         if (cout->freeBlocks == NULL) {
324             status = RSCTABLE_E_MEMORY;
325             GT_setFailureReason (curTrace,
326                                  GT_4CLASS,
327                                  "Carveout_register",
328                                  status,
329                                  "Unable to create free list");
330             Memory_free(NULL, cout, sizeof(Carveout_Object));
331             cout = NULL;
332         }
333         else {
334             // Add the whole of the memory to the free list
335             Carveout_Elem * elem = Memory_alloc(NULL, sizeof(Carveout_Elem),
336                                                 0, NULL);
337             if (elem) {
338                 elem->addr = cout->addr;
339                 elem->size = cout->size;
340                 List_put(cout->freeBlocks, (List_Elem *)elem);
341             }
342             else {
343                 status = RSCTABLE_E_MEMORY;
344                 GT_setFailureReason (curTrace,
345                                      GT_4CLASS,
346                                      "Carveout_register",
347                                      status,
348                                      "Unable to allocate elem");
349                 List_delete(&cout->freeBlocks);
350                 Memory_free(NULL, cout, sizeof(Carveout_Object));
351                 cout = NULL;
352             }
353         }
354     }
355     else {
356         status = RSCTABLE_E_MEMORY;
357         GT_setFailureReason (curTrace,
358                              GT_4CLASS,
359                              "Carveout_register",
360                              status,
361                              "Unable to allocate carveout structure");
362     }
364     obj->carveout[id] = cout;
365     obj->numCarveouts++;
366     return status;
369 Int Carveout_unregister (RscTable_Object *obj, UInt32 id)
371     Int status = 0;
372     List_Elem * elem = NULL;
374     if (obj->carveout[id]) {
375         if (obj->carveout[id]->freeBlocks) {
376             while ((elem = List_get(obj->carveout[id]->freeBlocks)))
377                 Memory_free(NULL, elem, sizeof(Carveout_Elem));
378             List_delete(&obj->carveout[id]->freeBlocks);
379         }
381         Memory_free(NULL, obj->carveout[id], sizeof(Carveout_Object));
382         obj->carveout[id] = NULL;
383         obj->numCarveouts--;
384     }
385     else {
386         status = RSCTABLE_E_INVALIDARG;
387         GT_setFailureReason (curTrace,
388                              GT_4CLASS,
389                              "Carveout_unregister",
390                              status,
391                              "No carveout associated with obj");
392     }
394     return status;
397 // allocate any addr
398 Int Chunk_allocate (RscTable_Object *obj, UInt32 size, UInt32 * pa)
400     Int status = 0;
401     List_Elem * elem = NULL;
402     Void * da;
403     long long paddr;
404     UInt32 len;
406     if (!pa || !obj || !obj->chunks) {
407         status = RSCTABLE_E_INVALIDARG;
408         GT_setFailureReason (curTrace,
409                              GT_4CLASS,
410                              "Chunk_allocate",
411                              status,
412                              "Invalid arg passed");
413         GT_3trace(curTrace, GT_4CLASS, "obj [0x%x] obj->chunks [0x%x] pa [0x%x]", obj, obj ? obj->chunks : NULL, pa);
414     }
415     else {
416         // first try to allocate contiguous mem
417         da = mmap64(NULL, size,
418                     PROT_NOCACHE | PROT_READ | PROT_WRITE,
419                     MAP_ANON | MAP_PHYS | MAP_SHARED,
420                     NOFD,
421                     0);
422         if (da == MAP_FAILED) {
423             // TODO: try to allocate non-contigous mem then get the pages
424             status = RSCTABLE_E_MEMORY;
425             GT_setFailureReason (curTrace,
426                                  GT_4CLASS,
427                                  "Chunk_allocate",
428                                  status,
429                                  "Unable to allocate chunk");
430         }
431         else {
432             /* Make sure the memory is contiguous */
433             status = mem_offset64(da, NOFD, size, &paddr, &len);
434             if (status || (len != size)) {
435                 munmap(da, size);
436                 status = RSCTABLE_E_MEMORY;
437                 GT_setFailureReason (curTrace,
438                                      GT_4CLASS,
439                                      "Chunk_allocate",
440                                      status,
441                                      "mem_offset64 failed");
442             }
443             else {
444                 *pa = (UInt32)paddr;
445                 // save the memory so that it can be freed later
446                 elem = Memory_alloc(NULL, sizeof(Carveout_Elem), 0, NULL);
447                 if (elem == NULL) {
448                     munmap(da, size);
449                     status = RSCTABLE_E_MEMORY;
450                     GT_setFailureReason (curTrace,
451                                          GT_4CLASS,
452                                          "Chunk_allocate",
453                                          status,
454                                          "Memory_alloc failed");
455                 }
456                 else {
457                     ((Carveout_Elem *)elem)->addr = (UInt32)da;
458                     ((Carveout_Elem *)elem)->size = size;
459                     List_put(obj->chunks, elem);
460                 }
461             }
462         }
463     }
464     return status;
467 // allocate any addr from a specified carveout
468 Int Carveout_allocate (RscTable_Object *obj, UInt32 size, UInt32 * pa)
470     Int status = 0;
471     Carveout_Object * cout = NULL;
472     List_Elem * elem = NULL;
473     Bool found = FALSE;
474     UInt i = 0;
476     if (!pa || !obj || !obj->numCarveouts) {
477         status = RSCTABLE_E_INVALIDARG;
478         GT_setFailureReason (curTrace,
479                              GT_4CLASS,
480                              "Carveout_allocate",
481                              status,
482                              "Invalid arg passed");
483     }
484     else {
485         for (i = 0; i < obj->numCarveouts; i++) {
486             *pa = 0;
487             cout = obj->carveout[i];
489             // search for a free block with sufficient size
490             List_traverse(elem, cout->freeBlocks) {
491                 if (((Carveout_Elem *)elem)->size >= size) {
492                     found = TRUE;
493                     break;
494                 }
495             }
496             if (found) {
497                 UInt32 rem = 0;
498                 UInt32 addr = 0;
500                 // found a spot for our request
501                 addr = ((Carveout_Elem *)elem)->addr;
502                 rem = ((Carveout_Elem *)elem)->size - size;
503                 if (rem) {
504                     ((Carveout_Elem *)elem)->addr += size;
505                     ((Carveout_Elem *)elem)->size = rem;
506                 }
507                 else {
508                     List_remove(cout->freeBlocks, elem);
509                     Memory_free (NULL, elem, sizeof(Carveout_Elem));
510                 }
511                 *pa = addr;
512                 break;
513             }
514         }
515         if (i == obj->numCarveouts) {
516             status = RSCTABLE_E_MEMORY;
517             GT_setFailureReason (curTrace,
518                                  GT_4CLASS,
519                                  "Carveout_allocate",
520                                  status,
521                                  "Not enough room in carveout");
522         }
523     }
524     return status;
527 // allocate specific addr
528 Int Carveout_reserve (RscTable_Object *obj, UInt32 size, UInt32 pa)
530     Int status = 0;
531     Carveout_Object * cout = NULL;
532     List_Elem * elem = NULL;
533     Bool found = FALSE;
534     UInt i = 0;
536     if (!pa || !obj || !obj->numCarveouts) {
537         status = RSCTABLE_E_INVALIDARG;
538         GT_setFailureReason (curTrace,
539                              GT_4CLASS,
540                              "Carveout_reserve",
541                              status,
542                              "Invalid arg passed");
543     }
544     else {
545         for (i = 0; i < obj->numCarveouts; i++) {
546             cout = obj->carveout[i];
548             // search for a free block with sufficient size
549             List_traverse(elem, cout->freeBlocks) {
550                 if ((((Carveout_Elem *)elem)->addr <= pa) &&
551                     ((((Carveout_Elem *)elem)->addr +
552                       ((Carveout_Elem *)elem)->size) >= (pa + size))) {
553                     found = TRUE;
554                     break;
555                 }
556             }
557             if (found) {
558                 UInt32 rem_start = 0;
559                 UInt32 rem_end = 0;
561                 // found a spot for our request
562                 if (((Carveout_Elem *)elem)->addr < pa) {
563                     // there is free mem at the beginning of the block
564                     rem_start = pa - ((Carveout_Elem *)elem)->addr;
565                 }
566                 if (((Carveout_Elem *)elem)->addr + ((Carveout_Elem *)elem)->size >
567                     (pa + size)) {
568                     // there is free mem at the end of the block
569                     rem_end = ((Carveout_Elem *)elem)->addr +
570                               ((Carveout_Elem *)elem)->size - (pa + size);
571                 }
572                 // now carve up the block
573                 if (rem_start) {
574                     ((Carveout_Elem *)elem)->size = rem_start;
575                 }
576                 else if (rem_end) {
577                     ((Carveout_Elem *)elem)->size = rem_end;
578                     ((Carveout_Elem *)elem)->addr = pa + size;
579                 }
580                 else {
581                     List_remove(cout->freeBlocks, elem);
582                     Memory_free (NULL, elem, sizeof(Carveout_Elem));
583                 }
584                 if (rem_start && rem_end) {
585                     Carveout_Elem * c_elem = NULL;
586                     c_elem = Memory_alloc (NULL, sizeof(Carveout_Elem), 0, NULL);
587                     if (c_elem) {
588                         c_elem->size = rem_end;
589                         c_elem->addr = pa + size;
590                         List_insert(cout->freeBlocks, (List_Elem *)&c_elem->elem,
591                                     elem->next);
592                     }
593                     else {
594                         /* add mem back to free block */
595                         ((Carveout_Elem *)elem)->size += (size + rem_end);
596                         status = RSCTABLE_E_MEMORY;
597                         GT_setFailureReason (curTrace,
598                                              GT_4CLASS,
599                                              "Carveout_reserve",
600                                              status,
601                                              "Unable to allocate elem");
602                     }
603                 }
604                 break;
605             }
606         }
607         if (i == obj->numCarveouts) {
608             status = RSCTABLE_E_MEMORY;
609             GT_setFailureReason (curTrace,
610                                  GT_4CLASS,
611                                  "Carveout_reserve",
612                                  status,
613                                  "Specified addr/size not available");
615         }
616     }
617     return status;
620 Int
621 RscTable_process (UInt16 procId, Bool mmuEnabled, UInt32 numCarveouts,
622                   Ptr carveOut[], UInt32 carveOutLen[], Bool tryAlloc,
623                   UInt32 * numBlocks)
625     Int status = 0;
626     Int ret = 0;
627     RscTable_Object * obj = NULL;
628     RscTable_Header * table = NULL;
629     UInt i = 0, j = 0;
630     UInt dmem_num = 0;
632     // Find the table for this coreId, if not found, return an error
633     if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
634         status = RSCTABLE_E_INVALIDARG;
635         GT_setFailureReason (curTrace,
636                              GT_4CLASS,
637                              "RscTable_process",
638                              status,
639                              "Invalid procId specified");
640         return status;
641     }
643     obj = (RscTable_Object *)RscTable_state.handles[procId];
644     table = (RscTable_Header *)obj->rscTable;
646     obj->numMemEntries = 0;
648     // Register carveout mem regions if provided
649     if (numCarveouts && carveOut && carveOutLen) {
650         for (i = 0; i < numCarveouts; i++) {
651             status = Carveout_register(obj, i, carveOut[i], carveOutLen[i]);
652             if (status < 0) {
653                 GT_setFailureReason (curTrace,
654                                      GT_4CLASS,
655                                      "RscTable_process",
656                                      status,
657                                      "Carveout_register failed");
658                 return status;
659             }
660         }
661     }
663     // TODO: Check the version
664     printf("RscTable_process: RscTable version is [%d]\n", table->ver);
666     // Process the table for this core, allocating carveout memory if necessary
667     for (i = 0; i < table->num && !ret; i++) {
668         RscTable_MemEntry * entry =
669                 (RscTable_MemEntry *)((UInt32)table + table->offset[i]);
670         switch (entry->type) {
671             case TYPE_CARVEOUT :
672             {
673                 // TODO: need to allocate this mem from carveout
674                 struct fw_rsc_carveout * cout = (struct fw_rsc_carveout *)entry;
675                 UInt32 pa = 0;
676                 if (cout->pa == 0)
677                     if (mmuEnabled)
678                         ret = Chunk_allocate (obj, cout->len, &pa);
679                     else {
680                         ret = Carveout_reserve (obj, cout->len, cout->da);
681                         pa = cout->da;
682                     }
683                 else
684                     ret = Carveout_reserve (obj, cout->len, cout->pa);
685                 if (!ret) {
686                     cout->pa = pa;
687                     if (obj->numMemEntries == SYSLINK_MAX_MEMENTRIES) {
688                         ret = -1;
689                     }
690                     else {
691                         obj->memEntries[obj->numMemEntries].slaveVirtAddr =
692                                 cout->da;
693                         obj->memEntries[obj->numMemEntries].masterPhysAddr =
694                                 cout->pa;
695                         obj->memEntries[obj->numMemEntries].size = cout->len;
696                         //if (mmuEnabled) {
697                             obj->memEntries[obj->numMemEntries].map = TRUE;
698                             obj->memEntries[obj->numMemEntries].mapMask =
699                                 ProcMgr_SLAVEVIRT;
700                         //}
701                         //else
702                         //    obj->memEntries[obj->numMemEntries].map = FALSE;
703                         obj->memEntries[obj->numMemEntries].isCached = FALSE;
704                         obj->memEntries[obj->numMemEntries].isValid = TRUE;
705                         obj->numMemEntries++;
706                     }
707                 }
708                 printf ("RscTable_process: carveout [%s] @ da [0x%08x] pa [0x%08x] len [0x%x]\n", cout->name, cout->da, cout->pa, cout->len);
709                 break;
710             }
711             case TYPE_DEVMEM :
712             {
713                 // only care about mem in DDR for now
714                 struct fw_rsc_devmem * dmem = (struct fw_rsc_devmem *)entry;
715                 UInt32 pa = 0;
716                 if (dmem->pa >= DDR_MEM) {
717                     // HACK: treat vring mem specially, vring is always the
718                     //       first devmem entry, may change in future
719                     if (dmem_num++ == 0) {
720                         // memory should already be reserved for vring
721                         if (obj->vringPa == 0) {
722                             // vdev must have been defined first
723                             GT_setFailureReason (curTrace,
724                                                  GT_4CLASS,
725                                                  "RscTable_process",
726                                                  status,
727                                                  "Vring Must be Defined First");
729                             ret = -1;
730                         }
731                         else if (obj->vringPa != dmem->pa &&
732                                  (!tryAlloc || !mmuEnabled)) {
733                             // defined pa does not match allocated pa, and
734                             // either the mmu is disabled or the platform has
735                             // not given permission to allocate on our own
736                             ret = -1;
737                             GT_setFailureReason (curTrace,
738                                                  GT_4CLASS,
739                                                  "RscTable_process",
740                                                  status,
741                                                  "Vring PA Mis-match");
743                             GT_2trace (curTrace, GT_4CLASS,
744                                        "vringPa is 0x%x, dmem->pa is 0x%x",
745                                        obj->vringPa, dmem->pa);
746                         }
747                         else {
748                             dmem->pa = obj->vringPa;
749                         }
750                     }
751                     else {
752                         ret = Carveout_reserve (obj, dmem->len, dmem->pa);
753                         if (ret && mmuEnabled && tryAlloc) {
754                             ret = Carveout_allocate (obj, dmem->len, &pa);
755                             if (!ret) dmem->pa = pa;
756                         }
757                     }
758                 }
759                 if (!ret) {
760                     if (obj->numMemEntries == SYSLINK_MAX_MEMENTRIES) {
761                         ret = -1;
762                     }
763                     else {
764                         obj->memEntries[obj->numMemEntries].slaveVirtAddr =
765                                 dmem->da;
766                         obj->memEntries[obj->numMemEntries].masterPhysAddr =
767                                 dmem->pa;
768                         obj->memEntries[obj->numMemEntries].size = dmem->len;
769                         //if (mmuEnabled) {
770                             obj->memEntries[obj->numMemEntries].map = TRUE;
771                             obj->memEntries[obj->numMemEntries].mapMask =
772                                 ProcMgr_SLAVEVIRT;
773                         //}
774                         //else
775                         //    obj->memEntries[obj->numMemEntries].map = FALSE;
776                         obj->memEntries[obj->numMemEntries].isCached = FALSE;
777                         obj->memEntries[obj->numMemEntries].isValid = TRUE;
778                         obj->numMemEntries++;
779                     }
780                 }
782                 // TODO: need to make sure this mem exists/is set aside, or allocate it
783                 printf ("RscTable_process: devmem [%s] @ da [0x%08x] pa [0x%08x] len [0x%x]\n", dmem->name, dmem->da, dmem->pa, dmem->len);
784                 break;
785             }
786             case TYPE_TRACE :
787             {
788                 // TODO: save da for future use
789                 struct fw_rsc_trace * trace = (struct fw_rsc_trace *)entry;
790                 Memory_copy(&obj->trace, trace, sizeof(*trace));
791                 printf ("RscTable_process: trace [%s] @ da [0x%08x] len [0x%x]\n", trace->name, trace->da, trace->len);
792                 break;
793             }
794             case TYPE_VDEV :
795             {
796                 // TODO: save vring info for future use
797                 struct fw_rsc_vdev *vdev = (struct fw_rsc_vdev *)entry;
798                 struct fw_rsc_vdev_vring * vring = NULL;
799                 UInt32 vr_size = 0;
800                 UInt32 vr_bufs_size = 0;
801                 UInt32 pa = 0;
802                 obj->numVrings = vdev->num_of_vrings;
803                 obj->vrings = Memory_alloc(NULL,
804                                            sizeof (*vring) * obj->numVrings, 0,
805                                            NULL);
806                 if (!obj->vrings)
807                     ret = -1;
808                 for (j = 0; j < vdev->num_of_vrings && !ret; j++) {
809                     vring = (struct fw_rsc_vdev_vring *)
810                                 ((UInt32)vdev + sizeof(*vdev) +
811                                  (sizeof(*vring) * j));
812                     Memory_copy (&obj->vrings[j], vring, sizeof (*vring));
813                     printf ("RscTable_process: vring [%d] @ [0x%08x]\n",
814                             vring->num, vring->da);
815                     // Hack, we know this is the size alignment
816                     if (vring->num != MessageQCopy_NUMBUFS ||
817                         vring->align != MessageQCopy_VRINGALIGN) {
818                         printf ("RscTable_process: warning size mis-match!\n");
819                         ret = -1;
820                     }
821                     vr_size += ROUND_UP(MessageQCopy_RINGSIZE, 0x4000);
822                     vr_bufs_size += (vring->num) * RPMSG_BUF_SIZE;
823                 }
824                 if (!ret)
825                     // HACK: round up to multiple of 1MB, because we know this
826                     //       is the size of the remote entry
827                     if (mmuEnabled)
828                         ret = Chunk_allocate(obj,
829                                      ROUND_UP(vr_size + vr_bufs_size, 0x100000),
830                                      &pa);
831                     else
832                         ret = Carveout_allocate(obj,
833                                      ROUND_UP(vr_size + vr_bufs_size, 0x100000),
834                                      &pa);
835                 else if (obj->vrings) {
836                     Memory_free (NULL, obj->vrings,
837                                  sizeof(*vring) * obj->numVrings);
838                     obj->vrings = NULL;
839                 }
841                 if (!ret) {
842                     obj->vringPa = pa;
843                     obj->vringBufsPa = pa + vr_size;
844                 }
845                 break;
846             }
847             case TYPE_CRASHDUMP :
848                 // what to do with this?
849                 break;
850             default :
851                 break;
852         }
853     }
855     if (ret) {
856         status = RSCTABLE_E_FAIL;
857         GT_setFailureReason (curTrace,
858                              GT_4CLASS,
859                              "RscTable_process",
860                              status,
861                              "Failure happened in processing table");
862         if (obj->vrings)
863             Memory_free(NULL, obj->vrings,
864                         sizeof(*obj->vrings) * obj->numVrings);
865         obj->vrings = NULL;
866         obj->numMemEntries = 0;
867     }
868     *numBlocks = obj->numMemEntries;
869     // Can un-register the carveout now? Don't need it anymore?
870     for (i = 0; i < numCarveouts; i++)
871         Carveout_unregister(obj, i);
873     return status;
876 Int
877 RscTable_getMemEntries (UInt16 procId, SysLink_MemEntry *memEntries,
878                         UInt32 * numMemEntries)
880     Int status = 0;
881     RscTable_Object *obj = NULL;
883     // Find the table for this procId, if not found, return an error
884     if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
885         status = RSCTABLE_E_INVALIDARG;
886         GT_setFailureReason (curTrace,
887                              GT_4CLASS,
888                              "RscTable_getMemEntries",
889                              status,
890                              "Invalid ProcId specified");
891         return status;
892     }
894     obj = (RscTable_Object *)RscTable_state.handles[procId];
896     if (obj->memEntries && obj->numMemEntries &&
897         *numMemEntries >= obj->numMemEntries) {
898         *numMemEntries = obj->numMemEntries;
899         Memory_copy(memEntries, obj->memEntries,
900                     sizeof(*memEntries) * obj->numMemEntries);
901     }
902     else {
903         status = RSCTABLE_E_INVALIDARG;
904         GT_setFailureReason (curTrace,
905                              GT_4CLASS,
906                              "RscTable_getMemEntries",
907                              status,
908                              "Invalid num of memEntries or memEntries is NULL");
909     }
911     return status;
914 Int
915 RscTable_getInfo (UInt16 procId, UInt32 type, UInt32 extra, UInt32 * da,
916                   UInt32 *pa, UInt32 * len)
918     Int status = 0;
919     RscTable_Object *obj = NULL;
921     // Find the table for this procId, if not found, return an error
922     if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
923         status = RSCTABLE_E_INVALIDARG;
924         GT_setFailureReason (curTrace,
925                              GT_4CLASS,
926                              "RscTable_getInfo",
927                              status,
928                              "Invalid procId specified");
929         return status;
930     }
932     obj = (RscTable_Object *)RscTable_state.handles[procId];
934     if (type == TYPE_TRACE) {
935         if (da && len) {
936             *da = obj->trace.da;
937             *len = obj->trace.len;
938         }
939         else {
940             status = RSCTABLE_E_INVALIDARG;
941             GT_setFailureReason (curTrace,
942                                  GT_4CLASS,
943                                  "RscTable_getInfo",
944                                  status,
945                                  "Invalid pointer passed");
946         }
947     }
948     else if (type == TYPE_VDEV) {
949         if (extra == 0 && len) {
950             *len = obj->numVrings;
951         }
952         else if (extra < obj->numVrings && da) {
953             *da = obj->vrings[extra-1].da;
954         }
955         else {
956             status = RSCTABLE_E_INVALIDARG;
957             GT_setFailureReason (curTrace,
958                                  GT_4CLASS,
959                                  "RscTable_getInfo",
960                                  status,
961                                  "Invalid pointer passed");
962         }
963     }
964     else {
965         // type not supported
966         status = -1;
967     }
969     return status;
970     // Retrieve the info for a certain resource type (ex. Vring info)
973 Int
974 RscTable_update (UInt16 procId, ProcMgr_Handle procHandle)
976     // Updates the table to physical memory so that phys addrs are available to
977     // the remote cores.  This should be called only after loading the remote
978     // cores.
979     Int status = 0;
980     RscTable_Object *obj = NULL;
981     UInt32 rscTableVA = 0, rscTablePA = 0;
983     // Find the table for this procId, if not found, return an error
984     if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
985         status = RSCTABLE_E_INVALIDARG;
986         GT_setFailureReason (curTrace,
987                              GT_4CLASS,
988                              "RscTable_update",
989                              status,
990                              "Invalid ProcId specified");
991         return status;
992     }
994     obj = (RscTable_Object *)RscTable_state.handles[procId];
996     status = ProcMgr_translateAddr(procHandle, (Ptr *)&rscTablePA,
997                                    ProcMgr_AddrType_MasterPhys,
998                                    (Ptr)obj->rscTableDA,
999                                    ProcMgr_AddrType_SlaveVirt);
1000     if (status < 0) {
1001         status = RSCTABLE_E_FAIL;
1002         GT_setFailureReason (curTrace,
1003                              GT_4CLASS,
1004                              "RscTable_update",
1005                              status,
1006                              "Unable to get the Master PA for RscTable");
1007     }
1008     else {
1009         /* Map the phys mem to local */
1010         rscTableVA = (UInt32)mmap_device_io(obj->rscTableLen, rscTablePA);
1011         if (rscTableVA != MAP_DEVICE_FAILED) {
1012             /* Copy the updated table to the memory */
1013             Memory_copy((Ptr)rscTableVA, obj->rscTable, obj->rscTableLen);
1014             munmap_device_io(rscTableVA, obj->rscTableLen);
1015         }
1016         else {
1017             status = RSCTABLE_E_FAIL;
1018             GT_setFailureReason (curTrace,
1019                                  GT_4CLASS,
1020                                  "RscTable_update",
1021                                  status,
1022                                  "Unable to map memory");
1023         }
1024     }
1026     return status;
1029 Int
1030 RscTable_free (RscTable_Handle * handle)
1032     Int status = 0;
1033     RscTable_Object * obj = NULL;
1034     Int i = 0;
1035     List_Elem * elem;
1037     // Remove resource table from coreId-Handle pair list
1038     if (handle && *handle) {
1039         // sanity check
1040         for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
1041             if (RscTable_state.handles[i] == *handle)
1042                 break;
1043         }
1044         if (i < MultiProc_MAXPROCESSORS) {
1045             obj = (RscTable_Object *)(*handle);
1046             // Additional sanity check
1047             if (obj->procId == i) {
1048                 // Free vrings, memEntries, etc.
1049                 if (obj->chunks) {
1050                     while ((elem = List_get(obj->chunks))) {
1051                         Carveout_Elem * co_elem = (Carveout_Elem *)elem;
1052                         munmap((Void *)co_elem->addr, co_elem->size);
1053                         Memory_free(NULL, co_elem, sizeof(Carveout_Elem));
1054                     }
1055                     List_delete(&obj->chunks);
1056                     obj->chunks = NULL;
1057                 }
1058                 if (obj->vrings)
1059                     Memory_free(NULL, obj->vrings,
1060                                 sizeof(*obj->vrings) * obj->numVrings);
1061                 obj->vrings = NULL;
1062                 obj->numMemEntries = 0;
1064                 if (obj->rscTable)
1065                     Memory_free(NULL, obj->rscTable, obj->rscTableLen);
1066                 obj->rscTableDA = 0;
1067                 Memory_free(NULL, obj, sizeof (RscTable_Object));
1068                 *handle = NULL;
1069                 RscTable_state.handles[i] = NULL;
1070             }
1071         }
1072         else {
1073             status = RSCTABLE_E_INVALIDARG;
1074             GT_setFailureReason (curTrace,
1075                                  GT_4CLASS,
1076                                  "RscTable_free",
1077                                  status,
1078                                  "Invalid handle passed");
1079         }
1080     }
1081     else {
1082         status = RSCTABLE_E_INVALIDARG;
1083         GT_setFailureReason (curTrace,
1084                              GT_4CLASS,
1085                              "RscTable_free",
1086                              status,
1087                              "Invalid handle passed");
1088     }
1090     return status;
1093 #if defined (__cplusplus)
1095 #endif /* defined (__cplusplus) */