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 }