1 /*
2 * @file RscTable.c
3 *
4 * @brief Resource Table parser.
5 *
6 * ============================================================================
7 *
8 * Copyright (c) 2012-2014, 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 /*!
88 * @brief RscTable Header
89 */
90 typedef struct RscTable_Header_tag {
91 UInt32 ver;
92 UInt32 num;
93 UInt32 reserved[2];
94 UInt32 offset[];
95 } RscTable_Header;
97 /*!
98 * @brief RscTable Entry
99 */
100 typedef struct RscTable_MemEntry_tag {
101 UInt32 type;
102 UInt32 da; /* Device Virtual Address */
103 UInt32 pa; /* Physical Address */
104 UInt32 len;
105 UInt32 flags;
106 UInt32 reserved;
107 Char name[32];
108 } RscTable_MemEntry;
110 /*!
111 * @brief RscTable Module state object
112 */
113 typedef struct RscTable_ModuleObject_tag {
114 RscTable_Handle handles [MultiProc_MAXPROCESSORS];
115 /*!< Array of Handles of RscTable instances */
116 } RscTable_ModuleObject;
118 /*!
119 * @brief RscTable instance object
120 */
121 struct RscTable_Object_tag {
122 UInt16 procId;
123 /*!< Processor ID associated with this RscTable. */
124 Char * fileName;
125 /*!< File name associated with this RscTable. */
126 Void * rscTable;
127 /*!< Pointer to the resource table. */
128 UInt32 rscTableLen;
129 /*!< Resource table length. */
130 UInt32 rscTableDA;
131 /*!< Resource table device address. */
132 SysLink_MemEntry memEntries[SYSLINK_MAX_MEMENTRIES];
133 /*!< Memory Entries for the remote processor. */
134 UInt32 numMemEntries;
135 /*!< Number of Memory Entries in the memEntries array. */
136 struct fw_rsc_vdev_vring * vrings;
137 /*!< Vring info for the remote processor. */
138 UInt32 numVrings;
139 /*!< Number of vrings. */
140 UInt32 vringPa;
141 /*!< PAddr of vrings space. */
142 UInt32 vringBufsPa;
143 /*!< PAddr of vring bufs space. */
144 struct fw_rsc_trace trace;
145 /*!< Trace info. */
146 List_Handle chunks;
147 /*!< Allocated Chunks. */
148 } ;
150 /* Defines the RscTable_Object type. */
151 typedef struct RscTable_Object_tag RscTable_Object;
153 /* =============================================================================
154 * Globals
155 * =============================================================================
156 */
157 /*!
158 * @var RscTable_state
159 *
160 * @brief RscTable state object variable
161 */
162 #if !defined(SYSLINK_BUILD_DEBUG)
163 static
164 #endif /* if !defined(SYSLINK_BUILD_DEBUG) */
165 RscTable_ModuleObject RscTable_state;
168 /* =============================================================================
169 * APIs
170 * =============================================================================
171 */
173 RscTable_Handle
174 RscTable_alloc (Char * fileName, UInt16 procId)
175 {
176 Int status = 0;
177 RscTable_Object * obj = NULL;
178 OsalKfile_Handle fileDesc = NULL;
179 UInt32 res_offs = 0, res_addr = 0, res_size = 0;
180 List_Params params;
182 // Check if this one is already registered
183 if (RscTable_state.handles[procId]) {
184 /* Not setting status here since this function does not return status.*/
185 GT_setFailureReason (curTrace,
186 GT_4CLASS,
187 "RscTable_alloc",
188 RSCTABLE_E_INVALIDARG,
189 "Invalid procId specified");
190 return NULL;
191 }
193 // Find the resource table in the file
194 status = OsalKfile_open (fileName, "r", &fileDesc);
195 if (status < 0) {
196 /* Not setting status here since this function does not return status.*/
197 GT_setFailureReason (curTrace,
198 GT_4CLASS,
199 "RscTable_alloc",
200 RSCTABLE_E_INVALIDARG,
201 "Invalid fileDesc specified");
202 return NULL;
203 }
205 status = DLOAD_get_section_offset((LOADER_FILE_DESC *)fileDesc,
206 RSC_TABLE_STRING, &res_offs, &res_size,
207 &res_addr);
208 if (status >= 0) {
209 obj = Memory_calloc(NULL, sizeof (RscTable_Object), 0, NULL);
210 if (obj != NULL) {
211 // Allocate memory to hold the table
212 obj->rscTable = Memory_alloc(NULL, res_size, 0, NULL);
213 if (obj->rscTable == NULL) {
214 /* Not setting status here since this function does not return
215 * status.*/
216 GT_setFailureReason (curTrace,
217 GT_4CLASS,
218 "RscTable_alloc",
219 RSCTABLE_E_MEMORY,
220 "Unable to allocate rscTable");
221 Memory_free(NULL, obj, sizeof (RscTable_Object));
222 obj = NULL;
223 }
224 else {
225 obj->rscTableLen = res_size;
226 status = OsalKfile_seek(fileDesc, res_offs,
227 OsalKfile_Pos_SeekSet);
228 if (status < 0) {
229 /* Not setting status here since this function does not
230 * return status.*/
231 GT_setFailureReason (curTrace,
232 GT_4CLASS,
233 "RscTable_alloc",
234 RSCTABLE_E_FAIL,
235 "Unable to seek to rsctable in file");
236 Memory_free(NULL, obj->rscTable, res_size);
237 Memory_free(NULL, obj, sizeof (RscTable_Object));
238 obj = NULL;
239 }
240 else {
241 // Copy the table to the allocated memory
242 status = OsalKfile_read(fileDesc, (char *)obj->rscTable, 1,
243 res_size);
244 if (status < 0) {
245 /* Not setting status here since this function does not
246 * return status.*/
247 GT_setFailureReason (curTrace,
248 GT_4CLASS,
249 "RscTable_alloc",
250 RSCTABLE_E_FAIL,
251 "Unable to read rsctable in file");
252 Memory_free(NULL, obj->rscTable, res_size);
253 Memory_free(NULL, obj, sizeof (RscTable_Object));
254 obj = NULL;
255 }
256 else {
257 obj->rscTableDA = res_addr;
258 List_Params_init(¶ms);
259 obj->chunks = List_create(¶ms);
260 if (obj->chunks == NULL) {
261 /* Not setting status here since this function does
262 * not return status.*/
263 GT_setFailureReason (curTrace,
264 GT_4CLASS,
265 "RscTable_alloc",
266 RSCTABLE_E_FAIL,
267 "Unable to create list");
268 Memory_free(NULL, obj->rscTable, res_size);
269 Memory_free(NULL, obj, sizeof (RscTable_Object));
270 obj = NULL;
271 }
272 }
273 }
274 }
275 }
276 else {
277 /* Not setting status here since this function does not return
278 * status.*/
279 GT_setFailureReason (curTrace,
280 GT_4CLASS,
281 "RscTable_alloc",
282 RSCTABLE_E_MEMORY,
283 "Unable to allocate obj");
284 }
285 }
286 else {
287 /* Not setting status here since this function does not return status.*/
288 GT_setFailureReason (curTrace,
289 GT_4CLASS,
290 "RscTable_alloc",
291 RSCTABLE_E_FAIL,
292 "Unable to find resource table in file");
293 }
295 OsalKfile_close(&fileDesc);
297 // If successful, save coreId-handle pair for later access
298 if (obj) {
299 obj->procId = procId;
300 RscTable_state.handles[procId] = (RscTable_Handle)obj;
301 }
303 return (RscTable_Handle)obj;
304 }
306 // allocate any addr
307 Int Chunk_allocate (RscTable_Object *obj, UInt32 size, UInt32 * pa)
308 {
309 Int status = 0;
310 List_Elem * elem = NULL;
311 Void * da;
312 long long paddr;
313 UInt32 len;
315 if (!pa || !obj || !obj->chunks) {
316 status = RSCTABLE_E_INVALIDARG;
317 GT_setFailureReason (curTrace,
318 GT_4CLASS,
319 "Chunk_allocate",
320 status,
321 "Invalid arg passed");
322 GT_3trace(curTrace, GT_4CLASS, "obj [0x%x] obj->chunks [0x%x] pa [0x%x]", obj, obj ? obj->chunks : NULL, pa);
323 }
324 else {
325 // first try to allocate contiguous mem
326 da = mmap64(NULL, size,
327 PROT_NOCACHE | PROT_READ | PROT_WRITE,
328 #if ZEROINIT_CHUNKS
329 MAP_ANON | MAP_PHYS | MAP_SHARED,
330 #else
331 MAP_ANON | MAP_PHYS | MAP_SHARED | MAP_NOINIT,
332 #endif
333 NOFD,
334 0);
335 if (da == MAP_FAILED) {
336 // TODO: try to allocate non-contigous mem then get the pages
337 status = RSCTABLE_E_MEMORY;
338 GT_setFailureReason (curTrace,
339 GT_4CLASS,
340 "Chunk_allocate",
341 status,
342 "Unable to allocate chunk");
343 }
344 else {
345 /* Make sure the memory is contiguous */
346 status = mem_offset64(da, NOFD, size, &paddr, &len);
347 if (status || (len != size)) {
348 munmap(da, size);
349 status = RSCTABLE_E_MEMORY;
350 GT_setFailureReason (curTrace,
351 GT_4CLASS,
352 "Chunk_allocate",
353 status,
354 "mem_offset64 failed");
355 }
356 else {
357 *pa = (UInt32)paddr;
358 // save the memory so that it can be freed later
359 elem = Memory_alloc(NULL, sizeof(Carveout_Elem), 0, NULL);
360 if (elem == NULL) {
361 munmap(da, size);
362 status = RSCTABLE_E_MEMORY;
363 GT_setFailureReason (curTrace,
364 GT_4CLASS,
365 "Chunk_allocate",
366 status,
367 "Memory_alloc failed");
368 }
369 else {
370 ((Carveout_Elem *)elem)->addr = (UInt32)da;
371 ((Carveout_Elem *)elem)->size = size;
372 List_put(obj->chunks, elem);
373 }
374 }
375 }
376 }
377 return status;
378 }
380 Int
381 RscTable_process (UInt16 procId, Bool mmuEnabled, Bool tryAlloc,
382 UInt32 * numBlocks)
383 {
384 Int status = 0;
385 Int ret = 0;
386 RscTable_Object * obj = NULL;
387 RscTable_Header * table = NULL;
388 UInt i = 0, j = 0;
389 UInt dmem_num = 0;
390 #if !ZEROINIT_CHUNKS
391 UInt32 vringVA = 0, vringSize = 0;
392 #endif
394 // Find the table for this coreId, if not found, return an error
395 if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
396 status = RSCTABLE_E_INVALIDARG;
397 GT_setFailureReason (curTrace,
398 GT_4CLASS,
399 "RscTable_process",
400 status,
401 "Invalid procId specified");
402 return status;
403 }
405 obj = (RscTable_Object *)RscTable_state.handles[procId];
406 table = (RscTable_Header *)obj->rscTable;
408 obj->numMemEntries = 0;
410 // TODO: Check the version
411 printf("RscTable_process: RscTable version is [%d]\n", table->ver);
413 // Process the table for this core, allocating carveout memory if necessary
414 for (i = 0; i < table->num && !ret; i++) {
415 RscTable_MemEntry * entry =
416 (RscTable_MemEntry *)((UInt32)table + table->offset[i]);
417 switch (entry->type) {
418 case TYPE_CARVEOUT :
419 {
420 // TODO: need to allocate this mem from carveout
421 struct fw_rsc_carveout * cout = (struct fw_rsc_carveout *)entry;
422 UInt32 pa = 0;
423 if (cout->pa == 0) {
424 if (mmuEnabled) {
425 ret = Chunk_allocate (obj, cout->len, &pa);
426 }
427 else {
428 pa = cout->da;
429 }
430 }
431 if (!ret) {
432 cout->pa = pa;
433 if (obj->numMemEntries == SYSLINK_MAX_MEMENTRIES) {
434 ret = -1;
435 }
436 else {
437 obj->memEntries[obj->numMemEntries].slaveVirtAddr =
438 cout->da;
439 obj->memEntries[obj->numMemEntries].masterPhysAddr =
440 cout->pa;
441 obj->memEntries[obj->numMemEntries].size = cout->len;
442 //if (mmuEnabled) {
443 obj->memEntries[obj->numMemEntries].map = TRUE;
444 obj->memEntries[obj->numMemEntries].mapMask =
445 ProcMgr_SLAVEVIRT;
446 //}
447 //else
448 // obj->memEntries[obj->numMemEntries].map = FALSE;
449 obj->memEntries[obj->numMemEntries].isCached = FALSE;
450 obj->memEntries[obj->numMemEntries].isValid = TRUE;
451 obj->numMemEntries++;
452 }
453 }
454 printf ("RscTable_process: carveout [%s] @ da [0x%08x] pa [0x%08x] len [0x%x]\n", cout->name, cout->da, cout->pa, cout->len);
455 break;
456 }
457 case TYPE_DEVMEM :
458 {
459 // only care about mem in DDR for now
460 struct fw_rsc_devmem * dmem = (struct fw_rsc_devmem *)entry;
461 if (dmem->pa >= DDR_MEM) {
462 // HACK: treat vring mem specially, vring is always the
463 // first devmem entry, may change in future
464 if (dmem_num++ == 0) {
465 // memory should already be reserved for vring
466 if (obj->vringPa == 0) {
467 // vdev must have been defined first
468 GT_setFailureReason (curTrace,
469 GT_4CLASS,
470 "RscTable_process",
471 status,
472 "Vring Must be Defined First");
474 ret = -1;
475 }
476 else if (obj->vringPa != dmem->pa &&
477 (!tryAlloc || !mmuEnabled)) {
478 // defined pa does not match allocated pa, and
479 // either the mmu is disabled or the platform has
480 // not given permission to allocate on our own
481 ret = -1;
482 GT_setFailureReason (curTrace,
483 GT_4CLASS,
484 "RscTable_process",
485 status,
486 "Vring PA Mis-match");
488 GT_2trace (curTrace, GT_4CLASS,
489 "vringPa is 0x%x, dmem->pa is 0x%x",
490 obj->vringPa, dmem->pa);
491 }
492 else {
493 dmem->pa = obj->vringPa;
494 }
495 }
496 }
497 if (!ret) {
498 if (obj->numMemEntries == SYSLINK_MAX_MEMENTRIES) {
499 ret = -1;
500 }
501 else {
502 obj->memEntries[obj->numMemEntries].slaveVirtAddr =
503 dmem->da;
504 obj->memEntries[obj->numMemEntries].masterPhysAddr =
505 dmem->pa;
506 obj->memEntries[obj->numMemEntries].size = dmem->len;
507 //if (mmuEnabled) {
508 obj->memEntries[obj->numMemEntries].map = TRUE;
509 obj->memEntries[obj->numMemEntries].mapMask =
510 ProcMgr_SLAVEVIRT;
511 //}
512 //else
513 // obj->memEntries[obj->numMemEntries].map = FALSE;
514 obj->memEntries[obj->numMemEntries].isCached = FALSE;
515 obj->memEntries[obj->numMemEntries].isValid = TRUE;
516 obj->numMemEntries++;
517 }
518 }
520 // TODO: need to make sure this mem exists/is set aside, or allocate it
521 printf ("RscTable_process: devmem [%s] @ da [0x%08x] pa [0x%08x] len [0x%x]\n", dmem->name, dmem->da, dmem->pa, dmem->len);
522 break;
523 }
524 case TYPE_TRACE :
525 {
526 // TODO: save da for future use
527 struct fw_rsc_trace * trace = (struct fw_rsc_trace *)entry;
528 Memory_copy(&obj->trace, trace, sizeof(*trace));
529 printf ("RscTable_process: trace [%s] @ da [0x%08x] len [0x%x]\n", trace->name, trace->da, trace->len);
530 break;
531 }
532 case TYPE_VDEV :
533 {
534 // TODO: save vring info for future use
535 struct fw_rsc_vdev *vdev = (struct fw_rsc_vdev *)entry;
536 struct fw_rsc_vdev_vring * vring = NULL;
537 UInt32 vr_size = 0;
538 UInt32 vr_bufs_size = 0;
539 UInt32 pa = 0;
540 obj->numVrings = vdev->num_of_vrings;
541 obj->vrings = Memory_alloc(NULL,
542 sizeof (*vring) * obj->numVrings, 0,
543 NULL);
544 if (!obj->vrings)
545 ret = -1;
546 for (j = 0; j < vdev->num_of_vrings && !ret; j++) {
547 vring = (struct fw_rsc_vdev_vring *)
548 ((UInt32)vdev + sizeof(*vdev) +
549 (sizeof(*vring) * j));
550 Memory_copy (&obj->vrings[j], vring, sizeof (*vring));
551 printf ("RscTable_process: vring [%d] @ [0x%08x]\n",
552 vring->num, vring->da);
553 // Hack, we know this is the size alignment
554 if (vring->num != MessageQCopy_NUMBUFS ||
555 vring->align != MessageQCopy_VRINGALIGN) {
556 printf ("RscTable_process: warning size mis-match!\n");
557 ret = -1;
558 }
559 vr_size += ROUND_UP(MessageQCopy_RINGSIZE, 0x4000);
560 vr_bufs_size += (vring->num) * RPMSG_BUF_SIZE;
561 }
562 if (!ret) {
563 // HACK: round up to multiple of 1MB, because we know this
564 // is the size of the remote entry
565 if (mmuEnabled) {
566 ret = Chunk_allocate(obj,
567 ROUND_UP(vr_size + vr_bufs_size, 0x100000),
568 &pa);
569 }
570 else {
571 /*
572 * TBD: if mmu is disabled, we need a way to specify
573 * shared memory from which to allocate the vrings
574 */
575 }
576 }
577 else if (obj->vrings) {
578 Memory_free (NULL, obj->vrings,
579 sizeof(*vring) * obj->numVrings);
580 obj->vrings = NULL;
581 }
583 if (!ret) {
584 #if !ZEROINIT_CHUNKS
585 /* Map the phys mem to local */
586 vringSize = vr_size + vr_bufs_size;
587 vringVA = (UInt32)mmap_device_io(vringSize, pa);
588 if (vringVA != MAP_DEVICE_FAILED) {
589 /* Zero-init the vring */
590 Memory_set((Ptr)vringVA, 0, vringSize);
591 munmap_device_io(vringVA, vringSize);
592 }
593 else {
594 GT_0trace(curTrace, GT_4CLASS,
595 "RscTable_alloc: "
596 "Warning - Unable to zero-init vring mem");
597 }
598 #endif
600 obj->vringPa = pa;
601 obj->vringBufsPa = pa + vr_size;
602 }
603 break;
604 }
605 case TYPE_CRASHDUMP :
606 // what to do with this?
607 break;
608 default :
609 break;
610 }
611 }
613 if (ret) {
614 status = RSCTABLE_E_FAIL;
615 GT_setFailureReason (curTrace,
616 GT_4CLASS,
617 "RscTable_process",
618 status,
619 "Failure happened in processing table");
620 if (obj->vrings)
621 Memory_free(NULL, obj->vrings,
622 sizeof(*obj->vrings) * obj->numVrings);
623 obj->vrings = NULL;
624 obj->numMemEntries = 0;
625 }
626 *numBlocks = obj->numMemEntries;
628 return status;
629 }
631 Int
632 RscTable_getMemEntries (UInt16 procId, SysLink_MemEntry *memEntries,
633 UInt32 * numMemEntries)
634 {
635 Int status = 0;
636 RscTable_Object *obj = NULL;
638 // Find the table for this procId, if not found, return an error
639 if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
640 status = RSCTABLE_E_INVALIDARG;
641 GT_setFailureReason (curTrace,
642 GT_4CLASS,
643 "RscTable_getMemEntries",
644 status,
645 "Invalid ProcId specified");
646 return status;
647 }
649 obj = (RscTable_Object *)RscTable_state.handles[procId];
651 if (obj->memEntries && obj->numMemEntries &&
652 *numMemEntries >= obj->numMemEntries) {
653 *numMemEntries = obj->numMemEntries;
654 Memory_copy(memEntries, obj->memEntries,
655 sizeof(*memEntries) * obj->numMemEntries);
656 }
657 else {
658 status = RSCTABLE_E_INVALIDARG;
659 GT_setFailureReason (curTrace,
660 GT_4CLASS,
661 "RscTable_getMemEntries",
662 status,
663 "Invalid num of memEntries or memEntries is NULL");
664 }
666 return status;
667 }
669 Int
670 RscTable_getInfo (UInt16 procId, UInt32 type, UInt32 extra, UInt32 * da,
671 UInt32 *pa, UInt32 * len)
672 {
673 Int status = 0;
674 RscTable_Object *obj = NULL;
676 // Find the table for this procId, if not found, return an error
677 if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
678 status = RSCTABLE_E_INVALIDARG;
679 GT_setFailureReason (curTrace,
680 GT_4CLASS,
681 "RscTable_getInfo",
682 status,
683 "Invalid procId specified");
684 return status;
685 }
687 obj = (RscTable_Object *)RscTable_state.handles[procId];
689 if (type == TYPE_TRACE) {
690 if (da && len) {
691 *da = obj->trace.da;
692 *len = obj->trace.len;
693 }
694 else {
695 status = RSCTABLE_E_INVALIDARG;
696 GT_setFailureReason (curTrace,
697 GT_4CLASS,
698 "RscTable_getInfo",
699 status,
700 "Invalid pointer passed");
701 }
702 }
703 else if (type == TYPE_VDEV) {
704 if (extra == 0 && len) {
705 *len = obj->numVrings;
706 }
707 else if (extra < obj->numVrings && da) {
708 *da = obj->vrings[extra-1].da;
709 }
710 else {
711 status = RSCTABLE_E_INVALIDARG;
712 GT_setFailureReason (curTrace,
713 GT_4CLASS,
714 "RscTable_getInfo",
715 status,
716 "Invalid pointer passed");
717 }
718 }
719 else {
720 // type not supported
721 status = -1;
722 }
724 return status;
725 // Retrieve the info for a certain resource type (ex. Vring info)
726 }
728 Int
729 RscTable_update (UInt16 procId, ProcMgr_Handle procHandle)
730 {
731 // Updates the table to physical memory so that phys addrs are available to
732 // the remote cores. This should be called only after loading the remote
733 // cores.
734 Int status = 0;
735 RscTable_Object *obj = NULL;
736 UInt32 rscTableVA = 0, rscTablePA = 0;
738 // Find the table for this procId, if not found, return an error
739 if (procId >= MultiProc_MAXPROCESSORS || !RscTable_state.handles[procId]) {
740 status = RSCTABLE_E_INVALIDARG;
741 GT_setFailureReason (curTrace,
742 GT_4CLASS,
743 "RscTable_update",
744 status,
745 "Invalid ProcId specified");
746 return status;
747 }
749 obj = (RscTable_Object *)RscTable_state.handles[procId];
751 status = ProcMgr_translateAddr(procHandle, (Ptr *)&rscTablePA,
752 ProcMgr_AddrType_MasterPhys,
753 (Ptr)obj->rscTableDA,
754 ProcMgr_AddrType_SlaveVirt);
755 if (status < 0) {
756 status = RSCTABLE_E_FAIL;
757 GT_setFailureReason (curTrace,
758 GT_4CLASS,
759 "RscTable_update",
760 status,
761 "Unable to get the Master PA for RscTable");
762 }
763 else {
764 /* Map the phys mem to local */
765 rscTableVA = (UInt32)mmap_device_io(obj->rscTableLen, rscTablePA);
766 if (rscTableVA != MAP_DEVICE_FAILED) {
767 /* Copy the updated table to the memory */
768 Memory_copy((Ptr)rscTableVA, obj->rscTable, obj->rscTableLen);
769 munmap_device_io(rscTableVA, obj->rscTableLen);
770 }
771 else {
772 status = RSCTABLE_E_FAIL;
773 GT_setFailureReason (curTrace,
774 GT_4CLASS,
775 "RscTable_update",
776 status,
777 "Unable to map memory");
778 }
779 }
781 return status;
782 }
784 Int
785 RscTable_free (RscTable_Handle * handle)
786 {
787 Int status = 0;
788 RscTable_Object * obj = NULL;
789 Int i = 0;
790 List_Elem * elem;
792 // Remove resource table from coreId-Handle pair list
793 if (handle && *handle) {
794 // sanity check
795 for (i = 0; i < MultiProc_MAXPROCESSORS; i++) {
796 if (RscTable_state.handles[i] == *handle)
797 break;
798 }
799 if (i < MultiProc_MAXPROCESSORS) {
800 obj = (RscTable_Object *)(*handle);
801 // Additional sanity check
802 if (obj->procId == i) {
803 // Free vrings, memEntries, etc.
804 if (obj->chunks) {
805 while ((elem = List_get(obj->chunks))) {
806 Carveout_Elem * co_elem = (Carveout_Elem *)elem;
807 munmap((Void *)co_elem->addr, co_elem->size);
808 Memory_free(NULL, co_elem, sizeof(Carveout_Elem));
809 }
810 List_delete(&obj->chunks);
811 obj->chunks = NULL;
812 }
813 if (obj->vrings)
814 Memory_free(NULL, obj->vrings,
815 sizeof(*obj->vrings) * obj->numVrings);
816 obj->vrings = NULL;
817 obj->numMemEntries = 0;
819 if (obj->rscTable)
820 Memory_free(NULL, obj->rscTable, obj->rscTableLen);
821 obj->rscTableDA = 0;
822 Memory_free(NULL, obj, sizeof (RscTable_Object));
823 *handle = NULL;
824 RscTable_state.handles[i] = NULL;
825 }
826 }
827 else {
828 status = RSCTABLE_E_INVALIDARG;
829 GT_setFailureReason (curTrace,
830 GT_4CLASS,
831 "RscTable_free",
832 status,
833 "Invalid handle passed");
834 }
835 }
836 else {
837 status = RSCTABLE_E_INVALIDARG;
838 GT_setFailureReason (curTrace,
839 GT_4CLASS,
840 "RscTable_free",
841 status,
842 "Invalid handle passed");
843 }
845 return status;
846 }
848 Int RscTable_setStatus(UInt16 procId, UInt32 value)
849 {
850 Int i;
851 Int status = 0;
853 RscTable_Object * obj = (RscTable_Object *)RscTable_state.handles[procId];
854 RscTable_Header * table = (RscTable_Header *)obj->rscTable;
856 /* Look for the vdev entry and update the status */
857 for (i = 0; i < table->num; i++) {
858 RscTable_MemEntry * entry =
859 (RscTable_MemEntry *)((UInt32)table + table->offset[i]);
860 if (entry->type == TYPE_VDEV) {
861 struct fw_rsc_vdev *vdev = (struct fw_rsc_vdev *)entry;
862 vdev->status = value;
863 break;
864 }
865 }
867 if (i == table->num) {
868 status = RSCTABLE_E_FAIL;
869 }
871 return status;
872 }
874 #if defined (__cplusplus)
875 }
876 #endif /* defined (__cplusplus) */