Int32 Utils_memInit() { SharedRegion_Entry srEntry; Int srStatus = SharedRegion_S_SUCCESS; UInt32 srId[UTILS_MEM_NUM_SHARED_REGION_HEAP], i; srId[UTILS_MEM_VID_FRAME_BUF_HEAP] = SYSTEM_IPC_SR_VIDEO_FRAME; srId[UTILS_MEM_VID_BITS_BUF_HEAP] = SYSTEM_IPC_SR_CACHED; for (i=0; i<UTILS_MEM_NUM_SHARED_REGION_HEAP; i++) { SharedRegion_entryInit(&srEntry); SharedRegion_getEntry(srId[i], &srEntry); Vps_printf (" %d: MEM: Shared Region %d: Base = 0x%08x, Length = 0x%08x (%d MB) \n", Utils_getCurTimeInMsec(), srId[i],srEntry.base,srEntry.len, srEntry.len/(1024*1024)); if ((FALSE == srEntry.isValid) && (0 != srEntry.len)) { srEntry.isValid = TRUE; do { srStatus = SharedRegion_setEntry(srId[i], &srEntry); if (srStatus != SharedRegion_S_SUCCESS) { Vps_printf(" %d: MEM: ERROR: SharedRegion_setEntry (%d, 0x%08x) FAILED !!! " " (status=%d) \n", Utils_getCurTimeInMsec(), srId[i], &srEntry, srStatus); Task_sleep(10); } } while (srStatus != SharedRegion_S_SUCCESS); } if (srEntry.len) { gUtils_heapMemHandle[i] = SharedRegion_getHeap(srId[i]); UTILS_assert(gUtils_heapMemHandle[i] != NULL); gUtils_memClearBuf[i] = FALSE; } } return 0; }
/** * Handler for shared region set entry API. * * \param ctp Thread's associated context information. * \param msg The actual devctl() message. * \param ocb OCB associated with client's session. * * \return POSIX errno value. * * \retval EOK Success. * \retval ENOTSUP Unsupported devctl(). */ int syslink_sharedregion_setentry(resmgr_context_t *ctp, io_devctl_t *msg, syslink_ocb_t *ocb) { SharedRegionDrv_CmdArgs * cargs = (SharedRegionDrv_CmdArgs *) (_DEVCTL_DATA (msg->i)); SharedRegionDrv_CmdArgs * out = (SharedRegionDrv_CmdArgs *) (_DEVCTL_DATA (msg->o)); SharedRegion_Entry *entry = (SharedRegion_Entry*)(cargs+1); entry->base = Memory_translate ((Ptr)cargs->args.setEntry.entry.base, Memory_XltFlags_Phys2Virt); GT_assert (curTrace, (entry->base != (UInt32)NULL)); out->apiStatus = SharedRegion_setEntry (cargs->args.setEntry.id, entry); GT_assert (curTrace, (out->apiStatus >= 0)); if (out->apiStatus >= 0) { /* Add this call to the list to be cleaned-up */ add_ocb_res(ocb, DCMD_SHAREDREGION_CLEARENTRY, (int)cargs->args.setEntry.id, NULL); } return (_RESMGR_PTR (ctp, &msg->o, sizeof (msg->o) + sizeof(SharedRegionDrv_CmdArgs))); }
/** ******************************************************************************** * @func memcfg_module_init_shared_region * @brief This function performs initialization of shared regions. * * This functions gets a virtual address by calling * DomxCore_mapPhyAddr2UsrVirtual(). Checks if the address already * available the table. If not it creates an entry and sets the entry * by calling SharedRegion_setEntry. * * @param[in ] None : None * * @returns MEMCFG_E_FAIL * MEMCFG_S_SUCCESS ******************************************************************************** */ static int32_t memcfg_module_init_shared_region (void) { int32_t i, j; int32_t nSR_retval; SharedRegion_Entry srEntry; uint16_t srOwnerProcId; uint16_t srIndex; int32_t createHeap; int32_t srStatus = SharedRegion_S_SUCCESS; void *srBaseVirtual = NULL; int32_t memcfg_retval = MEMCFG_S_SUCCESS; int32_t aSRIndices[MEMCFG_MAXNUMSHAREDREGIONS]; int16_t sridx_local = 0; int16_t k; /*--------------------------------------------------------------------------*/ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Following are the initialization steps for each of the shared regions: */ /* 1. Convert the base address into user space virtual */ /* 2. Derived to Base params with Actual values */ /* 3. Get entry for a specific shared region index */ /* 4. If the shared region is not valid, then set the shared region */ /* 5. If the shared region is already there, then check if the values are */ /* correct. */ /* */ /*--------------------------------------------------------------------------*/ /* This needs to be fixed. SR1 is in cacheable region for M3, but the heap is created by the master A8 which updates the Heap attributes in SR1, thus writing to it. If MEMCFGModule_init on M3 runs before A8, then the memory corresponding to the Heap attrs gets cached by M3 and thus SharedRegion_setEntry keeps on failing despite A8 successfully creating the heap. IPC probably needs to communicate heap attrs via SR0? The fix below ensures SR1 is created by A8 before M3 checks for it, as M3 waits for SR2 creation before SR1 and SR2 is in non-cacheable region. In short, on A8, SRs which does not require cache operations are created first and then those which does needs cache operations. On M3, reverse happens. */ if (DomxTypes_coreCortexA8 == MultiProc_self ()) { /* Master/SR Owner */ /* On master, create the order such that all the SRs that does not need cache operations go first... */ for (k = 0; k < MEMCFG_sharedRegionConfigTable.nNumSharedRegions; k++) { if (!MEMCFG_sharedRegionConfigTable.aSRInfo[k].bCacheEnable) { /* if the SR does NOT need cache operation, put that in */ aSRIndices[sridx_local++] = MEMCFG_sharedRegionConfigTable.aSRInfo[k].uIndex; } /* if */ } /* for */ /* ... and then all SRs that need cache operation go next */ for (k = 0; k < MEMCFG_sharedRegionConfigTable.nNumSharedRegions; k++) { if (MEMCFG_sharedRegionConfigTable.aSRInfo[k].bCacheEnable) { /* if the SR needs cache operation, put that in */ aSRIndices[sridx_local++] = MEMCFG_sharedRegionConfigTable.aSRInfo[k].uIndex; } /* if */ } /* for */ } /* if (DomxTypes_coreCortexA8...) */ else { /* Slaves */ /* On slaves, create the order such that all the SRs that needs cache operations go first... */ for (k = 0; k < MEMCFG_sharedRegionConfigTable.nNumSharedRegions; k++) { if (MEMCFG_sharedRegionConfigTable.aSRInfo[k].bCacheEnable) { /* if the SR is NOT cached, put that in */ aSRIndices[sridx_local++] = MEMCFG_sharedRegionConfigTable.aSRInfo[k].uIndex; } /* if */ } /* for */ /* ... and then all SRs does not need cache operation go next */ for (k = 0; k < MEMCFG_sharedRegionConfigTable.nNumSharedRegions; k++) { if (!MEMCFG_sharedRegionConfigTable.aSRInfo[k].bCacheEnable) { /* if the SR is cached, put that in */ aSRIndices[sridx_local++] = MEMCFG_sharedRegionConfigTable.aSRInfo[k].uIndex; } /* if */ } /* for */ } /* if (DomxTypes_coreCortexA8) else ... */ for (j = 0; j < MEMCFG_sharedRegionConfigTable.nNumSharedRegions; j++) { i = aSRIndices[j]; srBaseVirtual = NULL; /*------------------------------------------------------------------------*/ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Convert the physical address to virtual address. */ /* */ /*------------------------------------------------------------------------*/ srBaseVirtual = DomxCore_mapPhyAddr2UsrVirtual (MEMCFG_sharedRegionConfigTable.aSRInfo[i]. uBase, MEMCFG_sharedRegionConfigTable.aSRInfo[i]. uSize); /*------------------------------------------------------------------------*/ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* Get the entry for the specific shared region index. */ /* */ /*------------------------------------------------------------------------*/ nSR_retval = SharedRegion_getEntry (MEMCFG_sharedRegionConfigTable.aSRInfo[i].uIndex, &srEntry); if (nSR_retval == SharedRegion_S_SUCCESS) { if (FALSE == srEntry.isValid) { /*--------------------------------------------------------------------*/ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* If the shared region is not included, then set a new entry. */ /* */ /*--------------------------------------------------------------------*/ SharedRegion_entryInit (&srEntry); MEMCFG_module->bSrAddEntryDone[i] = TRUE; if (MEMCFG_sharedRegionTypeMaster == MEMCFG_sharedRegionConfigTable.aSRInfo[i].srType) { srOwnerProcId = MultiProc_self (); createHeap = TRUE; } else { srOwnerProcId = SharedRegion_DEFAULTOWNERID; createHeap = TRUE; } srEntry.base = srBaseVirtual; srIndex = MEMCFG_sharedRegionConfigTable.aSRInfo[i].uIndex; srEntry.len = MEMCFG_sharedRegionConfigTable.aSRInfo[i].uSize; srEntry.cacheEnable = MEMCFG_sharedRegionConfigTable.aSRInfo[i].bCacheEnable; srEntry.createHeap = createHeap; srEntry.isValid = TRUE; srEntry.ownerProcId = srOwnerProcId; Log_print2 (Diags_USER1, "Calling SharedRegion_setEntry (%d, 0x%x)", srIndex, (xdc_IArg) & srEntry); Log_print3 (Diags_USER1, "base : 0x%x, len: 0x%x, ownerProcId: %d\n", (xdc_IArg) srEntry.base, srEntry.len, srEntry.ownerProcId); do { /*------------------------------------------------------------------*/ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* If the shared region is not included, then set a new entry. */ /* */ /*------------------------------------------------------------------*/ srStatus = SharedRegion_setEntry (srIndex, &srEntry); if (srStatus != SharedRegion_S_SUCCESS) { /*----------------------------------------------------------------*/ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* If the shared region is not successful, retry for */ /* MEMCFG_MAX_NUM_TRIALS */ /* */ /*----------------------------------------------------------------*/ Log_print3 (Diags_USER1, "SharedRegion_setEntry (%d, 0x%x) Failed, Status %d", srIndex, (xdc_IArg) & srEntry, srStatus); } } while (srStatus != SharedRegion_S_SUCCESS); } /* if (FALSE == srEntry..isValid) { */ else { /*--------------------------------------------------------------------*/ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* There is already an entry. Check it has valid information. */ /* */ /*--------------------------------------------------------------------*/ Assert_isTrue (((srEntry.base == srBaseVirtual) && (srEntry.len == MEMCFG_sharedRegionConfigTable.aSRInfo[i].uSize)), Assert_E_assertFailed); MEMCFG_module->bSrAddEntryDone[i] = FALSE; } } /* End of IF block: if (nSR_retval == SharedRegion_S_SUCCESS) */ else { /* if (nSR_retval != SharedRegion_S_SUCCESS) */ memcfg_retval = MEMCFG_E_FAIL; goto EXIT; } } /* End of FOR block: for (i = 0; i < MEMCFG_sharedRegionConfigTable.nNumSharedRegions; i++) */ EXIT: return memcfg_retval; } /* memcfg_module_init_shared_region */