/* * ======== modifyDefaultLinkCfgObjectBasedOnUserCfgData ======== */ static Void modifyDefaultLinkCfgObjectBasedOnUserCfgData( String serverName ) { LINKCFG_MemEntry * linkcfgMemTable; LINKCFG_MemEntry * e; static LINKCFG_MemEntry * linkcfgMemTables[] = { NULL /* to be set */ }; Global_ArmDspLinkConfig * armDspLinkConfig = NULL; Global_ArmDspLinkConfigMemTableEntry *mte; DSP_BootMode staticCfgDspCtl; DSP_BootMode newCfgDspCtl; Int serverNameIndex; UInt32 cmemPhysBase; size_t cmemSize; Int status; /* MODIFY MEMORY CONFIGURATION */ CMEM_BlockAttrs blockAttrs; Int numMemTableEntries, i = 0; Int numMemEntries = 0; Int memEntryIdx; Int numCmemBlocks = 0; Bool addCmemBlocks = FALSE; /* first locate our server in the list of server names */ for (serverNameIndex = 0;;serverNameIndex++) { if (!strcmp(ti_sdo_ce_ipc_armDspLinkConfigServerNames[serverNameIndex], serverName)) { break; } if (ti_sdo_ce_ipc_armDspLinkConfigServerNames[serverNameIndex] == NULL ) { GT_1trace(curTrace, GT_7CLASS, "Processor_create_d> " "ERROR: Cannot find DspLink configuration data for the server " "named '%s' -- verify that the name was specified correctly in " "the application configuration file.\n", serverName); return; } } GT_2trace(curTrace, GT_2CLASS, "Processor_create_d> " "Using DspLink config data for entry #%d [server '%s']\n", serverNameIndex, serverName ); armDspLinkConfig = ti_sdo_ce_ipc_armDspLinkConfigs[ serverNameIndex ]; ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->memTables = linkcfgMemTables; ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->memTables[0] = NULL; /* * Count the number of CMEM blocks, so we can add entries for these, * if needed. */ status = CMEM_getNumBlocks(&numCmemBlocks); if (status != 0) { /* TODO: Is this always an error? */ GT_0trace(curTrace, GT_6CLASS, "Processor_create_d> " "CMEM_getNumBlocks() failed!"); numCmemBlocks = 0; } else { GT_1trace(curTrace, GT_2CLASS, "Processor_create_d> Number of CMEM " "blocks: %d\n", numCmemBlocks); } for (;armDspLinkConfig->memTable[i].segmentName != NULL; i++); /* * Add a few extra entries in case we need to map CMEM blocks. The * app's config will have at most one CMEM entry with base and length * set to 0. We'll use CMEM_getBlockAttrs to get the base and length * of all CMEM blocks. (Note: We will allocate at least one more entry * then is actually needed, but this is easier than checking the * memTable for "CMEM", and subtracting '1' from the nuber to allocate * if "CMEM" is found.) */ numMemEntries = i; numMemTableEntries = numMemEntries + numCmemBlocks; /* anything allocated here must be deallocated in procDelete */ linkcfgMemTable = (LINKCFG_MemEntry *) Memory_alloc( sizeof(LINKCFG_MemEntry) * numMemTableEntries, NULL); if (linkcfgMemTable == NULL) { GT_0trace(curTrace, GT_7CLASS, "Processor_create_d> " "ERROR: Memory_alloc failed\n"); return; } /* point link config memTables only entry to our list of memTable entries */ ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->memTables[0] = linkcfgMemTable; for (i = 0, memEntryIdx = 0; i < numMemEntries; i++) { e = &linkcfgMemTable[memEntryIdx]; mte = &armDspLinkConfig->memTable[i]; GT_4trace(curTrace, GT_2CLASS, "Processor_create_d> Adding memTable " "entry for %s, physAddr = 0x%x, dspAddr = 0x%x, size = 0x%x\n", mte->segmentName, mte->gppAddress, mte->startAddress, mte->sizeInBytes); if (!strcmp("CMEM", mte->segmentName)) { /* Skip CMEM entry, we'll add CMEM blocks later */ addCmemBlocks = TRUE; continue; } e->entry = memEntryIdx; //i; strncpy( e->name, mte->segmentName, DSP_MAX_STRLEN ); e->physAddr = mte->gppAddress; // gpp physical address e->dspVirtAddr = mte->startAddress; // dsp view (physical or virtual) e->gppVirtAddr = (UInt32)-1; e->size = mte->sizeInBytes; e->shared = mte->shared; e->syncd = mte->syncd; memEntryIdx++; GT_6trace(curTrace, GT_2CLASS, "Processor_create_d> " "Adding DSP segment #%d to Link configuration: " "name='%s', startAddress=0x%x, sizeInBytes=0x%x, shared=%d, " "syncd=%d\n", i, e->name, e->physAddr, e->size, e->shared, e->syncd); } /* Now add the CMEM blocks if needed */ if (addCmemBlocks) { for (i = 0; i < numCmemBlocks; i++) { e = &linkcfgMemTable[memEntryIdx]; status = CMEM_getBlockAttrs(i, &blockAttrs); if (status != 0) { GT_1trace(curTrace, GT_7CLASS, "Processor_create_d> " "ERROR: failed to get CMEM attrs of block %d\n", i); break; } sprintf(e->name, "CMEM_BLOCK%d", i); e->physAddr = blockAttrs.phys_base; e->dspVirtAddr = blockAttrs.phys_base; e->size = blockAttrs.size; memEntryIdx++; } } /* set number of memTable entries */ ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].memEntries = memEntryIdx; //numMemTableEntries; /* RESET vector is always #3 in the list (that's how Global.xdt arranges it; * read its start address and size and adjust some other params in the * dsplink config object. (Note: third in the list is index [2]. */ ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].resumeAddr = armDspLinkConfig->memTable[2].startAddress + 0x20; ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].resetVector = armDspLinkConfig->memTable[2].startAddress; ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].resetCodeSize = armDspLinkConfig->memTable[2].sizeInBytes; /* SET DOPOWERCONTROL PER CE CONFIGURATION */ staticCfgDspCtl = ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].doDspCtrl; if (armDspLinkConfig->doDspCtrl == BootNoPwr) { newCfgDspCtl = DSP_BootMode_Boot_NoPwr; } else if (armDspLinkConfig->doDspCtrl == BootPwr) { newCfgDspCtl = DSP_BootMode_Boot_Pwr; } else if (armDspLinkConfig->doDspCtrl == NoLoadNoPwr) { newCfgDspCtl = DSP_BootMode_NoLoad_NoPwr; } else if (armDspLinkConfig->doDspCtrl == NoLoadPwr) { newCfgDspCtl = DSP_BootMode_NoLoad_Pwr; } else { /* NoBoot */ newCfgDspCtl = DSP_BootMode_NoBoot; } ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].doDspCtrl = newCfgDspCtl; GT_2trace(curTrace, GT_2CLASS, "Processor_create_d> " "DODSPCTRL was=%d; now=%d\n", staticCfgDspCtl, newCfgDspCtl); }
/* * ======== procCreate ======== */ static Bool procCreate(Processor_Handle proc) { Int status = 0; Bool retVal; ProcMgr_AttachParams attachParams; ProcMgr_StartParams startParams; ProcMgr_State state; ProcMgr_AddrInfo CMEMAddrInfo; HeapBufMP_Params heapP; CMEM_BlockAttrs cmemBlockAttrs; Int blockNum; Int nCMEMBlocks; Bool createAndRegisterHeap; Int16 heapId; UInt16 regionId; UInt32 numMsgs; UInt32 msgSize; Char heapName[32]; Log_print1(Diags_ENTRY, "[+E] Processor_create_d> Enter(proc=0x%x)", (IArg)proc); /* Create and initialize the PROC object */ Log_print1(Diags_USER2, "[+2] Processor_create_d> " "Retrieving CPU ID for '%s'...", (IArg)(proc->attrs.cpuId)); proc->cpuId = Processor_getCoreId(proc->attrs.cpuId); if (proc->cpuId < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "Processor_getCoreId() failed: %d", proc->cpuId); goto fail; } /* Open DSP ProcMgr */ Log_print2(Diags_USER2, "[+2] Processor_create_d> " "Opening %s ProcMgr for cpuId %d...", (IArg)proc->attrs.cpuId, proc->cpuId); status = ProcMgr_open(&proc->procMgrH, proc->cpuId); if (status < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "ProcMgr_open() failed: %d", (IArg)status); goto fail; } /* Attach the DSP */ Log_print1(Diags_USER2, "[+2] Processor_create_d> " "Attaching to %s...", (IArg)proc->attrs.cpuId); if (proc->useExtLoader == FALSE) { /* We load the slave */ ProcMgr_getAttachParams(NULL, &attachParams); status = ProcMgr_attach(proc->procMgrH, &attachParams); if (status < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "ProcMgr_attach() failed: %d", (IArg)status); goto fail; } /* Map slave memory */ if (!mapByFile(proc->procMgrH, proc->memMapName, proc->cpuId, TRUE)) { Log_print0(Diags_USER6, "Processor_create_d> mapByFile() failed!"); } /* Load the executable on the DSP */ Log_print3(Diags_USER2, "[+2] Processor_create_d> " "Loading %s on %s (%d args)...", (IArg)(proc->imageName), (IArg)(proc->attrs.cpuId), (IArg)(proc->attrs.argc)); status = ProcMgr_load(proc->procMgrH, proc->imageName, proc->attrs.argc, proc->attrs.argv, NULL, &proc->fileId); if (status < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "ProcMgr_load() failed: %d", status); goto fail; } /* temporary: to be done by SysLink in the future */ Log_print0(Diags_USER1, "[+2] Processor_create_d> " "calling Ipc_control(LOADCALLBACK)..."); status = Ipc_control(proc->cpuId, Ipc_CONTROLCMD_LOADCALLBACK, NULL); Log_print1(Diags_USER1, "[+2] Processor_create_d> " "Ipc_control(LOADCALLBACK) status: %d", (IArg)status); /* Start execution on DSP */ Log_print1(Diags_USER2, "[+2] Processor_create_d> Starting %s ...", (IArg)proc->attrs.cpuId); ProcMgr_getStartParams(proc->procMgrH, &startParams); status = ProcMgr_start(proc->procMgrH, &startParams); if (status < 0) { Log_print1(Diags_USER7, "Processor_create_d> " "ProcMgr_start() failed: %d", status); goto fail; } } // if (proc->useExtLoader == FALSE) else { /* Check the state of the processor to make sure it's really running */ state = ProcMgr_getState(proc->procMgrH); if (state != ProcMgr_State_Running) { Log_print1(Diags_USER7, "Processor_create_d> Invalid processor " "state [%d].", state); goto fail; } Log_print0(Diags_USER1, "[+2] Processor_create_d> " "calling Ipc_control(LOADCALLBACK)..."); status = Ipc_control(proc->cpuId, Ipc_CONTROLCMD_LOADCALLBACK, NULL); proc->loadCallBackStatus = status; Log_print1(Diags_USER1, "[+2] Processor_create_d> " "Ipc_control(LOADCALLBACK) status: %d", (IArg)status); if (status < 0) { Log_print1(Diags_USER7, "Processor_create_d> " "Ipc_control(LOADCALLBACK) failed: %d", status); goto fail; } } status = Ipc_control(proc->cpuId, Ipc_CONTROLCMD_STARTCALLBACK, NULL); proc->startCallBackStatus = status; Log_print1(Diags_USER1, "[+2] Processor_create_d> " "Ipc_control(STARTCALLBACK) status: %d", (IArg)status); if (status < 0) { Log_print1(Diags_USER7, "Processor_create_d> " "Ipc_control(STARTCALLBACK) failed: %d", status); goto fail; } /* get user-specified heapId */ heapId = perCoreHeapId(proc->cpuId); createAndRegisterHeap = FALSE; if (heapId == Processor_INVALID) { /* runtime validation of user configuration */ if (perCoreUserCreatedHeapFlag(proc->cpuId) == TRUE || perCoreNumMsgs(proc->cpuId) != Processor_INVALID || perCoreMsgSize(proc->cpuId) != Processor_INVALID || perCoreSharedRegionId(proc->cpuId) != Processor_INVALID) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "Invalid heap configuration for core %d: " "attempting to set other Processor_CommDesc " "elements while Processor_CommDesc.heapId is " "undefined", proc->cpuId); goto fail; } /* will return default heapId since user didn't specify */ heapId = Processor_getHeapId(proc->cpuId); if (defaultHeapRefCount++ == 0) { createAndRegisterHeap = TRUE; /* tell code below to record heapH in defaultHeapH */ defaultHeapH = (HeapBufMP_Handle)-1; } } else { if (perCoreUserCreatedHeapFlag(proc->cpuId) == FALSE) { createAndRegisterHeap = TRUE; } } if (createAndRegisterHeap) { /* create a heap for message queue usage */ /* get either user-config'ed or module default */ numMsgs = Processor_getNumMsgs(proc->cpuId); msgSize = Processor_getMsgSize(proc->cpuId); regionId = Processor_getSharedRegionId(proc->cpuId); HeapBufMP_Params_init(&heapP); heapP.numBlocks = numMsgs; heapP.blockSize = msgSize; heapP.sharedAddr = NULL; heapP.regionId = regionId; if (defaultHeapH == (HeapBufMP_Handle)-1) { sprintf(heapName, "CE-default"); } else { sprintf(heapName, "CE<->Svr%d", proc->cpuId); } heapP.name = heapName; Log_print2(Diags_USER1, "[+2] Processor_create_d> " "calling HeapBufMP_create(): nblocks %d, blocksize 0x%x", heapP.numBlocks, heapP.blockSize); proc->heapH = HeapBufMP_create(&heapP); if (proc->heapH == NULL) { Log_print0(Diags_USER7, "[+7] Processor_create_d> " "HeapBufMP_create failed"); goto fail; } if (defaultHeapH == (HeapBufMP_Handle)-1) { /* we've just created the module default heap singleton */ defaultHeapH = proc->heapH; } /* register this heap with MessageQ */ Log_print2(Diags_USER1, "[+2] Processor_create_d> " "MessageQ_registerHeap(heapH: 0x%x, heapId: %d)", (IArg)(proc->heapH), (IArg)heapId); if (MessageQ_registerHeap((Ptr)(proc->heapH), heapId) != MessageQ_S_SUCCESS) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "MessageQ_registerHeap() failed for heapId %d", heapId); goto fail; } } else { /* * createAndRegisterHeap == FASLE * If using the default heap, need to set proc->heapH for use by * procDelete(). */ if (heapId == Processor_defaultHeapId) { proc->heapH = defaultHeapH; } } proc->heapId = heapId; blockNum = 0; nCMEMBlocks = 0; status = CMEM_getNumBlocks(&nCMEMBlocks); if (status != 0) { Log_print1(Diags_USER2, "[+2] Processor_create_d> " "CMEM_getNumBlocks() failed, not registering: %d", status); } while (blockNum < nCMEMBlocks) { status = CMEM_getBlockAttrs(blockNum, &cmemBlockAttrs); if (status != 0) { Log_print2(Diags_USER7, "[+7] Processor_create_d> " "CMEM_getBlockAttrs(%d) failed: %d", blockNum, status); goto fail; } CMEMAddrInfo.addr[ProcMgr_AddrType_MasterPhys] = cmemBlockAttrs.phys_base; CMEMAddrInfo.addr[ProcMgr_AddrType_SlaveVirt] = cmemBlockAttrs.phys_base; CMEMAddrInfo.size = cmemBlockAttrs.size; CMEMAddrInfo.isCached = FALSE; Log_print3(Diags_USER1, "[+1] Processor_create_d> CMEM block " "#%d found, doing ProcMgr_map(0x%x, 0x%x)...", blockNum, (IArg)cmemBlockAttrs.phys_base, (IArg)cmemBlockAttrs.size); status = ProcMgr_map(proc->procMgrH, ProcMgr_SLAVEVIRT, &CMEMAddrInfo, ProcMgr_AddrType_MasterPhys); if (status < 0) { Log_print1(Diags_USER7, "[+7] Processor_create_d> " "ProcMgr_map() failed: %d", status); goto fail; } if (CMEMAddrInfo.addr[ProcMgr_AddrType_SlaveVirt] != cmemBlockAttrs.phys_base) { Log_print2(Diags_USER1, "[+2] Processor_create_d> " "mapped CMEM slave virtual address 0x%x doesn't " "match expected value 0x%x", CMEMAddrInfo.addr[ProcMgr_AddrType_SlaveVirt], cmemBlockAttrs.phys_base); } blockNum++; } if (Global_getenv("CE_DSPDEBUG") != NULL) { printf("Codec Engine system message (b/c CE_DSPDEBUG=1) : %s image " "loaded and started, press Enter to continue: ", proc->attrs.cpuId); getchar(); } retVal = TRUE; goto procCreate_return; /* TODO:[4] should try those asyncErrorHandlers that link supports? * (MSGQ_SetErrorHandler) */ fail: Log_print3(Diags_USER7, "[+7] Processor_create_d> " "Loading and starting %s server '%s' FAILED, status=[0x%x]", (IArg)proc->attrs.cpuId, (IArg)proc->imageName, status); procDelete(proc); retVal = FALSE; procCreate_return: Log_print1(Diags_USER2, "[+2] Processor_create_d> return (%d)", (IArg)retVal); return (retVal); }
/* * ======== procDelete ======== */ static Void procDelete(Processor_Handle proc) { Int status = 0; Int16 heapId; Bool unregisterAndDeleteHeap; ProcMgr_AddrInfo CMEMAddrInfo; CMEM_BlockAttrs cmemBlockAttrs; Int blockNum; Int nCMEMBlocks; Log_print1(Diags_ENTRY, "[+E] Processor_delete_d> Enter (proc=0x%x)", (IArg)proc); if (proc == NULL) { goto procDelete_return; } /* close tranport and stop DSP, detach, destroy */ /* unregister this heap with MessageQ */ if (proc->startCallBackStatus >= 0) { blockNum = 0; nCMEMBlocks = 0; status = CMEM_getNumBlocks(&nCMEMBlocks); if (status != 0) { Log_print1(Diags_USER2, "[+2] Processor_delete_d> " "CMEM_getNumBlocks() failed: %d", status); } while (blockNum < nCMEMBlocks) { status = CMEM_getBlockAttrs(blockNum, &cmemBlockAttrs); if (status != 0) { Log_print2(Diags_USER7, "[+7] Processor_delete_d> " "CMEM_getBlockAttrs(%d) failed: %d", blockNum, status); goto cmemDone; } CMEMAddrInfo.addr[ProcMgr_AddrType_MasterPhys] = cmemBlockAttrs.phys_base; CMEMAddrInfo.addr[ProcMgr_AddrType_SlaveVirt] = cmemBlockAttrs.phys_base; CMEMAddrInfo.size = cmemBlockAttrs.size; CMEMAddrInfo.isCached = FALSE; Log_print3(Diags_USER1, "[+1] Processor_delete_d> CMEM block " "#%d found, doing ProcMgr_unmap(0x%x, 0x%x)...", blockNum, (IArg)cmemBlockAttrs.phys_base, (IArg)cmemBlockAttrs.size); status = ProcMgr_unmap(proc->procMgrH, ProcMgr_SLAVEVIRT, &CMEMAddrInfo, ProcMgr_AddrType_MasterPhys); if (status < 0) { Log_print1(Diags_USER7, "[+7] Processor_delete_d> " "ProcMgr_unmap() failed: %d", status); goto cmemDone; } blockNum++; } cmemDone: Log_print2(Diags_USER7, "[+2] Processor_delete_d> " "defaultHeapH: 0x%x, proc->heapH: 0x%x", (IArg)defaultHeapH, (IArg)proc->heapH); if (proc->heapH != NULL) { unregisterAndDeleteHeap = FALSE; if (proc->heapH == defaultHeapH) { Log_print1(Diags_USER1, "[+1] Processor_delete_d> " "defaultHeapRefCount = %d", (IArg)defaultHeapRefCount); if (--defaultHeapRefCount == 0) { /* this is the last one using the default heap */ unregisterAndDeleteHeap = TRUE; } } else { unregisterAndDeleteHeap = TRUE; } if (unregisterAndDeleteHeap) { heapId = proc->heapId; Log_print1(Diags_USER1, "[+1] Processor_delete_d> " "unregisterAndDeleteHeap, heapId = %d", (IArg)heapId); if (heapId != Processor_INVALID) { Log_print1(Diags_USER1, "[+1] Processor_delete_d> " "MessageQ_unregisterHeap(heapId: %d)", (IArg)heapId); if (MessageQ_unregisterHeap(heapId) !=MessageQ_S_SUCCESS) { Log_print1(Diags_USER7, "[+7] Processor_delete_d> " "MessageQ_unregisterHeap(heapId: %d) failed", heapId); } } /* delete heap used by message queue */ Log_print1(Diags_USER1, "[+1] Processor_delete_d> " "calling HeapBufMP_delete(heapH: 0x%x)", (IArg)(proc->heapH)); HeapBufMP_delete(&proc->heapH); } } /* Stop execution on DSP */ Log_print0(Diags_USER1, "[+2] Processor_delete_d> " "calling Ipc_control(STOPCALLBACK)..."); status = Ipc_control(proc->cpuId, Ipc_CONTROLCMD_STOPCALLBACK, NULL); Log_print2(Diags_USER2, "[+2] Processor_delete_d> " "Ipc_control(STOPCALLBACK) status: 0x%x [%d]", (IArg)status, (IArg)status); } else { Log_print2(Diags_USER2, "[+2] Processor_delete_d> Not calling " "Ipc_control(STOPCALLBACK) because startCallBackStatus = " "0x%x [%d]", (IArg)proc->startCallBackStatus, (IArg)proc->startCallBackStatus); } if (proc->useExtLoader == FALSE) { /* We unload the slave processor */ Log_print0(Diags_USER2, "[+2] Processor_delete_d> Stopping DSP..."); status = ProcMgr_stop(proc->procMgrH); if (status < 0) { Log_print1(Diags_USER6, "[+6] Processor_delete_d> " "Stopping DSP FAILED, status=0x%x", (IArg)status); } if (proc->fileId != 0xffffffff) { Log_print0(Diags_USER2, "[+2] Processor_delete_d> " "Unloading DSP..."); status = ProcMgr_unload(proc->procMgrH, proc->fileId); if (status < 0) { Log_print1(Diags_USER6, "[+6] Processor_delete_d> " "Unloading DSP FAILED, status=0x%x", (IArg)status); } } /* Unmap slave memory */ if (!mapByFile(proc->procMgrH, proc->memMapName, proc->cpuId, FALSE)) { Log_print0(Diags_USER6, "Processor_delete_d> mapByFile() failed!"); } /* Detach from the processor */ Log_print0(Diags_USER1, "[+1] Processor_delete_d> " "calling ProcMgr_detach()..."); status = ProcMgr_detach(proc->procMgrH); if (status < 0) { Log_print1(Diags_USER6, "[+6] Processor_delete_d> " "Detaching from DSP FAILED, status=0x%x", (IArg)status); } } // proc->useExtLoader == FALSE Log_print0(Diags_USER1, "[+1] Processor_delete_d> " "calling ProcMgr_close()..."); status = ProcMgr_close(&proc->procMgrH); if (status < 0) { Log_print1(Diags_USER6, "[+6] Processor_delete_d> " "Closing ProcMgr FAILED, status=0x%x", (IArg)status); } procDelete_return: Log_print0(Diags_EXIT, "[+X] Processor_delete_d> return"); }
int main(int argc, char *argv[]) { size_t size; int version; CMEM_BlockAttrs attrs; int i; int c; non_interactive_flag = FALSE; while ((c = getopt(argc, argv, "n")) != -1) { switch (c) { case 'n': non_interactive_flag = TRUE; break; default: fprintf(stderr, "Usage: %s [-n] <Number of bytes to allocate>\n", argv[0]); fprintf(stderr, " -n: non-interactive mode (no ENTER prompts)\n"); exit(EXIT_FAILURE); } } if ((argc - optind + 1) != 2) { fprintf(stderr, "Usage: %s [-n] <Number of bytes to allocate>\n", argv[0]); fprintf(stderr, " -n: non-interactive mode (no ENTER prompts)\n"); exit(EXIT_FAILURE); } errno = 0; size = strtol(argv[optind], NULL, 0); if (errno) { fprintf(stderr, "Bad argument ('%s'), strtol() set errno %d\n", argv[optind], errno); exit(EXIT_FAILURE); } /* First initialize the CMEM module */ if (CMEM_init() == -1) { fprintf(stderr, "Failed to initialize CMEM\n"); exit(EXIT_FAILURE); } printf("CMEM initialized.\n"); version = CMEM_getVersion(); if (version == -1) { fprintf(stderr, "Failed to retrieve CMEM version\n"); exit(EXIT_FAILURE); } printf("CMEM version = 0x%x\n", version); testMap(size); testAllocPhys(size); testCMA(size); if (CMEM_getNumBlocks(&nblocks)) { fprintf(stderr, "Failed to retrieve number of blocks\n"); exit(EXIT_FAILURE); } printf("\n# of CMEM blocks (doesn't include possible CMA global 'block'): %d\n", nblocks); if (nblocks) { for (i = 0; i < nblocks; i++) { if (CMEM_getBlockAttrs(i, &attrs) == -1) { fprintf(stderr, "Failed to retrieve CMEM memory block %d bounds\n", i); } else { printf("CMEM memory block %d: phys start = %#llx, size = %#llx\n", i, (unsigned long long)attrs.phys_base, attrs.size); } testHeap(size, i); testHeap(size, i); testPools(size, i); testPools(size, i); testCache(size, i); } } else { printf(" no physical block found, not performing block-based testing\n"); } /* block 'nblocks' is the special CMEM CMA "block" */ testPools(size, CMEM_CMABLOCKID); printf("\nexiting...\n"); if (CMEM_exit() < 0) { fprintf(stderr, "Failed to finalize the CMEM module\n"); } printf("...test done\n"); exit(EXIT_SUCCESS); }