FreeCalypso > hg > freecalypso-reveng
comparison fluid-mnf/fluid.c @ 311:9cecc930d78f
fluid-mnf: original source from TI,
defenestrated line endings and rearranged directory structure,
but no *.[ch] source file content changes yet
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 29 Feb 2020 05:36:07 +0000 |
parents | |
children | 77c86062e253 |
comparison
equal
deleted
inserted
replaced
310:ae39d76d5b7a | 311:9cecc930d78f |
---|---|
1 /****************************************************************************** | |
2 * FLUID (Flash Loader Utility Independent of Device) | |
3 * | |
4 * Copyright Texas Instruments, 2001. | |
5 * Mads Meisner-Jensen, mmj@ti.com. | |
6 * | |
7 * Main, command-line argument parsing, error handling. | |
8 * | |
9 * $Id: fluid.c 1.50 Thu, 14 Nov 2002 13:10:05 +0100 tsj $ | |
10 * | |
11 ******************************************************************************/ | |
12 | |
13 #include "fluid.h" | |
14 #include "flash.h" | |
15 #include "fileio.h" | |
16 #include "trace.h" | |
17 // Secure Calypso Plus | |
18 #include "../inc/ram_load.h" | |
19 | |
20 #include <stdio.h> | |
21 #include <string.h> | |
22 #include <stdlib.h> | |
23 #include <stdarg.h> | |
24 | |
25 #if defined(MSC) || defined(BCC) | |
26 #include "getopt.h" | |
27 #include "windows.h" | |
28 #else | |
29 #include <getopt.h> | |
30 #endif | |
31 | |
32 #include <errno.h> // for ERANGE | |
33 | |
34 | |
35 /****************************************************************************** | |
36 * Prototypes and Globals | |
37 ******************************************************************************/ | |
38 | |
39 extern T_RAM_LOADER d_ram_loader; // Secure Calypso Plus | |
40 | |
41 char *arg_file_list[ARG_FILE_LIST_SIZE_MAX] = { (char *) 0 }; | |
42 int arg_file_list_size = 0; | |
43 | |
44 char *arg_erase_override = ""; | |
45 char *arg_read = ""; | |
46 char *arg_write = ""; | |
47 int arg_checksum = 1; | |
48 int arg_compress = 1; | |
49 int arg_dry_run = 0; | |
50 int arg_list_devices = 0; | |
51 char arg_target_type = 0; | |
52 int arg_image_map_show = 0; | |
53 int arg_sector_map_show = 0; | |
54 int arg_sector_list_show = 0; | |
55 int arg_timers_show = 0; | |
56 int arg_timers_extended_show = 0; | |
57 int arg_checksum_show = 0; | |
58 int arg_show_hexdump = 0; | |
59 int arg_target_trace_enable = 0; | |
60 int arg_progress = 'a'; | |
61 char arg_hexfile_type = 'm'; | |
62 char arg_hexfile_memwidth = 2; | |
63 | |
64 int arg_target_reset = 1; | |
65 int arg_rom_bootloader = 0; | |
66 int arg_boot_delay_rom = 15; | |
67 int arg_boot_delay_fluid = 15; | |
68 int arg_device_id0 = -1; | |
69 int arg_device_id1 = -1; | |
70 | |
71 int arg_uart_port = 1; | |
72 int arg_uart_baudrate = 115200; | |
73 char arg_uart_flowcontrol[] = "pn"; | |
74 char arg_uart_level_convert = 0; | |
75 | |
76 char arg_verbose = 0; | |
77 int arg_debug_resume = 0; | |
78 int arg_debug_trace_pe = 0; | |
79 int arg_keep_going = 0; | |
80 int arg_show_main_args = 0; | |
81 int arg_skip_erase = 0; | |
82 | |
83 // Secure Calypso Plus | |
84 char *arg_die_id_file_name = ""; | |
85 char *arg_imeisv = ""; | |
86 char *arg_platform_certificate_addr = ""; | |
87 int arg_request_certificate = 0; | |
88 int arg_delay_for_changing_cs5 = 0; | |
89 int arg_uart_baudrate_during_cmd_download = 115200; | |
90 int arg_uart_timeout_configuration = 0; | |
91 int arg_block_size = 8 * 1024; // Must be a modulus of 64 bytes, except for the last command. | |
92 | |
93 int arg_usage = 0; | |
94 | |
95 char *argv_0; | |
96 | |
97 int arg_tr_mask = 0; | |
98 int arg_tr_spaces = 2; | |
99 char *arg_tr_file = NULL; | |
100 | |
101 int arg_errorfd = 2; | |
102 | |
103 static void main_usage(void); | |
104 static void main_args(int argc, char *argv[]); | |
105 static long arg_long_get(void); | |
106 | |
107 extern int fluid_machine(void); | |
108 extern int fluid_compress(void); | |
109 extern int fluid_decompress(void); | |
110 | |
111 extern int serial_is_baudrate(int bps); | |
112 | |
113 | |
114 /****************************************************************************** | |
115 * Error handling | |
116 ******************************************************************************/ | |
117 | |
118 extern char *main_strerror(int error); | |
119 | |
120 char *win32_strerror(void) | |
121 { | |
122 static char buf[220]; | |
123 int error; | |
124 char *p = buf; | |
125 | |
126 error = GetLastError(); | |
127 p += sprintf(buf, "%d: ", error); | |
128 | |
129 if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, | |
130 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), | |
131 p, sizeof(buf) - 20, NULL) == 0) | |
132 sprintf(p, "(Unknown Win32 error)"); | |
133 | |
134 return buf; | |
135 } | |
136 | |
137 void main_msg(char *format, ...) | |
138 { | |
139 va_list args; | |
140 char buf[1024]; | |
141 | |
142 va_start(args, format); | |
143 vsprintf(buf, format, args); | |
144 va_end(args); | |
145 | |
146 if (arg_errorfd == 2) { | |
147 fprintf(stderr, "%s", buf); | |
148 fflush(stderr); | |
149 } | |
150 else { | |
151 fprintf(stdout, "%s", buf); | |
152 fflush(stdout); | |
153 } | |
154 } | |
155 | |
156 void main_error_str(char type, int error, char *string) | |
157 { | |
158 // If it was an OS error... | |
159 if (error < E_OS) { | |
160 error -= E_OS; | |
161 main_msg("OS-ERROR: %s", win32_strerror()); | |
162 } | |
163 | |
164 main_msg(" %s(%d): %s%s\n", (type == 'w' ? "WARNING" : "ERROR"), | |
165 -error, main_strerror(error), string); | |
166 } | |
167 | |
168 void main_warning(int error) | |
169 { | |
170 main_error_str('w', error, ""); | |
171 } | |
172 | |
173 void main_error(int error) | |
174 { | |
175 main_error_str('e', error, ""); | |
176 | |
177 if (arg_keep_going == 0) | |
178 exit(-error); | |
179 } | |
180 | |
181 void main_fatal(int error) | |
182 { | |
183 main_error(error); | |
184 exit(-error); | |
185 } | |
186 | |
187 | |
188 /****************************************************************************** | |
189 * Command line parsing | |
190 ******************************************************************************/ | |
191 | |
192 static void main_help(void) | |
193 { | |
194 printf( | |
195 "\n" | |
196 "You have started fluid with no command line arguments\n" | |
197 "\n" | |
198 "To see all the available command line arguments, start fluid\n" | |
199 "from a command line prompt (cmd.exe or similar) with:\n" | |
200 "\n" | |
201 " fluid -h\n" | |
202 "\n" | |
203 "To see some basic and common examples of usage, start fluid with:\n" | |
204 "\n" | |
205 " fluid -ic\n" | |
206 "\n" | |
207 "You can get an overview of all the available examples with:\n" | |
208 "\n" | |
209 " fluid -ii\n" | |
210 "\n" | |
211 // "Please read the README file for notes and other info and read the\n" | |
212 // "HISTORY file to see what has happened with fluid since last release.\n" | |
213 // "\n" | |
214 "Press RETURN to exit...\n" | |
215 ); | |
216 getchar(); | |
217 } | |
218 | |
219 static void main_example(int type) | |
220 { | |
221 switch (type) { | |
222 case 'c': | |
223 printf( | |
224 "Download into board:\n" | |
225 " fluid -f gsm.m0\n" | |
226 "\n" | |
227 "Simulate a download into board (dry-run):\n" | |
228 " fluid -n -f gsm.m0\n" | |
229 "\n" | |
230 "Check if file has already been downloaded into board:\n" | |
231 " fluid -n -f gsm.m0\n" | |
232 "\n" | |
233 "Download into board without erasing boot sector:\n" | |
234 " fluid -e-0 -f gsm.m0\n" | |
235 "\n" | |
236 "Download into board with another progress indication:\n" | |
237 " fluid -gc -f gsm.m0\n" | |
238 "\n" | |
239 ); | |
240 break; | |
241 case 'a': | |
242 printf( | |
243 "Download into board with more output verbosity:\n" | |
244 " fluid -v -v -f gsm.m0\n" | |
245 "\n" | |
246 "Show the image map (which parts of the flash are used, which are not):\n" | |
247 " fluid -si -n -f gsm.m0\n" | |
248 "\n" | |
249 "Show both the image and the erase maps:\n" | |
250 " fluid -sis -n -f gsm.m0\n" | |
251 "\n" | |
252 "Download into board without delta download:\n" | |
253 " fluid -C -f gsm.m0\n" | |
254 "\n" | |
255 ); | |
256 break; | |
257 case 'e': | |
258 printf( | |
259 "Erase all flash (including boot sector!):\n" | |
260 " fluid -e+*\n" | |
261 "\n" | |
262 "Erase all flash except the boot sector:\n" | |
263 " fluid -e+*,-0\n" | |
264 "\n" | |
265 "Erase the last megabyte of a 4MB flash device:\n" | |
266 " fluid -e+3M..4M\n" | |
267 "\n" | |
268 "Erase all flash except sectors 1..7 and addresses 1984k..2048k:\n" | |
269 " fluid -e+*,-1..8,-1984k..2048k\n" | |
270 "\n" | |
271 ); | |
272 break; | |
273 case 'r': | |
274 printf( | |
275 "Read whole FFS system from a B-Sample:\n" | |
276 " fluid -r3M..4M -f bsffs.m0\n" | |
277 "\n" | |
278 "Then copy/download it (e.g., to another B-Sample):\n" | |
279 " fluid -f bsffs.m0\n" | |
280 "\n" | |
281 "Read serial switch config from a B- or C-Sample:\n" | |
282 "(serial switch config is in sector 2 on TI releases earlier than SSA-5.3.1)\n" | |
283 " fluid -r0x11ffe..0x12000 -f usxx.m0 -sx\n" | |
284 "\n" | |
285 "Copy it to a(nother) B- or C-sample:\n" | |
286 " fluid -f usxx.m0\n" | |
287 "\n"); | |
288 break; | |
289 case 'w': | |
290 printf( | |
291 "Over-write image with a byte string at a specific address:\n" | |
292 " fluid -f gsm.m0 -w7800=0x11,0x22,0x33,0x44,0x55,0x66\n" | |
293 "\n" | |
294 "Write zeroes into top-most 2MB of C-Sample flash memory:\n" | |
295 " fluid -w2M..4M=0\n" | |
296 "\n" | |
297 "Write a string to a specific address:\n" | |
298 " fluid -w0x1800=\"\"\"Mads\"\"\",0\n" | |
299 "\n"); | |
300 break; | |
301 case 's': | |
302 printf( | |
303 "Reset target, doing nothing else (requires special cable):\n" | |
304 " fluid -n -or\n" | |
305 "\n" | |
306 ); | |
307 break; | |
308 default: | |
309 printf( | |
310 "Avaliable examples:\n" | |
311 " a = Advanced, common usage\n" | |
312 " c = Common usage\n" | |
313 " e = Erase override\n" | |
314 " r = Read target memory\n" | |
315 " w = Write target memory\n" | |
316 " s = Special usage\n" | |
317 ); | |
318 break; | |
319 } | |
320 exit(0); | |
321 } | |
322 | |
323 static void main_debug_usage(void) | |
324 { | |
325 printf("Debug usage: fluid [OPTIONS...]\n" | |
326 "\n" | |
327 " -d r Display target (remote) tracing.\n" | |
328 " -d c Resume fluid state machine in command interpreter.\n" | |
329 " -d o Display final command line option values.\n" | |
330 " -d t<char> Trace mask in human format:\n" | |
331 " a = All, except ?\n" | |
332 " * = All\n" | |
333 " g = getchar()\n" | |
334 " p = putchar()\n" | |
335 " G = target driver receive\n" | |
336 " P = target driver transmit\n" | |
337 " w = target wait\n" | |
338 " t = target/transport layer driver\n" | |
339 " h = hexfile read/decode\n" | |
340 " H = hexfile write/encode\n" | |
341 " r = device file parser\n" | |
342 " c = Command line argument parser\n" | |
343 " u = utility functions\n" | |
344 " m = state machine functions\n" | |
345 " \n" | |
346 " -d v Display info on compiler used.\n" | |
347 " -d f<file> Trace to file.\n" | |
348 " -d i<n> Trace indentation multiplier. Default is 2.\n" | |
349 " -d m<n> Trace mask. Default is 0.\n" | |
350 " -t <char> Trace mask in human format. Same as '-d t<char>'.\n" | |
351 "\n" | |
352 "B-/C-/D-Sample LEDs layout:\n" | |
353 "\n" | |
354 "+---0---+---1---+---2---+---3---+---4---+---5---+---6---+---7---+\n" | |
355 "| Recv | Erase | Prog | Overhd| Idle | | | Busy |\n" | |
356 "+-------+-------+-------+-------+-------+-------+-------+-------+\n" | |
357 ); | |
358 exit(0); | |
359 } | |
360 | |
361 static void main_args_debug_trace(void) | |
362 { | |
363 while (*optarg) { | |
364 switch(*optarg++) { | |
365 case 'a': arg_tr_mask |= TrAll & ~(0); break; | |
366 case '*': arg_tr_mask |= TrAll; break; | |
367 case 'm': arg_tr_mask |= TrMachines; break; | |
368 case 'g': arg_tr_mask |= TrGetChar; break; | |
369 case 'p': arg_tr_mask |= TrPutChar; break; | |
370 case 'G': arg_tr_mask |= TrDriverGet; break; | |
371 case 'P': arg_tr_mask |= TrDriverPut; break; | |
372 case 'w': arg_tr_mask |= TrTargetWait; break; | |
373 case 't': arg_tr_mask |= TrTargetDrv; break; | |
374 case 'h': arg_tr_mask |= TrHexRead; break; | |
375 case 'H': arg_tr_mask |= TrHexWrite; break; | |
376 case 'r': arg_tr_mask |= TrParser; break; | |
377 case 'c': arg_tr_mask |= TrArgParser; break; | |
378 case 'C': arg_tr_mask |= TrCmdLineParser; break; | |
379 case 'u': arg_tr_mask |= TrUtility; break; | |
380 } | |
381 } | |
382 } | |
383 | |
384 static void fluid_welcome(void) | |
385 { | |
386 flowf(NORMAL, | |
387 "FLUID Revision 2.27, (23 Aug 2004). Copyright Texas Instruments, 2001-2004.\n"); | |
388 } | |
389 | |
390 static void fluid_compile_info(void) | |
391 { | |
392 flowf( | |
393 NORMAL, | |
394 "Compiled " __DATE__ " " __TIME__ " with " | |
395 #if defined(MSC) | |
396 "Microsoft cl.exe" | |
397 #elif defined(BCC) | |
398 "Borland bcc" | |
399 #else | |
400 "GNU gcc" | |
401 #endif | |
402 "\n"); | |
403 } | |
404 | |
405 static void main_usage(void) | |
406 { | |
407 printf( | |
408 "Usage: fluid [OPTIONS...]\n" | |
409 "\n"); | |
410 if (!arg_usage) | |
411 fluid_welcome(); | |
412 printf( | |
413 "FLUID is a Flash Loader Utility Independent of Device\n" | |
414 "This version supports:\n" | |
415 " TI GSM Boot Loader V6.x.x (with fluid patch)\n" | |
416 " TI ROM Boot Loader (Calypso devices only)\n" | |
417 "\n" | |
418 " -f <file> Flash image file (input or output file).\n" | |
419 " -p <num> Serial port number. Default is 1.\n" | |
420 " -b <num> Serial baudrate. Default is 115200.\n" | |
421 " -t <char> Target type (Default is auto-detect):\n" | |
422 " h = Hercules\n" | |
423 " u = Ulysses\n" | |
424 " c = Calypso\n" | |
425 " l = Calypso Lite\n" | |
426 " p = Calypso Plus\n" | |
427 " -l List all known flash devices.\n" | |
428 " -c, -C Do or do not checksum target memory thus enabling delta\n" | |
429 " download (only program changed sectors). Default is on.\n" | |
430 " -z, -Z Do or do not compress data on download. Default is on.\n" | |
431 " -g <char> Progress indication type:\n" | |
432 " a = asterisks (default), c = chars, d = dots,\n" | |
433 " x = address+size, n = none\n" | |
434 " -e [+|-]<addr0>..<addr1>,... or [+|-]<n>,...<\n" | |
435 " Erase/program override. Erase or don't erase flash\n" | |
436 " memory in the range [addr0..addr1[. Use '-ie' to see\n" | |
437 " examples of usage\n" | |
438 " -<...> = do *not* erase and program\n" | |
439 " +<...> = force erase\n" | |
440 " Giving <n> as an asterisk, '*', means all sectors\n" | |
441 " -r <addr0>..<addr1>,...\n" | |
442 " Read target memory range [addr0..addr1[ and write the\n" | |
443 " bytes to output file specified.\n" | |
444 " -w <addr0>..<addr1>=<b0,b1,...,bN>:...\n" | |
445 " Write bytes to image. The bytes b0..bN are replicated\n" | |
446 " through the whole memory range [addr0..addr1[\n" | |
447 " -o <char> Extra options:\n" | |
448 " o = Only bootstrap using ROM boot loader (Calypso devices only)\n" | |
449 " O = Do NOT use ROM boot loader\n" | |
450 " e = Skip erase (Require empty flash)\n" | |
451 " r = Reset target after download (default)\n" | |
452 " R = Do NOT reset target after download\n" | |
453 " l = Activate (old-fashioned) UART level conversion\n" | |
454 " m = Select Motorola hexfile output format (default)\n" | |
455 " b = Select binary/raw file output format\n" | |
456 " i<n1>,<n2> = Disable device auto-detection and set manufacturer\n" | |
457 " id and device id\n" | |
458 " d<n1>,<n2> = Set detection delay (in ms) for ROM and fluid boot\n" | |
459 " loader, respectively\n" | |
460 " 1, 2, 4 = Select hexfile memory width 1, 2 or 4. Default is 2\n" | |
461 " -s <char> Show additional info:\n" | |
462 " i = image map\n" | |
463 " s = sector erase map\n" | |
464 " l = sector erase list\n" | |
465 " t = target timers, T = extended target timer info\n" | |
466 " x = hexdump of target memory (together with '-r')\n" | |
467 " c = checksums\n" | |
468 " -n Dry run. Do not program the flash device.\n" | |
469 " -v Be verbose. Multiple '-v's means more verbosity.\n" | |
470 " -q Be quiet.\n" | |
471 // " -y Use stdout for error messages.\n" | |
472 " -dh Display help on debug and trace options.\n" | |
473 " -h Display this help.\n" | |
474 " -i <char> Display examples (i = index/overview of examples).\n" | |
475 // Secure Calypso Plus | |
476 "\n Secure Calypso Plus options:\n" | |
477 " -I <char> IMEI protection options:\n" | |
478 " d <file> = Retrieve die id from target and write to <file>.\n" | |
479 " n <num> = 16 digits representing the IMEI-SV, [8 TAC]+[6 SNR]+\n" | |
480 " [2 SVN], which is used for non-secure E-samples or\n" | |
481 " secure E-samples when the die id is not added to the\n" | |
482 " DIE_ID field of the manufacturer certificate.\n" | |
483 " a <addr> = Address of the platform certificate stored in flash.\n" | |
484 " -R Request firmware certificate.\n" | |
485 " -D <num> Insert a delay before detection of flash type. This delay is used\n" | |
486 " for changing the memory mapping on CS5 due to a bug in ROM code\n" | |
487 " 0x0410 (see SECURITY.txt) or for connecting to target via JTAG.\n" | |
488 " -U <num> UART baudrate during flash programmer download. Default is 115200.\n" | |
489 " -u <num> UART timeout configuration. Default is 0.\n" | |
490 " -B <num> Block size. Must be a modulus of 64 bytes. Default is %d bytes.\n", arg_block_size | |
491 // End Secure Calypso Plus | |
492 ); | |
493 } | |
494 | |
495 static void main_args(int argc, char *argv[]) | |
496 { | |
497 char ch; | |
498 int i; | |
499 // IMEI Protection | |
500 char d_i, d_digit; | |
501 char a_imeisv_format[] = "The IMEI-SV must consist of 16 digits in compliance with the following format:\n[8 TAC]+[6 SNR]+[2 SVN]\n"; | |
502 | |
503 if (argc == 1) { | |
504 fluid_welcome(); | |
505 main_help(); | |
506 exit(0); | |
507 } | |
508 | |
509 for (i = argc - 1; i >= 0; i--) { | |
510 // TODO?: scan for filenames. | |
511 } | |
512 | |
513 while ((ch = getopt(argc, argv, | |
514 "f:p:b:cCzZjJt:e:s:r:w:nlqg:o:vkd:i:hVyI:RD:U:u:B:")) != -1) | |
515 { | |
516 switch (ch) | |
517 { | |
518 case 'f': | |
519 if (arg_file_list_size < ARG_FILE_LIST_SIZE_MAX - 1) | |
520 arg_file_list[arg_file_list_size++] = optarg; | |
521 arg_file_list[arg_file_list_size] = NULL; | |
522 break; | |
523 case 'p': | |
524 arg_uart_port = arg_long_get(); | |
525 if (arg_uart_port < 1 || 24 < arg_uart_port) | |
526 main_error(E_BADARG); | |
527 break; | |
528 case 'b': | |
529 arg_uart_baudrate = arg_long_get(); | |
530 arg_uart_baudrate = serial_is_baudrate(arg_uart_baudrate); | |
531 if (arg_uart_baudrate == 0) | |
532 main_error(E_BADARG); | |
533 break; | |
534 case 't': | |
535 arg_target_type = *optarg; | |
536 break; | |
537 case 'c': arg_checksum = 1; break; | |
538 case 'C': arg_checksum = 0; break; | |
539 case 'z': arg_compress = 1; break; | |
540 case 'Z': arg_compress = 0; break; | |
541 case 'e': | |
542 if (*arg_erase_override != 0) | |
543 main_error(E_ARG_MULTI); | |
544 arg_erase_override = optarg; | |
545 break; | |
546 case 's': | |
547 while (*optarg) { | |
548 switch(*optarg++) { | |
549 case 'i': arg_image_map_show++; break; | |
550 case 's': arg_sector_map_show++; break; | |
551 case 'l': arg_sector_list_show++; break; | |
552 case 't': arg_timers_show++; break; | |
553 case 'T': arg_timers_extended_show++; break; | |
554 case 'c': arg_checksum_show++; break; | |
555 case 'x': arg_show_hexdump++; break; | |
556 } | |
557 } | |
558 break; | |
559 case 'r': | |
560 if (*arg_read != 0) | |
561 main_error(E_ARG_MULTI); | |
562 arg_read = optarg; | |
563 break; | |
564 case 'w': | |
565 if (*arg_write != 0) | |
566 main_error(E_ARG_MULTI); | |
567 arg_write = optarg; | |
568 break; | |
569 case 'l': arg_list_devices = 1; break; | |
570 case 'n': arg_dry_run++; break; | |
571 case 'k': arg_keep_going = 1; break; | |
572 case 'v': arg_verbose++; break; | |
573 case 'q': arg_verbose--; break; | |
574 case 'g': | |
575 if (*optarg != 'a' && | |
576 *optarg != 'c' && | |
577 *optarg != 'd' && | |
578 *optarg != 'x' && | |
579 *optarg != 'n') | |
580 main_error(E_BADARG); | |
581 arg_progress = *optarg; | |
582 break; | |
583 case 'o': | |
584 while (*optarg) { | |
585 tr(TrCmdLineParser, "main_args(): -o%s", optarg); | |
586 switch (*optarg) { | |
587 case 'e': arg_skip_erase = 1; break; | |
588 case 'R': arg_target_reset = 0; break; | |
589 case 'r': arg_target_reset = 2; break; | |
590 case 'o': arg_rom_bootloader = 1; break; | |
591 case 'O': arg_rom_bootloader = -1; break; | |
592 case 'l': arg_uart_level_convert = 1; break; | |
593 case 'b': | |
594 case 'm': arg_hexfile_type = *optarg; break; | |
595 case 'i': | |
596 optarg++; | |
597 arg_device_id0 = arg_long_get(); | |
598 if (*optarg == ',') { | |
599 optarg++; | |
600 arg_device_id1 = arg_long_get(); | |
601 } | |
602 else { | |
603 fprintf(stderr, "arg: '%s'", optarg); | |
604 main_error(E_BADARG); | |
605 } | |
606 optarg--; | |
607 break; | |
608 case 'd': | |
609 optarg++; | |
610 arg_boot_delay_rom = arg_long_get(); | |
611 if (*optarg == ',') { | |
612 optarg++; | |
613 arg_boot_delay_fluid = arg_long_get(); | |
614 } | |
615 else if (*optarg == 0) | |
616 arg_boot_delay_fluid = arg_boot_delay_rom; | |
617 else { | |
618 fprintf(stderr, "arg: '%s'", optarg); | |
619 main_error(E_BADARG); | |
620 } | |
621 optarg--; | |
622 break; | |
623 case '1': | |
624 case '2': | |
625 case '4': | |
626 arg_hexfile_memwidth = *optarg - '0'; | |
627 break; | |
628 default: | |
629 main_error(E_BADARG); | |
630 } | |
631 tr(TrCmdLineParser, "\n"); | |
632 optarg++; | |
633 } | |
634 break; | |
635 case 'd': | |
636 while (*optarg) { | |
637 switch (*optarg++) { | |
638 case 'h': main_debug_usage(); break; | |
639 case 'c': arg_debug_resume = 1; break; | |
640 case 'p': arg_debug_trace_pe = 1; break; | |
641 case 'r': arg_target_trace_enable = 1; break; | |
642 case 'o': arg_show_main_args = 1; break; | |
643 case 't': main_args_debug_trace(); break; | |
644 case 'v': fluid_compile_info(); exit(0); break; | |
645 case 'f': arg_tr_file = optarg; optarg += strlen(optarg); break; | |
646 case 'm': arg_tr_mask = arg_long_get(); break; | |
647 case 'i': arg_tr_spaces = arg_long_get(); break; | |
648 default: | |
649 main_error(E_BADARG); | |
650 } | |
651 } | |
652 optarg++; | |
653 break; | |
654 case 'i': main_example(*optarg); break; | |
655 case 'h': arg_usage = 1; break; | |
656 case 'V': fluid_welcome(); exit(0); | |
657 case 'y': arg_errorfd = 1; break; | |
658 // IMEI Protection | |
659 case 'I': | |
660 switch (*optarg++) { | |
661 case 'd': | |
662 if (*arg_die_id_file_name != 0) | |
663 main_error(E_ARG_MULTI); | |
664 if (*optarg == 0) | |
665 optarg++; | |
666 arg_die_id_file_name = optarg; | |
667 break; | |
668 case 'n': | |
669 if (*arg_imeisv != 0) | |
670 main_error(E_ARG_MULTI); | |
671 if (*optarg == 0) | |
672 optarg++; | |
673 arg_imeisv = optarg; | |
674 if (strlen(arg_imeisv) != C_IMEISV_DIGITS) { | |
675 fprintf(stderr, a_imeisv_format); | |
676 main_error(E_BADARG); | |
677 } | |
678 for (d_i = 0; d_i < C_IMEISV_DIGITS; d_i++) { | |
679 sscanf(arg_imeisv++, "%1c", &d_digit); | |
680 if (d_digit < '0' ||d_digit > '9') { | |
681 fprintf(stderr, a_imeisv_format); | |
682 main_error(E_BADARG); | |
683 } | |
684 } | |
685 arg_imeisv = optarg; // Re-assign arg_imeisv after error check | |
686 break; | |
687 case 'a': | |
688 if (*arg_platform_certificate_addr != 0) | |
689 main_error(E_ARG_MULTI); | |
690 if (*optarg == 0) | |
691 optarg++; | |
692 arg_platform_certificate_addr = optarg; | |
693 if ((strlen(arg_platform_certificate_addr) == C_PLATFORM_CERT_ADDR_DIGITS + 2) && | |
694 (arg_platform_certificate_addr[0] == '0') && | |
695 (arg_platform_certificate_addr[1] == 'x')) | |
696 arg_platform_certificate_addr += 2; | |
697 else if (strlen(arg_platform_certificate_addr) != C_PLATFORM_CERT_ADDR_DIGITS) { | |
698 fprintf(stderr, "The platform certificate address must comply with the following format, e.g.,\n0x04650000\n"); | |
699 main_error(E_BADARG); | |
700 } | |
701 break; | |
702 default: | |
703 main_error(E_BADARG); | |
704 } | |
705 break; | |
706 // Secure Calypso Plus | |
707 case 'R': | |
708 arg_request_certificate = 1; | |
709 d_ram_loader.b_certificate_request = C_TRUE; | |
710 break; | |
711 case 'D': | |
712 arg_delay_for_changing_cs5 = arg_long_get(); | |
713 if (arg_delay_for_changing_cs5 < 0) | |
714 main_error(E_BADARG); | |
715 break; | |
716 case 'U': | |
717 arg_uart_baudrate_during_cmd_download = arg_long_get(); | |
718 if (arg_uart_baudrate_during_cmd_download < 0) | |
719 main_error(E_BADARG); | |
720 break; | |
721 case 'u': | |
722 arg_uart_timeout_configuration = arg_long_get(); | |
723 d_ram_loader.d_uart_timeout = (UWORD32) arg_uart_timeout_configuration; | |
724 if (d_ram_loader.d_uart_timeout < 0) | |
725 main_error(E_BADARG); | |
726 break; | |
727 case 'B': | |
728 arg_block_size = arg_long_get(); | |
729 d_ram_loader.d_nb_byte_in_block = (UWORD32) arg_block_size; | |
730 if (d_ram_loader.d_nb_byte_in_block < 1) | |
731 main_error(E_BADARG); | |
732 break; | |
733 // End Secure Calypso Plus | |
734 default: | |
735 main_usage(); | |
736 exit(-E_BADARG); | |
737 } | |
738 } | |
739 | |
740 if (arg_usage) { | |
741 main_usage(); | |
742 exit(0); | |
743 } | |
744 | |
745 if (arg_show_main_args) { | |
746 printf("Command line option values:\n"); | |
747 printf("argv[0] = '%s'\n", argv[0]); | |
748 printf("\n"); | |
749 printf("port = %d\n", arg_uart_port); | |
750 printf("baudrate = %d\n", arg_uart_baudrate); | |
751 | |
752 printf("target_trace_enable = %d\n", arg_target_trace_enable); | |
753 printf("\n"); | |
754 } | |
755 | |
756 } | |
757 | |
758 static long arg_long_get(void) | |
759 { | |
760 long value; | |
761 char *endp; | |
762 | |
763 errno = 0; | |
764 value = strtol(optarg, &endp, 0); | |
765 | |
766 if (errno == ERANGE || endp == optarg) { | |
767 fprintf(stderr, "Invalid command line number argument: '%s'", optarg); | |
768 exit(1); | |
769 } | |
770 optarg = endp; | |
771 return value; | |
772 } | |
773 | |
774 | |
775 /****************************************************************************** | |
776 * Globals and Main | |
777 ******************************************************************************/ | |
778 | |
779 int flowf(int level, char *format, ...) | |
780 { | |
781 int n = 0; | |
782 va_list args; | |
783 char buf[1024]; | |
784 | |
785 if (level <= arg_verbose) { | |
786 va_start(args, format); | |
787 vsprintf(buf, format, args); | |
788 | |
789 n = fprintf(stdout, "%s", buf); | |
790 } | |
791 fflush(stdout); | |
792 | |
793 return n; | |
794 } | |
795 | |
796 int main(int argc, char *argv[]) | |
797 { | |
798 int error; | |
799 | |
800 file_read_rc(".fluidrc"); | |
801 | |
802 main_args(argc, argv); | |
803 argv_0 = argv[0]; | |
804 | |
805 if (arg_verbose >= NORMAL) | |
806 fluid_welcome(); | |
807 | |
808 // Init tracing library | |
809 tr_init(arg_tr_spaces, arg_tr_file); | |
810 tr_mask(TrMAIN | arg_tr_mask); | |
811 | |
812 error = fluid_machine(); | |
813 | |
814 if (error < 0) | |
815 main_error(error); | |
816 | |
817 exit(-error); | |
818 } |