summaryrefslogtreecommitdiffstats
path: root/main/common/monprof.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/common/monprof.c')
-rw-r--r--main/common/monprof.c968
1 files changed, 480 insertions, 488 deletions
diff --git a/main/common/monprof.c b/main/common/monprof.c
index ebf673b..ddc3d5a 100644
--- a/main/common/monprof.c
+++ b/main/common/monprof.c
@@ -1,7 +1,7 @@
/**************************************************************************
*
* Copyright (c) 2013 Alcatel-Lucent
- *
+ *
* Alcatel Lucent licenses this file to You under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. A copy of the License is contained the
@@ -34,7 +34,7 @@
* interaction with the user at the monitor command line. The runtime
* profiling calls are done in application space, but the initial setup of
* the profiling session is done at the CLI.
- *
+ *
* There are a few different profiling mechanisms in place...
*
* FUNCTION LOGGING:
@@ -52,17 +52,17 @@
* monprof structure. Upon entry into the profiler, the 'pc' member of
* the incoming structure is assumed to contain the address that was
* executing at the time of the interrupt. The profiler uses a simple
- * binary search to scan through all entries in the table to find the
+ * binary search to scan through all entries in the table to find the
* symbol (function) that the address falls within. When this is found,
* that entry's pass count variable is incremented. At some point later,
- * profiling is completed and the user can dump the results to show the
+ * profiling is completed and the user can dump the results to show the
* user what functions were hogging the CPU during the profiling session.
*
* Example setup:
- * prof init # Initialize internals.
- * prof funccfg # Configure function logging using symtbl.
- * prof on # Enable profiling.
- *
+ * prof init # Initialize internals.
+ * prof funccfg # Configure function logging using symtbl.
+ * prof on # Enable profiling.
+ *
*
* PC LOGGING:
* This capability assumes that every instruction is the same size (typical
@@ -76,12 +76,12 @@
* be an option.
*
* Example setup:
- * prof init # Initialize internals.
- * prof pccfg 4 0x22000 0x10000 # Configure pc logging for 32-bit
- * # instructions. The .text space of
- * # the application starts at 0x22000
- * # with a size of 0x10000 bytes.
- * prof on # Enable profiling.
+ * prof init # Initialize internals.
+ * prof pccfg 4 0x22000 0x10000 # Configure pc logging for 32-bit
+ * # instructions. The .text space of
+ * # the application starts at 0x22000
+ * # with a size of 0x10000 bytes.
+ * prof on # Enable profiling.
*
* TASK ID LOGGING:
* Similar to function logging except that the MONPROF_TIDLOG flag is set
@@ -95,11 +95,11 @@
* pass count is incremented.
*
* Example setup:
- * prof init # Initialize internals.
- * prof tidcfg 16 # Configure tid logging for 16 unique tids.
- * prof on # Enable profiling.
- *
- *
+ * prof init # Initialize internals.
+ * prof tidcfg 16 # Configure tid logging for 16 unique tids.
+ * prof on # Enable profiling.
+ *
+ *
* Original author: Ed Sutter (ed.sutter@alcatel-lucent.com)
*
*/
@@ -113,31 +113,31 @@
#include "tfs.h"
#include "tfsprivate.h"
-#define HALF(m) (m >> 1)
+#define HALF(m) (m >> 1)
/* pdata:
- * One of these represents each symbol (or tid) in the profiling session.
+ * One of these represents each symbol (or tid) in the profiling session.
* For MONPROF_FUNCLOG, the data member is the starting address of the symbol
* and for MONPROF_TIDLOG, the data member is the tid value.
*/
struct pdata {
- ulong data; /* Start of symbol or tid. */
- int pcount; /* Pass count. */
+ ulong data; /* Start of symbol or tid. */
+ int pcount; /* Pass count. */
};
-static int prof_Enabled; /* If set, profiler runs; else return. */
-static int prof_BadSymCnt; /* Number of hits not within a symbol. */
-static int prof_CallCnt; /* Number of times profiler was called. */
-static int prof_FuncTot; /* Number of functions being profiled. */
-static int prof_TidTot; /* Number of TIDs being profiled. */
-static int prof_TidTally; /* Number of unique TIDs logged so far. */
-static int prof_TidOverflow; /* More TIDs than the table was built for. */
-static int prof_PcTot; /* Number of instructions being profiled. */
-static int prof_PcDelta; /* Delta between .text space and PC table. */
-static int prof_PcWidth; /* Width (2 or 4) of PC table elements. */
-static int prof_PcOORCnt; /* Out-of-range hit count for PC profiler */
-static ulong prof_PcTxtEnd; /* End of .text area being profiled */
-static ulong prof_PcTxtBase; /* Base of .text area being profiled */
+static int prof_Enabled; /* If set, profiler runs; else return. */
+static int prof_BadSymCnt; /* Number of hits not within a symbol. */
+static int prof_CallCnt; /* Number of times profiler was called. */
+static int prof_FuncTot; /* Number of functions being profiled. */
+static int prof_TidTot; /* Number of TIDs being profiled. */
+static int prof_TidTally; /* Number of unique TIDs logged so far. */
+static int prof_TidOverflow; /* More TIDs than the table was built for. */
+static int prof_PcTot; /* Number of instructions being profiled. */
+static int prof_PcDelta; /* Delta between .text space and PC table. */
+static int prof_PcWidth; /* Width (2 or 4) of PC table elements. */
+static int prof_PcOORCnt; /* Out-of-range hit count for PC profiler */
+static ulong prof_PcTxtEnd; /* End of .text area being profiled */
+static ulong prof_PcTxtBase; /* Base of .text area being profiled */
static struct pdata *prof_FuncTbl;
static struct pdata *prof_TidTbl;
@@ -147,236 +147,237 @@ static char prof_SymFile[TFSNAMESIZE+1];
void
profiler(struct monprof *mpp)
{
- struct pdata *current, *base;
- int nmem;
-
- if (prof_Enabled == 0)
- return;
-
- if (mpp->type & MONPROF_FUNCLOG) {
- nmem = prof_FuncTot;
- base = prof_FuncTbl;
- while(nmem) {
- current = &base[HALF(nmem)];
- if (mpp->pc < current->data)
- nmem = HALF(nmem);
- else if (mpp->pc > current->data) {
- if (mpp->pc < (current+1)->data) {
- current->pcount++;
- goto tidlog;
- }
- else {
- base = current + 1;
- nmem = (HALF(nmem)) - (nmem ? 0 : 1);
- }
- }
- else {
- current->pcount++;
- goto tidlog;
- }
- }
- prof_BadSymCnt++;
- }
+ struct pdata *current, *base;
+ int nmem;
+
+ if(prof_Enabled == 0) {
+ return;
+ }
+
+ if(mpp->type & MONPROF_FUNCLOG) {
+ nmem = prof_FuncTot;
+ base = prof_FuncTbl;
+ while(nmem) {
+ current = &base[HALF(nmem)];
+ if(mpp->pc < current->data) {
+ nmem = HALF(nmem);
+ } else if(mpp->pc > current->data) {
+ if(mpp->pc < (current+1)->data) {
+ current->pcount++;
+ goto tidlog;
+ } else {
+ base = current + 1;
+ nmem = (HALF(nmem)) - (nmem ? 0 : 1);
+ }
+ } else {
+ current->pcount++;
+ goto tidlog;
+ }
+ }
+ prof_BadSymCnt++;
+ }
tidlog:
- if (mpp->type & MONPROF_TIDLOG) {
- /* First see if the tid is already in the table. If it is,
- * increment the pcount. If it isn't add it to the table.
- */
- nmem = prof_TidTally;
- base = prof_TidTbl;
- while(nmem) {
- current = &base[HALF(nmem)];
- if (mpp->tid < current->data)
- nmem = HALF(nmem);
- else if (mpp->tid > current->data) {
- base = current + 1;
- nmem = (HALF(nmem)) - (nmem ? 0 : 1);
- }
- else {
- current->pcount++;
- goto pclog;
- }
- }
- /* Since we got here, the tid must not be in the table, so
- * do an insertion into the table. Items are in the table in
- * ascending order.
- */
- if (prof_TidTally == 0) {
- prof_TidTbl->pcount = 1;
- prof_TidTbl->data = mpp->tid;
- prof_TidTally++;
- }
- else if (prof_TidTally >= prof_TidTot) {
- prof_TidOverflow++;
- }
- else {
- current = prof_TidTbl + prof_TidTally - 1;
- while(current >= prof_TidTbl) {
- if (mpp->tid > current->data) {
- current++;
- current->pcount = 1;
- current->data = mpp->tid;
- break;
- }
- else {
- *(current+1) = *current;
- if (current == prof_TidTbl) {
- current->pcount = 1;
- current->data = mpp->tid;
- break;
- }
- }
- current--;
- }
- prof_TidTally++;
- }
- }
+ if(mpp->type & MONPROF_TIDLOG) {
+ /* First see if the tid is already in the table. If it is,
+ * increment the pcount. If it isn't add it to the table.
+ */
+ nmem = prof_TidTally;
+ base = prof_TidTbl;
+ while(nmem) {
+ current = &base[HALF(nmem)];
+ if(mpp->tid < current->data) {
+ nmem = HALF(nmem);
+ } else if(mpp->tid > current->data) {
+ base = current + 1;
+ nmem = (HALF(nmem)) - (nmem ? 0 : 1);
+ } else {
+ current->pcount++;
+ goto pclog;
+ }
+ }
+ /* Since we got here, the tid must not be in the table, so
+ * do an insertion into the table. Items are in the table in
+ * ascending order.
+ */
+ if(prof_TidTally == 0) {
+ prof_TidTbl->pcount = 1;
+ prof_TidTbl->data = mpp->tid;
+ prof_TidTally++;
+ } else if(prof_TidTally >= prof_TidTot) {
+ prof_TidOverflow++;
+ } else {
+ current = prof_TidTbl + prof_TidTally - 1;
+ while(current >= prof_TidTbl) {
+ if(mpp->tid > current->data) {
+ current++;
+ current->pcount = 1;
+ current->data = mpp->tid;
+ break;
+ } else {
+ *(current+1) = *current;
+ if(current == prof_TidTbl) {
+ current->pcount = 1;
+ current->data = mpp->tid;
+ break;
+ }
+ }
+ current--;
+ }
+ prof_TidTally++;
+ }
+ }
pclog:
- if (mpp->type & MONPROF_PCLOG) {
- ulong offset;
-
- if ((mpp->pc > prof_PcTxtEnd) || (mpp->pc < prof_PcTxtBase)) {
- prof_PcOORCnt++;
- }
- else {
- offset = mpp->pc - prof_PcDelta;
- switch(prof_PcWidth) {
- case 2:
- (*(ushort *)offset)++;
- break;
- case 4:
- (*(ulong *)offset)++;
- break;
- }
- }
- }
- prof_CallCnt++;
- return;
+ if(mpp->type & MONPROF_PCLOG) {
+ ulong offset;
+
+ if((mpp->pc > prof_PcTxtEnd) || (mpp->pc < prof_PcTxtBase)) {
+ prof_PcOORCnt++;
+ } else {
+ offset = mpp->pc - prof_PcDelta;
+ switch(prof_PcWidth) {
+ case 2:
+ (*(ushort *)offset)++;
+ break;
+ case 4:
+ (*(ulong *)offset)++;
+ break;
+ }
+ }
+ }
+ prof_CallCnt++;
+ return;
}
int
prof_GetSymFile(void)
{
- int tfd;
-
- if (prof_SymFile[0] == 0) {
- tfd = SymFileFd(1);
- }
- else {
- tfd = tfsopen(prof_SymFile,TFS_RDONLY,0);
- if (tfd < 0) {
- printf("%s: %s\n",prof_SymFile,(char *)tfsctrl(TFS_ERRMSG,tfd,0));
- }
- }
- return(tfd);
+ int tfd;
+
+ if(prof_SymFile[0] == 0) {
+ tfd = SymFileFd(1);
+ } else {
+ tfd = tfsopen(prof_SymFile,TFS_RDONLY,0);
+ if(tfd < 0) {
+ printf("%s: %s\n",prof_SymFile,(char *)tfsctrl(TFS_ERRMSG,tfd,0));
+ }
+ }
+ return(tfd);
}
void
prof_ShowStats(int minhit, int more)
{
- int i, tfd, linecount;
- ulong notused;
- char symname[64];
- struct pdata *pptr;
-
- printf("FuncCount Cfg: tbl: 0x%08lx, size: 0x%x\n",
- (ulong)prof_FuncTbl, prof_FuncTot);
- printf("TidCount Cfg: tbl: 0x%08lx, size: 0x%x\n",
- (ulong)prof_TidTbl, prof_TidTot);
- printf("PcCount Cfg: tbl: 0x%08lx, size: 0x%x\n",
- (ulong)prof_PcTbl, prof_PcTot*prof_PcWidth);
-
- if (prof_CallCnt == 0) {
- printf("No data collected%s",
- prof_Enabled == 0 ? " (profiling disabled)\n" : "\n");
- return;
- }
- linecount = 0;
- tfd = prof_GetSymFile();
- if ((prof_FuncTbl) && (prof_FuncTot > 0)) {
- printf("\nFUNC_PROF stats:\n");
- pptr = prof_FuncTbl;
- for(i=0;i<prof_FuncTot;pptr++,i++) {
- if (pptr->pcount < minhit)
- continue;
- if ((tfd < 0) ||
- (AddrToSym(tfd,pptr->data,symname,&notused) == 0)) {
- printf(" %08lx : %d\n",pptr->data,pptr->pcount);
- }
- else {
- printf(" %-25s: %d\n",symname,pptr->pcount);
- }
- if ((more) && (++linecount >= more)) {
- linecount = 0;
- if (More() == 0)
- goto showdone;
- }
- }
- }
- if ((prof_TidTbl) && (prof_TidTot > 0)) {
- printf("\nTID_PROF stats:\n");
- pptr = prof_TidTbl;
- for(i=0;i<prof_TidTot;pptr++,i++) {
- if (pptr->pcount < minhit)
- continue;
- printf(" %08lx : %d\n",pptr->data,pptr->pcount);
- if ((more) && (++linecount >= more)) {
- linecount = 0;
- if (More() == 0)
- goto showdone;
- }
- }
- }
- if (prof_PcTbl) {
- ushort *sp;
- ulong *lp;
-
- sp = (ushort *)prof_PcTbl;
- lp = (ulong *)prof_PcTbl;
- printf("\nPC_PROF stats:\n");
- for(i=0;i<prof_PcTot;i++) {
- switch(prof_PcWidth) {
- case 2:
- if (*sp >= minhit) {
- printf(" %08x : %d\n",
- (int)sp + prof_PcDelta,*sp);
- linecount++;
- }
- sp++;
- break;
- case 4:
- if (*lp >= minhit) {
- printf(" %08x : %ld\n",
- (int)lp + prof_PcDelta,*lp);
- linecount++;
- }
- lp++;
- break;
- }
- if ((more) && (linecount >= more)) {
- linecount = 0;
- if (More() == 0)
- goto showdone;
- }
- }
- }
+ int i, tfd, linecount;
+ ulong notused;
+ char symname[64];
+ struct pdata *pptr;
+
+ printf("FuncCount Cfg: tbl: 0x%08lx, size: 0x%x\n",
+ (ulong)prof_FuncTbl, prof_FuncTot);
+ printf("TidCount Cfg: tbl: 0x%08lx, size: 0x%x\n",
+ (ulong)prof_TidTbl, prof_TidTot);
+ printf("PcCount Cfg: tbl: 0x%08lx, size: 0x%x\n",
+ (ulong)prof_PcTbl, prof_PcTot*prof_PcWidth);
+
+ if(prof_CallCnt == 0) {
+ printf("No data collected%s",
+ prof_Enabled == 0 ? " (profiling disabled)\n" : "\n");
+ return;
+ }
+ linecount = 0;
+ tfd = prof_GetSymFile();
+ if((prof_FuncTbl) && (prof_FuncTot > 0)) {
+ printf("\nFUNC_PROF stats:\n");
+ pptr = prof_FuncTbl;
+ for(i=0; i<prof_FuncTot; pptr++,i++) {
+ if(pptr->pcount < minhit) {
+ continue;
+ }
+ if((tfd < 0) ||
+ (AddrToSym(tfd,pptr->data,symname,&notused) == 0)) {
+ printf(" %08lx : %d\n",pptr->data,pptr->pcount);
+ } else {
+ printf(" %-25s: %d\n",symname,pptr->pcount);
+ }
+ if((more) && (++linecount >= more)) {
+ linecount = 0;
+ if(More() == 0) {
+ goto showdone;
+ }
+ }
+ }
+ }
+ if((prof_TidTbl) && (prof_TidTot > 0)) {
+ printf("\nTID_PROF stats:\n");
+ pptr = prof_TidTbl;
+ for(i=0; i<prof_TidTot; pptr++,i++) {
+ if(pptr->pcount < minhit) {
+ continue;
+ }
+ printf(" %08lx : %d\n",pptr->data,pptr->pcount);
+ if((more) && (++linecount >= more)) {
+ linecount = 0;
+ if(More() == 0) {
+ goto showdone;
+ }
+ }
+ }
+ }
+ if(prof_PcTbl) {
+ ushort *sp;
+ ulong *lp;
+
+ sp = (ushort *)prof_PcTbl;
+ lp = (ulong *)prof_PcTbl;
+ printf("\nPC_PROF stats:\n");
+ for(i=0; i<prof_PcTot; i++) {
+ switch(prof_PcWidth) {
+ case 2:
+ if(*sp >= minhit) {
+ printf(" %08x : %d\n",
+ (int)sp + prof_PcDelta,*sp);
+ linecount++;
+ }
+ sp++;
+ break;
+ case 4:
+ if(*lp >= minhit) {
+ printf(" %08x : %ld\n",
+ (int)lp + prof_PcDelta,*lp);
+ linecount++;
+ }
+ lp++;
+ break;
+ }
+ if((more) && (linecount >= more)) {
+ linecount = 0;
+ if(More() == 0) {
+ goto showdone;
+ }
+ }
+ }
+ }
showdone:
- putchar('\n');
- if (prof_BadSymCnt)
- printf("%d out-of-range symbols\n",prof_BadSymCnt);
- if (prof_TidOverflow)
- printf("%d tid overflow attempts\n",prof_TidOverflow);
- if (prof_PcOORCnt)
- printf("%d pc out-of-range hits\n",prof_PcOORCnt);
- printf("%d total profiler calls\n",prof_CallCnt);
-
- if (tfd >= 0)
- tfsclose(tfd,0);
- return;
+ putchar('\n');
+ if(prof_BadSymCnt) {
+ printf("%d out-of-range symbols\n",prof_BadSymCnt);
+ }
+ if(prof_TidOverflow) {
+ printf("%d tid overflow attempts\n",prof_TidOverflow);
+ }
+ if(prof_PcOORCnt) {
+ printf("%d pc out-of-range hits\n",prof_PcOORCnt);
+ }
+ printf("%d total profiler calls\n",prof_CallCnt);
+
+ if(tfd >= 0) {
+ tfsclose(tfd,0);
+ }
+ return;
}
/* prof_FuncConfig():
- * This function builds a table of pdata structures based on the
+ * This function builds a table of pdata structures based on the
* content of the symbol table.
* It assumes the file is a list of symbols and addresses listed
* in ascending address order.
@@ -384,257 +385,248 @@ showdone:
void
prof_FuncConfig(void)
{
- int tfd, i;
- struct pdata *pfp;
- char line[80], *space;
-
- tfd = prof_GetSymFile();
- if (tfd < 0)
- return;
-
- prof_FuncTot = 0;
- pfp = prof_FuncTbl;
-
- while(tfsgetline(tfd,line,sizeof(line)-1)) {
- space = strpbrk(line,"\t ");
- if (!space)
- continue;
- *space++ = 0;
- while(isspace(*space))
- space++;
- pfp->data = strtoul(space,0,0);
- pfp->pcount = 0;
- pfp++;
- prof_FuncTot++;
- }
- tfsclose(tfd,0);
-
- /* Add one last item to the list so that there is an upper limit for
- * the final symbol in the table:
- */
- pfp->data = 0xffffffff;
- pfp->pcount = 0;
-
- /* Test to verify that all symbols are in ascending address order...
- */
- for (i=0;i<prof_FuncTot;i++) {
- if (prof_FuncTbl[i].data > prof_FuncTbl[i+1].data) {
- printf("Warning: function addresses not in order\n");
- break;
- }
- }
- prof_FuncTot++;
+ int tfd, i;
+ struct pdata *pfp;
+ char line[80], *space;
+
+ tfd = prof_GetSymFile();
+ if(tfd < 0) {
+ return;
+ }
+
+ prof_FuncTot = 0;
+ pfp = prof_FuncTbl;
+
+ while(tfsgetline(tfd,line,sizeof(line)-1)) {
+ space = strpbrk(line,"\t ");
+ if(!space) {
+ continue;
+ }
+ *space++ = 0;
+ while(isspace(*space)) {
+ space++;
+ }
+ pfp->data = strtoul(space,0,0);
+ pfp->pcount = 0;
+ pfp++;
+ prof_FuncTot++;
+ }
+ tfsclose(tfd,0);
+
+ /* Add one last item to the list so that there is an upper limit for
+ * the final symbol in the table:
+ */
+ pfp->data = 0xffffffff;
+ pfp->pcount = 0;
+
+ /* Test to verify that all symbols are in ascending address order...
+ */
+ for(i=0; i<prof_FuncTot; i++) {
+ if(prof_FuncTbl[i].data > prof_FuncTbl[i+1].data) {
+ printf("Warning: function addresses not in order\n");
+ break;
+ }
+ }
+ prof_FuncTot++;
}
/* prof():
*/
char *ProfHelp[] = {
- "Profiler configuration and result display",
- "-[h:m:s:] [operation] [op-specific args]",
+ "Profiler configuration and result display",
+ "-[h:m:s:] [operation] [op-specific args]",
#if INCLUDE_VERBOSEHELP
- "Operations:",
- " on enable profiler",
- " off disable profiler",
- " show dump stats",
- " init clear internal tables and runtime stats",
- " call {type pc tid} call profiler from CLI",
- " ('type' can be any combination of 't', 'f' & 'p')",
- " restart clear runtime stats only",
- " tidcfg {tidtot} init tid profiler based on number of task ids",
- " funccfg init function profiler from symtbl file",
- " pccfg {wid add siz} init pc profiler with instruction width (2 or 4)",
- " plus size and addr of text area",
- "",
- "Options:",
- " -a{#} address to use for table",
- " -h{#} minimum hit count for show",
- " -m{#} line count for output throttling in show",
- " -s{symfile} use this file for symbols instead of default",
+ "Operations:",
+ " on enable profiler",
+ " off disable profiler",
+ " show dump stats",
+ " init clear internal tables and runtime stats",
+ " call {type pc tid} call profiler from CLI",
+ " ('type' can be any combination of 't', 'f' & 'p')",
+ " restart clear runtime stats only",
+ " tidcfg {tidtot} init tid profiler based on number of task ids",
+ " funccfg init function profiler from symtbl file",
+ " pccfg {wid add siz} init pc profiler with instruction width (2 or 4)",
+ " plus size and addr of text area",
+ "",
+ "Options:",
+ " -a{#} address to use for table",
+ " -h{#} minimum hit count for show",
+ " -m{#} line count for output throttling in show",
+ " -s{symfile} use this file for symbols instead of default",
#endif
- 0,
+ 0,
};
int
Prof(int argc,char *argv[])
{
- char *arg1, *arg2, *arg3, *arg4;
- ulong address;
- int i, opt, minhit, ret, more;
-
- ret = CMD_SUCCESS;
- minhit = 1;
- more = 0;
- address = 0;
- while((opt=getopt(argc,argv,"a:h:m:s:")) != -1) {
- switch(opt) {
- case 'a':
- address = strtoul(optarg,0,0);
- break;
- case 'h':
- minhit = atoi(optarg);
- break;
- case 'm':
- more = atoi(optarg);
- break;
- case 's':
- strncpy(prof_SymFile,optarg,TFSNAMESIZE);
- prof_SymFile[TFSNAMESIZE] = 0;
- break;
- default:
- return(CMD_PARAM_ERROR);
- }
- }
-
- arg1 = argv[optind];
- arg2 = argv[optind+1];
- arg3 = argv[optind+2];
- arg4 = argv[optind+3];
-
- if (argc == optind+1) {
- if (!strcmp(arg1,"on")) {
- prof_Enabled = 1;
- }
- else if (!strcmp(arg1,"off")) {
- prof_Enabled = 0;
- }
- else if (!strcmp(arg1,"show")) {
- prof_ShowStats(minhit, more);
- }
- else if (!strcmp(arg1,"init")) {
- prof_BadSymCnt = 0;
- prof_CallCnt = 0;
- prof_TidTally = 0;
- prof_Enabled = 0;
- prof_FuncTot = 0;
- prof_TidTot = 0;
- prof_PcTot = 0;
- prof_FuncTbl = (struct pdata *)0;
- prof_TidTbl = (struct pdata *)0;
- prof_PcTbl = (uchar *)0;
- prof_PcWidth = 0;
- prof_PcDelta = 0;
- prof_SymFile[0] = 0;
- }
- else if (!strcmp(arg1,"restart")) {
- prof_BadSymCnt = 0;
- prof_CallCnt = 0;
- prof_TidTally = 0;
- if (prof_FuncTbl) {
- for(i=0;i<prof_FuncTot;i++)
- prof_FuncTbl[i].pcount = 0;
- }
- if (prof_TidTbl) {
- for(i=0;i<prof_TidTot;i++)
- prof_TidTbl[i].pcount = 0;
- prof_TidTbl[i].data = 0;
- }
- if (prof_PcTbl) {
- memset((char *)prof_PcTbl,0,prof_PcTot*prof_PcWidth);
- }
- }
- else if (!strcmp(arg1,"funccfg")) {
- if (prof_FuncTbl) {
- printf("Already configured, run init to re-configure\n");
- return(CMD_FAILURE);
- }
- else if (prof_PcTbl) {
- printf("Can't use PC and FUNC profiling simultaneously\n");
- return(CMD_FAILURE);
- }
- else if (address) {
- prof_FuncTbl = (struct pdata *)address;
- }
- else if (prof_TidTbl) {
- prof_FuncTbl = &prof_TidTbl[prof_TidTot];
- }
- else
- prof_FuncTbl = (struct pdata *)getAppRamStart();
-
- prof_FuncConfig();
- }
- else
- ret = CMD_PARAM_ERROR;
- }
- else if (argc == optind+2) {
- if (!strcmp(arg1,"tidcfg")) {
- if (prof_TidTbl) {
- printf("Already configured, run init to re-configure\n");
- return(CMD_FAILURE);
- }
- else if (address) {
- prof_TidTbl = (struct pdata *)address;
- }
- else if (prof_FuncTbl) {
- prof_TidTbl = &prof_FuncTbl[prof_FuncTot];
- }
- else if (prof_PcTbl) {
- prof_TidTbl = (struct pdata *)&prof_PcTbl[prof_PcTot];
- }
- else
- prof_TidTbl = (struct pdata *)getAppRamStart();
- prof_TidTot = strtoul(arg2,0,0);
- for(i=0;i<prof_TidTot;i++) {
- prof_TidTbl[i].data = 0;
- prof_TidTbl[i].pcount = 0;
- }
- }
- else
- ret = CMD_PARAM_ERROR;
- }
- else if (argc == optind+4) {
- if (!strcmp(arg1,"call")) {
- struct monprof mp;
-
- mp.type = 0;
-
- if (strchr(arg2,'f'))
- mp.type |= MONPROF_FUNCLOG;
- if (strchr(arg2,'p'))
- mp.type |= MONPROF_PCLOG;
- if (strchr(arg2,'t'))
- mp.type |= MONPROF_TIDLOG;
-
- mp.pc = strtoul(arg3,0,0);
- mp.tid = strtoul(arg4,0,0);
-
- profiler(&mp);
- }
- else if (!strcmp(arg1,"pccfg")) {
- int size;
-
- if (prof_PcTbl) {
- printf("Already configured, run init to re-configure\n");
- return(CMD_FAILURE);
- }
- else if (prof_FuncTbl) {
- printf("Can't use PC and FUNC profiling simultaneously\n");
- return(CMD_FAILURE);
- }
- else if (address) {
- prof_PcTbl = (uchar *)address;
- }
- else if (prof_TidTbl) {
- prof_PcTbl = (uchar *)&prof_TidTbl[prof_TidTot];
- }
- else
- prof_PcTbl = (uchar *)getAppRamStart();
- prof_PcWidth = strtol(arg2,0,0); /* instruction width */
- prof_PcTxtBase = strtol(arg3,0,0); /* address of .text */
- size = strtol(arg4,0,0); /* size of .text */
- prof_PcTxtEnd = prof_PcTxtBase + size;
- prof_PcTot = size / prof_PcWidth;
- prof_PcDelta = (ulong)prof_PcTxtBase - (ulong)prof_PcTbl;
- memset((char *)prof_PcTbl,0,prof_PcTot*prof_PcWidth);
-
- }
- else
- ret = CMD_PARAM_ERROR;
- }
- else
- ret = CMD_PARAM_ERROR;
-
- return(ret);
+ char *arg1, *arg2, *arg3, *arg4;
+ ulong address;
+ int i, opt, minhit, ret, more;
+
+ ret = CMD_SUCCESS;
+ minhit = 1;
+ more = 0;
+ address = 0;
+ while((opt=getopt(argc,argv,"a:h:m:s:")) != -1) {
+ switch(opt) {
+ case 'a':
+ address = strtoul(optarg,0,0);
+ break;
+ case 'h':
+ minhit = atoi(optarg);
+ break;
+ case 'm':
+ more = atoi(optarg);
+ break;
+ case 's':
+ strncpy(prof_SymFile,optarg,TFSNAMESIZE);
+ prof_SymFile[TFSNAMESIZE] = 0;
+ break;
+ default:
+ return(CMD_PARAM_ERROR);
+ }
+ }
+
+ arg1 = argv[optind];
+ arg2 = argv[optind+1];
+ arg3 = argv[optind+2];
+ arg4 = argv[optind+3];
+
+ if(argc == optind+1) {
+ if(!strcmp(arg1,"on")) {
+ prof_Enabled = 1;
+ } else if(!strcmp(arg1,"off")) {
+ prof_Enabled = 0;
+ } else if(!strcmp(arg1,"show")) {
+ prof_ShowStats(minhit, more);
+ } else if(!strcmp(arg1,"init")) {
+ prof_BadSymCnt = 0;
+ prof_CallCnt = 0;
+ prof_TidTally = 0;
+ prof_Enabled = 0;
+ prof_FuncTot = 0;
+ prof_TidTot = 0;
+ prof_PcTot = 0;
+ prof_FuncTbl = (struct pdata *)0;
+ prof_TidTbl = (struct pdata *)0;
+ prof_PcTbl = (uchar *)0;
+ prof_PcWidth = 0;
+ prof_PcDelta = 0;
+ prof_SymFile[0] = 0;
+ } else if(!strcmp(arg1,"restart")) {
+ prof_BadSymCnt = 0;
+ prof_CallCnt = 0;
+ prof_TidTally = 0;
+ if(prof_FuncTbl) {
+ for(i=0; i<prof_FuncTot; i++) {
+ prof_FuncTbl[i].pcount = 0;
+ }
+ }
+ if(prof_TidTbl) {
+ for(i=0; i<prof_TidTot; i++) {
+ prof_TidTbl[i].pcount = 0;
+ }
+ prof_TidTbl[i].data = 0;
+ }
+ if(prof_PcTbl) {
+ memset((char *)prof_PcTbl,0,prof_PcTot*prof_PcWidth);
+ }
+ } else if(!strcmp(arg1,"funccfg")) {
+ if(prof_FuncTbl) {
+ printf("Already configured, run init to re-configure\n");
+ return(CMD_FAILURE);
+ } else if(prof_PcTbl) {
+ printf("Can't use PC and FUNC profiling simultaneously\n");
+ return(CMD_FAILURE);
+ } else if(address) {
+ prof_FuncTbl = (struct pdata *)address;
+ } else if(prof_TidTbl) {
+ prof_FuncTbl = &prof_TidTbl[prof_TidTot];
+ } else {
+ prof_FuncTbl = (struct pdata *)getAppRamStart();
+ }
+
+ prof_FuncConfig();
+ } else {
+ ret = CMD_PARAM_ERROR;
+ }
+ } else if(argc == optind+2) {
+ if(!strcmp(arg1,"tidcfg")) {
+ if(prof_TidTbl) {
+ printf("Already configured, run init to re-configure\n");
+ return(CMD_FAILURE);
+ } else if(address) {
+ prof_TidTbl = (struct pdata *)address;
+ } else if(prof_FuncTbl) {
+ prof_TidTbl = &prof_FuncTbl[prof_FuncTot];
+ } else if(prof_PcTbl) {
+ prof_TidTbl = (struct pdata *)&prof_PcTbl[prof_PcTot];
+ } else {
+ prof_TidTbl = (struct pdata *)getAppRamStart();
+ }
+ prof_TidTot = strtoul(arg2,0,0);
+ for(i=0; i<prof_TidTot; i++) {
+ prof_TidTbl[i].data = 0;
+ prof_TidTbl[i].pcount = 0;
+ }
+ } else {
+ ret = CMD_PARAM_ERROR;
+ }
+ } else if(argc == optind+4) {
+ if(!strcmp(arg1,"call")) {
+ struct monprof mp;
+
+ mp.type = 0;
+
+ if(strchr(arg2,'f')) {
+ mp.type |= MONPROF_FUNCLOG;
+ }
+ if(strchr(arg2,'p')) {
+ mp.type |= MONPROF_PCLOG;
+ }
+ if(strchr(arg2,'t')) {
+ mp.type |= MONPROF_TIDLOG;
+ }
+
+ mp.pc = strtoul(arg3,0,0);
+ mp.tid = strtoul(arg4,0,0);
+
+ profiler(&mp);
+ } else if(!strcmp(arg1,"pccfg")) {
+ int size;
+
+ if(prof_PcTbl) {
+ printf("Already configured, run init to re-configure\n");
+ return(CMD_FAILURE);
+ } else if(prof_FuncTbl) {
+ printf("Can't use PC and FUNC profiling simultaneously\n");
+ return(CMD_FAILURE);
+ } else if(address) {
+ prof_PcTbl = (uchar *)address;
+ } else if(prof_TidTbl) {
+ prof_PcTbl = (uchar *)&prof_TidTbl[prof_TidTot];
+ } else {
+ prof_PcTbl = (uchar *)getAppRamStart();
+ }
+ prof_PcWidth = strtol(arg2,0,0); /* instruction width */
+ prof_PcTxtBase = strtol(arg3,0,0); /* address of .text */
+ size = strtol(arg4,0,0); /* size of .text */
+ prof_PcTxtEnd = prof_PcTxtBase + size;
+ prof_PcTot = size / prof_PcWidth;
+ prof_PcDelta = (ulong)prof_PcTxtBase - (ulong)prof_PcTbl;
+ memset((char *)prof_PcTbl,0,prof_PcTot*prof_PcWidth);
+
+ } else {
+ ret = CMD_PARAM_ERROR;
+ }
+ } else {
+ ret = CMD_PARAM_ERROR;
+ }
+
+ return(ret);
}
#else