1 /*
2  *  Copyright 2001-2008 Texas Instruments - http://www.ti.com/
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16 
17 /*
18  *  ======== cexec.c ========
19  *  "cexec" is a Linux console-based utility that allows developers to load
20  *  and start a new DSP/BIOS Bridge based DSP program. If "cexec" encounters
21  *  an error, it will display a DSP/BIOS Bridge GPP API error code.
22  *
23  *  Usage:
24  *      cexec [optional args] <dsp_program>
25  *
26  *  Options:
27  *      -?: displays "cexec" usage. If this option is set, cexec does not
28  *          load the DSP program.
29  *      -w: waits for the user to hit the enter key on the keyboard, which
30  *          stops DSP program execution by placing the DSP into reset. This
31  *          will also display on the WinCE console window the contents of
32  *          DSP/BIOS Bridge trace buffer, which is used internally by the
33  *          DSP/BIOS Bridge runtime. If this option is not specified, "cexec"
34  *          loads and starts the DSP program, then returns immeidately,
35  *          leaving the DSP program running.
36  *      -v: verbose mode.
37  *      -p [processor]: defines the DSP processor on which to execute code,
38  *          where processor is the processor number provided by cexec to
39  *          the DSPProcessor_Attach() function. If this option is not
40  *          specified, the default processor is 0.
41  *      -T: Set scriptable mode. If set, cexec will run to completion after
42  *          loading and running a DSP target. User will not be able to stop
43  *          the loaded DSP target.
44  *
45  *  Example:
46  *      1.  Load and execute a DSP/BIOS Bridge base image, waiting for user to
47  *          hit enter key to halt the DSP.
48  *
49  *          cexec -w chnltest_tiomap1510.x55l
50  *
51  *      2.  Start a program running on the second processor (zero-indexed).
52  *          This will halt the currently running DSP program, if any.
53  *
54  *          cexec -w -p l chnltest_tiomap1510.x55l
55  *
56  *      3.  Load and start a program running on the DSP. Cexec will run to
57  *          completion and leave the DSP loaded and running.
58  *
59  *          cexec -T chnltest_tiomap1510.x55l
60  *
61  *! Revision History:
62  *! ================
63  *! 20-Oct-2002 map: 	Instrumented to measure performance on PROC_Load
64  *! 31-Jul-2002 kc:     Added scriptable mode to enable batch testing.
65  *! 05-Apr-2001 kc:     Adapted from existing cexec. Updated cexec program
66  *!                     options. Added command line argument handling.
67  *!                     Based on DSP/BIOS Bridge API version 0.??.
68  *! 13-Feb-2001 kc:     DSP/BIOS Bridge name update.
69  *! 15-Nov-2000 jeh     Converted to use DSPProcessor.
70  */
71 
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <unistd.h>
75 #include <dbdefs.h>
76 /* #include <varargs.h> */
77 #include <stdarg.h>
78 
79 #include <dbapi.h>
80 #include <DSPManager.h>
81 #include <DSPProcessor.h>
82 #include <DSPProcessor_OEM.h>
83 
84 /* global constants. */
85 #define MAXTRACESIZE 256   /* size of trace buffer. */
86 
87 /* function prototype. */
88 VOID DisplayUsage();
89 VOID PrintVerbose(PSTR pstrFmt,...);
90 
91 /* global variables. */
92 bool g_fVerbose = false;
93 
94 /*
95  *  ======== main ========
96  */
main(INT argc,CHAR * argv[])97 INT main(INT argc, CHAR * argv[])
98 {
99 	INT opt;
100 	bool fWaitForTerminate = false;
101 	UINT uProcId = 0;	/* default proc ID is 0. */
102 	bool fError = false;
103 	DSP_HPROCESSOR hProc;
104 	DSP_STATUS status = DSP_SOK;
105 	INT cArgc = 0;		/* local argc count. */
106 	bool fScriptable = false;
107 	extern char *optarg;
108 	struct DSP_PROCESSORINFO dspInfo;
109 	UINT numProcs;
110 	UINT index = 0;
111 	while ((opt = getopt(argc, argv, "+T+v+w+?p:")) != EOF) {
112 		switch (opt) {
113 		case 'v':
114 			/* verbose mode */
115 			fprintf(stdout, "Verbose mode: ON\n");
116 			g_fVerbose = true;
117 			cArgc++;
118 			break;
119 		case 'w':
120 			/* wait for user input to terminate */
121 			fprintf(stdout, "Not supported \n");
122 			fWaitForTerminate = true;
123 			cArgc++;
124 			break;
125 		case 'T':
126 			fScriptable = true;
127 			cArgc++;
128 			break;
129 		case 'p':
130 			/* user specified DSP processor ID (based on zero-index) */
131 			uProcId = atoi(optarg);
132 			cArgc++;
133 			break;
134 		case '?':
135 		default:
136 			fError = true;
137 			break;
138 		}
139 	}
140 	argv += cArgc + 1;
141 	argc -= cArgc + 1;
142 	if (fError) {
143 		DisplayUsage();
144 	} else {
145 		status = (DBAPI)DspManager_Open(0, NULL);
146 		if (DSP_FAILED(status)) {
147 			PrintVerbose("DSPManager_Open failed \n");
148 			return -1;
149 		}
150 		while (DSP_SUCCEEDED(DSPManager_EnumProcessorInfo(index,&dspInfo,
151 						(UINT)sizeof(struct DSP_PROCESSORINFO),&numProcs))) {
152 			if ((dspInfo.uProcessorType == DSPTYPE_55) ||
153 									(dspInfo.uProcessorType == DSPTYPE_64)) {
154 				printf("DSP device detected !! \n");
155 				uProcId = index;
156 				status = DSP_SOK;
157 				break;
158 			}
159 			index++;
160 		}
161 		status = DSPProcessor_Attach(uProcId, NULL, &hProc);
162 		if (DSP_SUCCEEDED(status)) {
163 			PrintVerbose("DSPProcessor_Attach succeeded.\n");
164 			status = DSPProcessor_Stop(hProc);
165 			if (DSP_SUCCEEDED(status)) {
166 				PrintVerbose("DSPProcessor_Stop succeeded.\n");
167 				status = DSPProcessor_Load(hProc,argc,(CONST CHAR **)argv,NULL);
168 				if (DSP_SUCCEEDED(status)) {
169 					PrintVerbose("DSPProcessor_Load succeeded.\n");
170 					status = DSPProcessor_Start(hProc);
171 					if (DSP_SUCCEEDED(status)) {
172 						fprintf(stdout,"DSPProcessor_Start succeeded.\n");
173 #if 0
174 						/* It seems Linux bridge does n't yet support
175 						 * * DSPProcessor_GetTrace */
176 						if (fWaitForTerminate) {
177 							/* wait for user */
178 							fprintf(stdout,"Hit \"return\" to stop DSP and"
179 													"dump trace buffer:\n");
180 							(void)getchar();
181 							status = DSPProcessor_GetTrace(hProc,
182 												(BYTE *)&traceBuf,MAXTRACESIZE);
183 							fprintf(stdout,"%s\n",traceBuf);
184 						} else {
185 							PrintVerbose("in run free mode...\n");
186 						}
187 #endif	/* 0 */
188 					} else {
189 						PrintVerbose("DSPProcessor_Start failed: 0x%x.\n",
190 																		status);
191 					}
192 				} else {
193 					PrintVerbose("DSPProcessor_Load failed: 0x%x.\n",status);
194 				}
195 				DSPProcessor_Detach(hProc);
196 			}
197 		} else {
198 			PrintVerbose("DSPProcessor_Attach failed: 0x%x.\n",status);
199 		}
200 	}
201 	if (!fScriptable) {
202 		/* Wait for user to hit any key before exiting. */
203 		fprintf(stdout, "Hit any key to terminate cexec.\n");
204 		(void)getchar();
205 	}
206 	status = DspManager_Close(0, NULL);
207 	if (DSP_FAILED(status)) {
208 		printf("\nERROR: DSPManager Close FAILED\n");
209 	}
210 	return (DSP_SUCCEEDED(status) ? 0 : -1);
211 }
212 
DisplayUsage()213 VOID DisplayUsage()
214 {
215 	fprintf(stdout, "Usage: cexec [options] <dsp program>\n");
216 	fprintf(stdout, "\t[optional arguments]:\n");
217 	fprintf(stdout, "\t-?: Display cexec usage\n");
218 	fprintf(stdout, "\t-v: Verbose mode\n");
219 	fprintf(stdout, "\t-w: Waits for user to hit enter key before\n");
220 	fprintf(stdout, "\t    terminating. Displays trace buffer\n");
221 	fprintf(stdout, "\t-p [processor]: User-specified processor #\n");
222 	fprintf(stdout, "\n\t[required arguments]:\n");
223 	fprintf(stdout, "\t<dsp program>\n");
224 	fprintf(stdout, "\n\tExample: cexec -w -p 1 prog.x55l\n\n");
225 }
226 
227 
228 /*
229  * ======== PrintVerbose ========
230  */
PrintVerbose(PSTR pstrFmt,...)231 VOID PrintVerbose(PSTR pstrFmt,...)
232 {
233 	va_list args;
234 	if (g_fVerbose) {
235 		va_start(args, pstrFmt);
236 		vfprintf(stdout, pstrFmt, args);
237 		va_end(args);
238 		fflush(stdout);
239 	}
240 }
241 
242 
243