90cbf6dfaff7fae02c964eb8c1bd8bd52889de65
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 */
70 /*
71 * ZEROINIT_CHUNKS - Set to 1 to zero-init chunk allocations for
72 * dynamically allocated remote core memory carveout
73 * sections. Default is 0 to achieve better startup
74 * performance.
75 */
76 #define ZEROINIT_CHUNKS 0
78 #define RSC_TABLE_STRING ".resource_table"
79 #define DDR_MEM 0x80000000
81 typedef struct Carveout_Elem_tag {
82 List_Elem elem;
83 UInt32 addr;
84 UInt32 size;
85 } Carveout_Elem;
87 typedef struct Carveout_Object_tag {
88 UInt32 addr;
89 UInt32 size;
90 List_Handle freeBlocks;
91 } Carveout_Object;
93 /*!
94 * @brief RscTable Header
95 */
96 typedef struct RscTable_Header_tag {
97 UInt32 ver;
98 UInt32 num;
99 UInt32 reserved[2];
100 UInt32 offset[];
101 } RscTable_Header;
103 /*!
104 * @brief RscTable Entry
105 */
106 typedef struct RscTable_MemEntry_tag {
107 UInt32 type;
108 UInt32 da; /* Device Virtual Address */
109 UInt32 pa; /* Physical Address */
110 UInt32 len;
111 UInt32 flags;
112 UInt32 reserved;
113 Char name[32];
114 } RscTable_MemEntry;
116 /*!
117 * @brief RscTable Module state object
118 */
119 typedef struct RscTable_ModuleObject_tag {
120 RscTable_Handle handles [MultiProc_MAXPROCESSORS];
121 /*!< Array of Handles of RscTable instances */
122 } RscTable_ModuleObject;
124 /*!
125 * @brief RscTable instance object
126 */
127 struct RscTable_Object_tag {
128 UInt16 procId;
129 /*!< Processor ID associated with this RscTable. */
130 Char * fileName;
131 /*!< File name associated with this RscTable. */
132 Void * rscTable;
133 /*!< Pointer to the resource table. */
134 UInt32 rscTableLen;
135 /*!< Resource table length. */
136 UInt32 rscTableDA;
137 /*!< Resource table device address. */
138 Carveout_Object * carveout[SYSLINK_MAX_MEMENTRIES];
139 /*!< Carveouts for this table. */
140 UInt32 numCarveouts;
141 /*!< Carveouts for this table. */
142 SysLink_MemEntry memEntries[SYSLINK_MAX_MEMENTRIES];
143 /*!< Memory Entries for the remote processor. */
144 UInt32 numMemEntries;
145 /*!< Number of Memory Entries in the memEntries array. */
146 struct fw_rsc_vdev_vring * vrings;
147 /*!< Vring info for the remote processor. */
148 UInt32 numVrings;
149 /*!< Number of vrings. */
150 UInt32 vringPa;
151 /*!< PAddr of vrings space. */
152 UInt32 vringBufsPa;
153 /*!< PAddr of vring bufs space. */
154 struct fw_rsc_trace trace;
155 /*!< Trace info. */
156 List_Handle chunks;
157 /*!< Allocated Chunks. */
158 } ;
160 /* Defines the RscTable_Object type. */
161 typedef struct RscTable_Object_tag RscTable_Object;
163 /* =============================================================================
164 * Globals
165 * =============================================================================
166 */
167 /*!
168 * @var RscTable_state
169 *
170 * @brief RscTable state object variable
171 */
172 #if !defined(SYSLINK_BUILD_DEBUG)
173 static
174 #endif /* if !defined(SYSLINK_BUILD_DEBUG) */
175 RscTable_ModuleObject RscTable_state;
178 /* =============================================================================
179 * APIs
180 * =============================================================================
181 */
183 RscTable_Handle
184 RscTable_alloc (Char * fileName, UInt16 procId)
185 {
186 Int status = 0;
187 RscTable_Object * obj = NULL;
188 OsalKfile_Handle fileDesc = NULL;
189 UInt32 res_offs = 0, res_addr = 0, res_size = 0;
190 List_Params params;
192 // Check if this one is already registered
193 if (RscTable_state.handles[procId]) {
194 /* Not setting status here since this function does not return status.*/
195 GT_setFailureReason (curTrace,
196 GT_4CLASS,
197 "RscTable_alloc",
198 RSCTABLE_E_INVALIDARG,
199 "Invalid procId specified");
200 return NULL;
201 }
203 // Find the resource table in the file
204 status = OsalKfile_open (fileName, "r", &fileDesc);
205 if (status < 0) {
206 /* Not setting status here since this function does not return status.*/
207 GT_setFailureReason (curTrace,
208 GT_4CLASS,
209 "RscTable_alloc",
210 RSCTABLE_E_INVALIDARG,
211 "Invalid fileDesc specified");
212 return NULL;
213 }
215 status = DLOAD_get_section_offset((LOADER_FILE_DESC *)fileDesc,
216 RSC_TABLE_STRING, &res_offs, &res_size,
217 &res_addr);
218 if (status >= 0) {
219 obj = Memory_calloc(NULL, sizeof (RscTable_Object), 0, NULL);
220 if (obj != NULL) {
221 // Allocate memory to hold the table
222 obj->rscTable = Memory_alloc(NULL, res_size, 0, NULL);
223 if (obj->rscTable == NULL) {
224 /* Not setting status here since this function does not return
225 * status.*/
226 GT_setFailureReason (curTrace,
227 GT_4CLASS,
228 "RscTable_alloc",
229 RSCTABLE_E_MEMORY,
230 "Unable to allocate rscTable");
231 Memory_free(NULL, obj, sizeof (RscTable_Object));
232 obj = NULL;
233 }
234 else {
235 obj->rscTableLen = res_size;
236 status = OsalKfile_seek(fileDesc, res_offs,
237 OsalKfile_Pos_SeekSet);
238 if (status < 0) {
239 /* Not setting status here since this function does not
240 * return status.*/
241 GT_setFailureReason (curTrace,
242 GT_4CLASS,
243 "RscTable_alloc",
244 RSCTABLE_E_FAIL,
245 "Unable to seek to rsctable in file");
246 Memory_free(NULL, obj->rscTable, res_size);
247 Memory_free(NULL, obj, sizeof (RscTable_Object));
248 obj = NULL;
249 }
250 else {
251 // Copy the table to the allocated memory
252 status = OsalKfile_read(fileDesc, (char *)obj->rscTable, 1,
253 res_size);
254 if (status < 0) {
255 /* Not setting status here since this function does not
256 * return status.*/
257 GT_setFailureReason (curTrace,
258 GT_4CLASS,
259 "RscTable_alloc",
260 RSCTABLE_E_FAIL,
261 "Unable to read rsctable in file");
262 Memory_free(NULL, obj->rscTable, res_size);
263 Memory_free(NULL, obj, sizeof (RscTable_Object));
264 obj = NULL;
265 }
266 else {
267 obj->rscTableDA = res_addr;
268 List_Params_init(¶ms);
269 obj->chunks = List_create(¶ms);
270 if (obj->chunks == NULL) {
271 /* Not setting status here since this function does
272 * not return status.*/
273 GT_setFailureReason (curTrace,
274 GT_4CLASS,
275 "RscTable_alloc",
276 RSCTABLE_E_FAIL,
277 "Unable to create list");
278 Memory_free(NULL, obj->rscTable, res_size);
279 Memory_free(NULL, obj, sizeof (RscTable_Object));
280 obj = NULL;
281 }
282 }
283 }
284 }
285 }
286 else {
287 /* Not setting status here since this function does not return
288 * status.*/
289 GT_setFailureReason (curTrace,
290 GT_4CLASS,
291 "RscTable_alloc",
292 RSCTABLE_E_MEMORY,
293 "Unable to allocate obj");
294 }
295 }
296 else {
297 /* Not setting status here since this function does not return status.*/
298 GT_setFailureReason (curTrace,
299 GT_4CLASS,
300 "RscTable_alloc",
301 RSCTABLE_E_FAIL,
302 "Unable to find resource table in file");
303 }
305 OsalKfile_close(&fileDesc);
307 // If successful, save coreId-handle pair for later access
308 if (obj) {
309 obj->procId = procId;
310 RscTable_state.handles[procId] = (RscTable_Handle)obj;
311 }
313 return (RscTable_Handle)obj;
314 }
316 /* Helper functions for processing carveout */
317 Int Carveout_register (RscTable_Object *obj, UInt32 id, Ptr carveOut,
318 UInt32 carveOutLen)
319 {
320 Int status = 0;
321 Carveout_Object * cout = NULL;
322 List_Params params;
324 cout = Memory_alloc(NULL, sizeof(Carveout_Object), 0, NULL);
325 if (cout) {
326 cout->addr = (UInt32)carveOut;
327 cout->size = carveOutLen;
328 List_Params_init(¶ms);
329 cout->freeBlocks = List_create(¶ms);
330 if (cout->freeBlocks == NULL) {
331 status = RSCTABLE_E_MEMORY;
332 GT_setFailureReason (curTrace,
333 GT_4CLASS,
334 "Carveout_register",
335 status,
336 "Unable to create free list");
337 Memory_free(NULL, cout, sizeof(Carveout_Object));
338 cout = NULL;
339 }
340 else {
341 // Add the whole of the memory to the free list
342 Carveout_Elem * elem = Memory_alloc(NULL, sizeof(Carveout_Elem),
343 0, NULL);
344 if (elem) {
345 elem->addr = cout->addr;
346 elem->size = cout->size;
347 List_put(cout->freeBlocks, (List_Elem *)elem);
348 }
349 else {
350 status = RSCTABLE_E_MEMORY;
351 GT_setFailureReason (curTrace,
352 GT_4CLASS,
353 "Carveout_register",
354 status,
355 "Unable to allocate elem");
356 List_delete(&cout->freeBlocks);
357 Memory_free(NULL, cout, sizeof(Carveout_Object));
358 cout = NULL;
359 }
360 }
361 }
362 else {
363 status = RSCTABLE_E_MEMORY;
364 GT_setFailureReason (curTrace,
365 GT_4CLASS,
366 "Carveout_register",
367 status,
368 "Unable to allocate carveout structure");
369 }
371 obj->carveout[id] = cout;
372 obj->numCarveouts++;
373 return status;
374 }
376 Int Carveout_unregister (RscTable_Object *obj, UInt32 id)
377 {
378 Int status = 0;
379 List_Elem * elem = NULL;
381 if (obj->carveout[id]) {
382 if (obj->carveout[id]->freeBlocks) {
383 while ((elem = List_get(obj->carveout[id]->freeBlocks)))
384 Memory_free(NULL, elem, sizeof(Carveout_Elem));
385 List_delete(&obj->carveout[id]->freeBlocks);
386 }
388 Memory_free(NULL, obj->carveout[id], sizeof(Carveout_Object));
389 obj->carveout[id] = NULL;
390 obj->numCarveouts--;
391 }
392 else {
393 status = RSCTABLE_E_INVALIDARG;
394 GT_setFailureReason (curTrace,
395 GT_4CLASS,
396 "Carveout_unregister",
397 status,
398 "No carveout associated with obj");
399 }
401 return status;
402 }
404 // allocate any addr
405 Int Chunk_allocate (RscTable_Object *obj, UInt32 size, UInt32 * pa)
406 {
407 Int status = 0;
408 List_Elem * elem = NULL;
409 Void * da;
410 long long paddr;
411 UInt32 len;
413 if (!pa || !obj || !obj->chunks) {
414 status = RSCTABLE_E_INVALIDARG;
415 GT_setFailureReason (curTrace,
416 GT_4CLASS,
417 "Chunk_allocate",
418 status,
419 "Invalid arg passed");
420 GT_3trace(curTrace, GT_4CLASS, "obj [0x%x] obj->chunks [0x%x] pa [0x%x]", obj, obj ? obj->chunks : NULL, pa);
421 }
422 else {
423 // first try to allocate contiguous mem
424 da = mmap64(NULL, size,
425 PROT_NOCACHE | PROT_READ | PROT_WRITE,
426 #if ZEROINIT_CHUNKS
427 MAP_ANON | MAP_PHYS | MAP_SHARED,
428 #else
429 MAP_ANON | MAP_PHYS | MAP_SHARED | MAP_NOINIT,
430 #endif
431 NOFD,
432 0);
433 if (da == MAP_FAILED) {
434 // TODO: try to allocate non-contigous mem then get the pages
435 status = RSCTABLE_E_MEMORY;
436 GT_setFailureReason (curTrace,
437 GT_4CLASS,
438 "Chunk_allocate",
439 status,
440 "Unable to allocate chunk");
441 }
442 else {
443 /* Make sure the memory is contiguous */
444 status = mem_offset64(da, NOFD, size, &paddr, &len);
445 if (status || (len != size)) {
446 munmap(da, size);
447 status = RSCTABLE_E_MEMORY;
448 GT_setFailureReason (curTrace,
449 GT_4CLASS,
450 "Chunk_allocate",
451 status,
452 "mem_offset64 failed");
453 }
454 else {
455 *pa = (UInt32)paddr;
456 // save the memory so that it can be freed later
457 elem = Memory_alloc(NULL, sizeof(Carveout_Elem), 0, NULL);
458 if (elem == NULL) {
459 munmap(da, size);
460 status = RSCTABLE_E_MEMORY;
461 GT_setFailureReason (curTrace,
462 GT_4CLASS,
463 "Chunk_allocate",
464 status,
465 "Memory_alloc failed");
466 }
467 else {
468 ((Carveout_Elem *)elem)->addr = (UInt32)da;
469 ((Carveout_Elem *)elem)->size = size;
470 List_put(obj->chunks, elem);
471 }
472 }
473 }
474 }
475 return status;
476 }
478 // allocate any addr from a specified carveout
479 Int Carveout_allocate (RscTable_Object *obj, UInt32 size, UInt32 * pa)
480 {
481 Int status = 0;
482 Carveout_Object * cout = NULL;
483 List_Elem * elem = NULL;
484 Bool found = FALSE;
485 UInt i = 0;
487 if (!pa || !obj || !obj->numCarveouts) {
488 status = RSCTABLE_E_INVALIDARG;
489 GT_setFailureReason (curTrace,
490 GT_4CLASS,
491 "Carveout_allocate",
492 status,
493 "Invalid arg passed");
494 }
495 else {
496 for (i = 0; i < obj->numCarveouts; i++) {
497 *pa = 0;
498 cout = obj->carveout[i];
500 // search for a free block with sufficient size
501 List_traverse(elem, cout->freeBlocks) {
502 if (((Carveout_Elem *)elem)->size >= size) {
503 found = TRUE;
504 break;
505 }
506 }
507 if (found) {
508 UInt32 rem = 0;
509 UInt32 addr = 0;
511 // found a spot for our request
512 addr = ((Carveout_Elem *)elem)->addr;
513 rem = ((Carveout_Elem *)elem)->size - size;
514 if (rem) {
515 ((Carveout_Elem *)elem)->addr += size;
516 ((Carveout_Elem *)elem)->size = rem;
517 }
518 else {
519 List_remove(cout->freeBlocks, elem);
520 Memory_free (NULL, elem, sizeof(Carveout_Elem));
521 }
522 *pa = addr;
523 break;
524 }
525 }
526 if (i == obj->numCarveouts) {
527 status = RSCTABLE_E_MEMORY;
528 GT_setFailureReason (curTrace,
529 GT_4CLASS,
530 "Carveout_allocate",
531 status,
532 "Not enough room in carveout");
533 }
534 }
535 return status;
536 }
538 // allocate specific addr
539 Int Carveout_reserve (RscTable_Object *obj, UInt32 size, UInt32 pa)
540 {
541 Int status = 0;
542 Carveout_Object * cout = NULL;
543 List_Elem * elem = NULL;
544 Bool found = FALSE;
545 UInt i = 0;
547 if (!pa || !obj || !obj->numCarveouts) {
548 status = RSCTABLE_E_INVALIDARG;
549 GT_setFailureReason (curTrace,
550 GT_4CLASS,
551 "Carveout_reserve",
552 status,
553 "Invalid arg passed");
554 }
555 else {
556 for (i = 0; i < obj->numCarveouts; i++) {
557 cout = obj->carveout[i];
559 // search for a free block with sufficient size
560 List_traverse(elem, cout->freeBlocks) {
561 if ((((Carveout_Elem *)elem)->addr <= pa) &&
562 ((((Carveout_Elem *)elem)->addr +
563 ((Carveout_Elem *)elem)->size) >= (pa + size))) {
564 found = TRUE;
565 break;
566 }
567 }
568 if (found) {
569 UInt32 rem_start = 0;
570 UInt32 rem_end = 0;
572 // found a spot for our request
573 if (((Carveout_Elem *)elem)->addr < pa) {
574 // there is free mem at the beginning of the block
575 rem_start = pa - ((Carveout_Elem *)elem)->addr;
576 }
577 if (((Carveout_Elem *)elem)->addr + ((Carveout_Elem *)elem)->size >
578 (pa + size)) {
579 // there is free mem at the end of the block
580 rem_end = ((Carveout_Elem *)elem)->addr +
581 ((Carveout_Elem *)elem)->size - (pa + size);
582 }
583 // now carve up the block
584 if (rem_start) {
585 ((Carveout_Elem *)elem)->size = rem_start;
586 }
587 else if (rem_end) {
588 ((Carveout_Elem *)elem)->size = rem_end;
589 ((Carveout_Elem *)elem)->addr = pa + size;
590 }
591 else {
592 List_remove(cout->freeBlocks, elem);
593 Memory_free (NULL, elem, sizeof(Carveout_Elem));
594 }
595 if (rem_start && rem_end) {
596 Carveout_Elem * c_elem = NULL;
597 c_elem = Memory_alloc (NULL, sizeof(Carveout_Elem), 0, NULL);
598 if (c_elem) {
599 c_elem->size = rem_end;
600 c_elem->addr = pa + size;
601 List_insert(cout->freeBlocks, (List_Elem *)&c_elem->elem,
602 elem->next);
603 }
604 else {
605 /* add mem back to free block */
606 ((Carveout_Elem *)elem)->size += (size + rem_end);
607 status = RSCTABLE_E_MEMORY;
608 GT_setFailureReason (curTrace,
609 GT_4CLASS,
610 "Carveout_reserve",
611 status,
612 "Unable to allocate elem");
613 }
614 }
615 break;
616 }
617 }
618 if (i == obj->numCarveouts) {
619 status = RSCTABLE_E_MEMORY;
620 GT_setFailureReason (curTrace,
621 GT_4CLASS,
622 "Carveout_reserve",
623 status,
624 "Specified addr/size not available");
626 }
627 }
628 return status;
629 }
631 Int
632 RscTable_process (UInt16 procId, Bool mmuEnabled, UInt32 numCarveouts,
633 Ptr carveOut[], UInt32 carveOutLen[], Bool tryAlloc,
634 UInt32 * numBlocks)
635 {
636 Int status = 0;
637 Int ret = 0;
638 RscTable_Object * obj = NULL;
639 RscTable_Header * table = NULL;
640 UInt i = 0, j = 0;
641 UInt dmem_num = 0;
642 #if !ZEROINIT_CHUNKS
643 UInt32 vringVA = 0, vringSize = 0;
644 #endif
646 // Find the table for this coreId, if not found, return an error
647 if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
648 status = RSCTABLE_E_INVALIDARG;
649 GT_setFailureReason (curTrace,
650 GT_4CLASS,
651 "RscTable_process",
652 status,
653 "Invalid procId specified");
654 return status;
655 }
657 obj = (RscTable_Object *)RscTable_state.handles[procId];
658 table = (RscTable_Header *)obj->rscTable;
660 obj->numMemEntries = 0;
662 // Register carveout mem regions if provided
663 if (numCarveouts && carveOut && carveOutLen) {
664 for (i = 0; i < numCarveouts; i++) {
665 status = Carveout_register(obj, i, carveOut[i], carveOutLen[i]);
666 if (status < 0) {
667 GT_setFailureReason (curTrace,
668 GT_4CLASS,
669 "RscTable_process",
670 status,
671 "Carveout_register failed");
672 return status;
673 }
674 }
675 }
677 // TODO: Check the version
678 printf("RscTable_process: RscTable version is [%d]\n", table->ver);
680 // Process the table for this core, allocating carveout memory if necessary
681 for (i = 0; i < table->num && !ret; i++) {
682 RscTable_MemEntry * entry =
683 (RscTable_MemEntry *)((UInt32)table + table->offset[i]);
684 switch (entry->type) {
685 case TYPE_CARVEOUT :
686 {
687 // TODO: need to allocate this mem from carveout
688 struct fw_rsc_carveout * cout = (struct fw_rsc_carveout *)entry;
689 UInt32 pa = 0;
690 if (cout->pa == 0)
691 if (mmuEnabled)
692 ret = Chunk_allocate (obj, cout->len, &pa);
693 else {
694 ret = Carveout_reserve (obj, cout->len, cout->da);
695 pa = cout->da;
696 }
697 else
698 ret = Carveout_reserve (obj, cout->len, cout->pa);
699 if (!ret) {
700 cout->pa = pa;
701 if (obj->numMemEntries == SYSLINK_MAX_MEMENTRIES) {
702 ret = -1;
703 }
704 else {
705 obj->memEntries[obj->numMemEntries].slaveVirtAddr =
706 cout->da;
707 obj->memEntries[obj->numMemEntries].masterPhysAddr =
708 cout->pa;
709 obj->memEntries[obj->numMemEntries].size = cout->len;
710 //if (mmuEnabled) {
711 obj->memEntries[obj->numMemEntries].map = TRUE;
712 obj->memEntries[obj->numMemEntries].mapMask =
713 ProcMgr_SLAVEVIRT;
714 //}
715 //else
716 // obj->memEntries[obj->numMemEntries].map = FALSE;
717 obj->memEntries[obj->numMemEntries].isCached = FALSE;
718 obj->memEntries[obj->numMemEntries].isValid = TRUE;
719 obj->numMemEntries++;
720 }
721 }
722 printf ("RscTable_process: carveout [%s] @ da [0x%08x] pa [0x%08x] len [0x%x]\n", cout->name, cout->da, cout->pa, cout->len);
723 break;
724 }
725 case TYPE_DEVMEM :
726 {
727 // only care about mem in DDR for now
728 struct fw_rsc_devmem * dmem = (struct fw_rsc_devmem *)entry;
729 UInt32 pa = 0;
730 if (dmem->pa >= DDR_MEM) {
731 // HACK: treat vring mem specially, vring is always the
732 // first devmem entry, may change in future
733 if (dmem_num++ == 0) {
734 // memory should already be reserved for vring
735 if (obj->vringPa == 0) {
736 // vdev must have been defined first
737 GT_setFailureReason (curTrace,
738 GT_4CLASS,
739 "RscTable_process",
740 status,
741 "Vring Must be Defined First");
743 ret = -1;
744 }
745 else if (obj->vringPa != dmem->pa &&
746 (!tryAlloc || !mmuEnabled)) {
747 // defined pa does not match allocated pa, and
748 // either the mmu is disabled or the platform has
749 // not given permission to allocate on our own
750 ret = -1;
751 GT_setFailureReason (curTrace,
752 GT_4CLASS,
753 "RscTable_process",
754 status,
755 "Vring PA Mis-match");
757 GT_2trace (curTrace, GT_4CLASS,
758 "vringPa is 0x%x, dmem->pa is 0x%x",
759 obj->vringPa, dmem->pa);
760 }
761 else {
762 dmem->pa = obj->vringPa;
763 }
764 }
765 else {
766 ret = Carveout_reserve (obj, dmem->len, dmem->pa);
767 if (ret && mmuEnabled && tryAlloc) {
768 ret = Carveout_allocate (obj, dmem->len, &pa);
769 if (!ret) dmem->pa = pa;
770 }
771 }
772 }
773 if (!ret) {
774 if (obj->numMemEntries == SYSLINK_MAX_MEMENTRIES) {
775 ret = -1;
776 }
777 else {
778 obj->memEntries[obj->numMemEntries].slaveVirtAddr =
779 dmem->da;
780 obj->memEntries[obj->numMemEntries].masterPhysAddr =
781 dmem->pa;
782 obj->memEntries[obj->numMemEntries].size = dmem->len;
783 //if (mmuEnabled) {
784 obj->memEntries[obj->numMemEntries].map = TRUE;
785 obj->memEntries[obj->numMemEntries].mapMask =
786 ProcMgr_SLAVEVIRT;
787 //}
788 //else
789 // obj->memEntries[obj->numMemEntries].map = FALSE;
790 obj->memEntries[obj->numMemEntries].isCached = FALSE;
791 obj->memEntries[obj->numMemEntries].isValid = TRUE;
792 obj->numMemEntries++;
793 }
794 }
796 // TODO: need to make sure this mem exists/is set aside, or allocate it
797 printf ("RscTable_process: devmem [%s] @ da [0x%08x] pa [0x%08x] len [0x%x]\n", dmem->name, dmem->da, dmem->pa, dmem->len);
798 break;
799 }
800 case TYPE_TRACE :
801 {
802 // TODO: save da for future use
803 struct fw_rsc_trace * trace = (struct fw_rsc_trace *)entry;
804 Memory_copy(&obj->trace, trace, sizeof(*trace));
805 printf ("RscTable_process: trace [%s] @ da [0x%08x] len [0x%x]\n", trace->name, trace->da, trace->len);
806 break;
807 }
808 case TYPE_VDEV :
809 {
810 // TODO: save vring info for future use
811 struct fw_rsc_vdev *vdev = (struct fw_rsc_vdev *)entry;
812 struct fw_rsc_vdev_vring * vring = NULL;
813 UInt32 vr_size = 0;
814 UInt32 vr_bufs_size = 0;
815 UInt32 pa = 0;
816 obj->numVrings = vdev->num_of_vrings;
817 obj->vrings = Memory_alloc(NULL,
818 sizeof (*vring) * obj->numVrings, 0,
819 NULL);
820 if (!obj->vrings)
821 ret = -1;
822 for (j = 0; j < vdev->num_of_vrings && !ret; j++) {
823 vring = (struct fw_rsc_vdev_vring *)
824 ((UInt32)vdev + sizeof(*vdev) +
825 (sizeof(*vring) * j));
826 Memory_copy (&obj->vrings[j], vring, sizeof (*vring));
827 printf ("RscTable_process: vring [%d] @ [0x%08x]\n",
828 vring->num, vring->da);
829 // Hack, we know this is the size alignment
830 if (vring->num != MessageQCopy_NUMBUFS ||
831 vring->align != MessageQCopy_VRINGALIGN) {
832 printf ("RscTable_process: warning size mis-match!\n");
833 ret = -1;
834 }
835 vr_size += ROUND_UP(MessageQCopy_RINGSIZE, 0x4000);
836 vr_bufs_size += (vring->num) * RPMSG_BUF_SIZE;
837 }
838 if (!ret)
839 // HACK: round up to multiple of 1MB, because we know this
840 // is the size of the remote entry
841 if (mmuEnabled)
842 ret = Chunk_allocate(obj,
843 ROUND_UP(vr_size + vr_bufs_size, 0x100000),
844 &pa);
845 else
846 ret = Carveout_allocate(obj,
847 ROUND_UP(vr_size + vr_bufs_size, 0x100000),
848 &pa);
849 else if (obj->vrings) {
850 Memory_free (NULL, obj->vrings,
851 sizeof(*vring) * obj->numVrings);
852 obj->vrings = NULL;
853 }
855 if (!ret) {
856 #if !ZEROINIT_CHUNKS
857 /* Map the phys mem to local */
858 vringSize = vr_size + vr_bufs_size;
859 vringVA = (UInt32)mmap_device_io(vringSize, pa);
860 if (vringVA != MAP_DEVICE_FAILED) {
861 /* Zero-init the vring */
862 Memory_set((Ptr)vringVA, 0, vringSize);
863 munmap_device_io(vringVA, vringSize);
864 }
865 else {
866 GT_0trace(curTrace, GT_4CLASS,
867 "RscTable_alloc: "
868 "Warning - Unable to zero-init vring mem");
869 }
870 #endif
872 obj->vringPa = pa;
873 obj->vringBufsPa = pa + vr_size;
874 }
875 break;
876 }
877 case TYPE_CRASHDUMP :
878 // what to do with this?
879 break;
880 default :
881 break;
882 }
883 }
885 if (ret) {
886 status = RSCTABLE_E_FAIL;
887 GT_setFailureReason (curTrace,
888 GT_4CLASS,
889 "RscTable_process",
890 status,
891 "Failure happened in processing table");
892 if (obj->vrings)
893 Memory_free(NULL, obj->vrings,
894 sizeof(*obj->vrings) * obj->numVrings);
895 obj->vrings = NULL;
896 obj->numMemEntries = 0;
897 }
898 *numBlocks = obj->numMemEntries;
899 // Can un-register the carveout now? Don't need it anymore?
900 for (i = 0; i < numCarveouts; i++)
901 Carveout_unregister(obj, i);
903 return status;
904 }
906 Int
907 RscTable_getMemEntries (UInt16 procId, SysLink_MemEntry *memEntries,
908 UInt32 * numMemEntries)
909 {
910 Int status = 0;
911 RscTable_Object *obj = NULL;
913 // Find the table for this procId, if not found, return an error
914 if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
915 status = RSCTABLE_E_INVALIDARG;
916 GT_setFailureReason (curTrace,
917 GT_4CLASS,
918 "RscTable_getMemEntries",
919 status,
920 "Invalid ProcId specified");
921 return status;
922 }
924 obj = (RscTable_Object *)RscTable_state.handles[procId];
926 if (obj->memEntries && obj->numMemEntries &&
927 *numMemEntries >= obj->numMemEntries) {
928 *numMemEntries = obj->numMemEntries;
929 Memory_copy(memEntries, obj->memEntries,
930 sizeof(*memEntries) * obj->numMemEntries);
931 }
932 else {
933 status = RSCTABLE_E_INVALIDARG;
934 GT_setFailureReason (curTrace,
935 GT_4CLASS,
936 "RscTable_getMemEntries",
937 status,
938 "Invalid num of memEntries or memEntries is NULL");
939 }
941 return status;
942 }
944 Int
945 RscTable_getInfo (UInt16 procId, UInt32 type, UInt32 extra, UInt32 * da,
946 UInt32 *pa, UInt32 * len)
947 {
948 Int status = 0;
949 RscTable_Object *obj = NULL;
951 // Find the table for this procId, if not found, return an error
952 if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
953 status = RSCTABLE_E_INVALIDARG;
954 GT_setFailureReason (curTrace,
955 GT_4CLASS,
956 "RscTable_getInfo",
957 status,
958 "Invalid procId specified");
959 return status;
960 }
962 obj = (RscTable_Object *)RscTable_state.handles[procId];
964 if (type == TYPE_TRACE) {
965 if (da && len) {
966 *da = obj->trace.da;
967 *len = obj->trace.len;
968 }
969 else {
970 status = RSCTABLE_E_INVALIDARG;
971 GT_setFailureReason (curTrace,
972 GT_4CLASS,
973 "RscTable_getInfo",
974 status,
975 "Invalid pointer passed");
976 }
977 }
978 else if (type == TYPE_VDEV) {
979 if (extra == 0 && len) {
980 *len = obj->numVrings;
981 }
982 else if (extra < obj->numVrings && da) {
983 *da = obj->vrings[extra-1].da;
984 }
985 else {
986 status = RSCTABLE_E_INVALIDARG;
987 GT_setFailureReason (curTrace,
988 GT_4CLASS,
989 "RscTable_getInfo",
990 status,
991 "Invalid pointer passed");
992 }
993 }
994 else {
995 // type not supported
996 status = -1;
997 }
999 return status;
1000 // Retrieve the info for a certain resource type (ex. Vring info)
1001 }
1003 Int
1004 RscTable_update (UInt16 procId, ProcMgr_Handle procHandle)
1005 {
1006 // Updates the table to physical memory so that phys addrs are available to
1007 // the remote cores. This should be called only after loading the remote
1008 // cores.
1009 Int status = 0;
1010 RscTable_Object *obj = NULL;
1011 UInt32 rscTableVA = 0, rscTablePA = 0;
1013 // Find the table for this procId, if not found, return an error
1014 if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
1015 status = RSCTABLE_E_INVALIDARG;
1016 GT_setFailureReason (curTrace,
1017 GT_4CLASS,
1018 "RscTable_update",
1019 status,
1020 "Invalid ProcId specified");
1021 return status;
1022 }
1024 obj = (RscTable_Object *)RscTable_state.handles[procId];
1026 status = ProcMgr_translateAddr(procHandle, (Ptr *)&rscTablePA,
1027 ProcMgr_AddrType_MasterPhys,
1028 (Ptr)obj->rscTableDA,
1029 ProcMgr_AddrType_SlaveVirt);
1030 if (status < 0) {
1031 status = RSCTABLE_E_FAIL;
1032 GT_setFailureReason (curTrace,
1033 GT_4CLASS,
1034 "RscTable_update",
1035 status,
1036 "Unable to get the Master PA for RscTable");
1037 }
1038 else {
1039 /* Map the phys mem to local */
1040 rscTableVA = (UInt32)mmap_device_io(obj->rscTableLen, rscTablePA);
1041 if (rscTableVA != MAP_DEVICE_FAILED) {
1042 /* Copy the updated table to the memory */
1043 Memory_copy((Ptr)rscTableVA, obj->rscTable, obj->rscTableLen);
1044 munmap_device_io(rscTableVA, obj->rscTableLen);
1045 }
1046 else {
1047 status = RSCTABLE_E_FAIL;
1048 GT_setFailureReason (curTrace,
1049 GT_4CLASS,
1050 "RscTable_update",
1051 status,
1052 "Unable to map memory");
1053 }
1054 }
1056 return status;
1057 }
1059 Int
1060 RscTable_free (RscTable_Handle * handle)
1061 {
1062 Int status = 0;
1063 RscTable_Object * obj = NULL;
1064 Int i = 0;
1065 List_Elem * elem;
1067 // Remove resource table from coreId-Handle pair list
1068 if (handle && *handle) {
1069 // sanity check
1070 for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
1071 if (RscTable_state.handles[i] == *handle)
1072 break;
1073 }
1074 if (i < MultiProc_MAXPROCESSORS) {
1075 obj = (RscTable_Object *)(*handle);
1076 // Additional sanity check
1077 if (obj->procId == i) {
1078 // Free vrings, memEntries, etc.
1079 if (obj->chunks) {
1080 while ((elem = List_get(obj->chunks))) {
1081 Carveout_Elem * co_elem = (Carveout_Elem *)elem;
1082 munmap((Void *)co_elem->addr, co_elem->size);
1083 Memory_free(NULL, co_elem, sizeof(Carveout_Elem));
1084 }
1085 List_delete(&obj->chunks);
1086 obj->chunks = NULL;
1087 }
1088 if (obj->vrings)
1089 Memory_free(NULL, obj->vrings,
1090 sizeof(*obj->vrings) * obj->numVrings);
1091 obj->vrings = NULL;
1092 obj->numMemEntries = 0;
1094 if (obj->rscTable)
1095 Memory_free(NULL, obj->rscTable, obj->rscTableLen);
1096 obj->rscTableDA = 0;
1097 Memory_free(NULL, obj, sizeof (RscTable_Object));
1098 *handle = NULL;
1099 RscTable_state.handles[i] = NULL;
1100 }
1101 }
1102 else {
1103 status = RSCTABLE_E_INVALIDARG;
1104 GT_setFailureReason (curTrace,
1105 GT_4CLASS,
1106 "RscTable_free",
1107 status,
1108 "Invalid handle passed");
1109 }
1110 }
1111 else {
1112 status = RSCTABLE_E_INVALIDARG;
1113 GT_setFailureReason (curTrace,
1114 GT_4CLASS,
1115 "RscTable_free",
1116 status,
1117 "Invalid handle passed");
1118 }
1120 return status;
1121 }
1123 Int RscTable_setStatus(UInt16 procId, UInt32 value)
1124 {
1125 Int i;
1126 Int status = 0;
1128 RscTable_Object * obj = (RscTable_Object *)RscTable_state.handles[procId];
1129 RscTable_Header * table = (RscTable_Header *)obj->rscTable;
1131 /* Look for the vdev entry and update the status */
1132 for (i = 0; i < table->num; i++) {
1133 RscTable_MemEntry * entry =
1134 (RscTable_MemEntry *)((UInt32)table + table->offset[i]);
1135 if (entry->type == TYPE_VDEV) {
1136 struct fw_rsc_vdev *vdev = (struct fw_rsc_vdev *)entry;
1137 vdev->status = value;
1138 break;
1139 }
1140 }
1142 if (i == table->num) {
1143 status = RSCTABLE_E_FAIL;
1144 }
1146 return status;
1147 }
1149 #if defined (__cplusplus)
1150 }
1151 #endif /* defined (__cplusplus) */