add initial support for the crisarchitecture used on foxboards to openwrt
[openwrt/staging/dedeckeh.git] / target / linux / etrax-2.6 / image / e100boot / src / sbl / win32 / common.c
1 /*!***************************************************************************
2 *!
3 *! FILE NAME : common.c
4 *!
5 *! DESCRIPTION: Common functions for e100boot.
6 *!
7 *! ---------------------------------------------------------------------------
8 *! HISTORY
9 *!
10 *! DATE NAME CHANGES
11 *! ---- ---- -------
12 *! ??? ? ???? Ronny Ranerup Initial version
13 *! ---------------------------------------------------------------------------
14 *! (C) Copyright 1999-2003 Axis Communications AB, LUND, SWEDEN
15 *!***************************************************************************/
16 /* $Id: common.c,v 1.1 2004/01/26 10:52:40 mikaelp Exp $ */
17
18 /************************** Version **************************************/
19
20 char version[] = "Time-stamp: $Id: common.c,v 1.1 2004/01/26 10:52:40 mikaelp Exp $";
21
22 /************************** Include files ********************************/
23
24 #define WIN32_LEAN_AND_MEAN
25 #include <windows.h>
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <io.h>
31 #include <winsock2.h>
32
33 #include <e100boot.h>
34 #include <pcap.h>
35 #include "boot_images.h"
36 #include <reg_des.h>
37 #include <sv_addr_ag.h>
38 #include <common.h>
39
40 #include <serial.h>
41 #include <network.h>
42
43 /************************** Constants and macros *************************/
44
45 #define BOOT_CMDS_FILE "BOOT_CMDS"
46
47 /************************** Type definitions *****************************/
48
49 struct label_t {
50 struct label_t *prev;
51 udword addr;
52 char *name;
53 };
54
55 /************************** Global variables *****************************/
56
57 char needle[MAX_STRING_LEN] = "END"; /* search needle for --find */
58 int needle_len = 3;
59
60 int exitonfind = FALSE;
61
62 int doing_flash = FALSE; /* Just a flag to see if we should
63 warn that it might take some
64 time. */
65
66 int toFiles = FALSE; /* Dump all packets to files. */
67 int cmdsOnly = FALSE; /* Just dump boot cmds to file. */
68 int netBoot = TRUE; /* Do network boot? */
69 int serBoot = FALSE; /* Do serial boot? */
70
71 struct label_t *loop_label = NULL;
72 struct label_t *label = NULL;
73
74 struct packet_buf *first_packet = NULL;
75 struct packet_buf *last_packet = NULL;
76
77 struct packet_buf *boot_cmds_packet;
78
79 int create_boot_loader = TRUE;
80
81 /* We use the INTERNAL boot image as default */
82 char boot_loader_file[MAX_STRING_LEN] = INTERNAL_NW;
83
84 int noleds = FALSE; /* Use boot images that doesn't toggle leds? */
85
86 struct boot_files_T *first_boot_file = NULL;
87 struct boot_files_T *last_boot_file = NULL;
88
89 unsigned int boot_cmds[SIZE_OF_BOOT_CMDS / sizeof(unsigned int)];
90 int boot_cmds_cnt = 0;
91
92 int svboot = FALSE;
93
94 int quiet = 0;
95
96 struct packet_header_T send_packet;
97 struct packet_header_T *receive_packet;
98
99 int seq_nr = 0;
100
101 /* debug flags */
102 int db1 = FALSE;
103 int db2 = FALSE;
104 int db3 = FALSE;
105 int db4 = FALSE;
106
107 char device[MAX_STRING_LEN] = "";
108
109
110 /************************** Function prototypes **************************/
111
112 FILE *Fopen (const char *name, const char *mode);
113 int main (int argc, const char *argv[]);
114 int GetNumberOption (int *argNr, int argCount, const char *argVect[], unsigned int *ret, const char *option, int base);
115 int GetStringOption (int *argNr, int argCount, const char *argVect[], char *ret, const char *option);
116 int GetRegisterOption (int *argNr, int argCount, const char *argVect[], unsigned int *ret, const char *option, int base);
117 struct boot_files_T* allocate_boot_file (struct boot_files_T *bf);
118 struct packet_buf* CreateNewBootPacket (void);
119 struct packet_buf* allocate_packet (struct packet_buf *p);
120 void SigHandler (int sig);
121 void CreateBootLoader (void);
122 void FinishBootCmds (void);
123 void ParseArgs (int argc, const char *argv[]);
124 void PrintHelp (void);
125 void CreateBootCmds (void);
126 void handle_labels (void);
127 void new_label (struct label_t **label, udword addr, const char *name);
128
129 /****************************************************************************
130 *#
131 *# FUNCTION NAME: main
132 *#
133 *# PARAMETERS: Command line arguments.
134 *#
135 *#---------------------------------------------------------------------------
136 *# HISTORY
137 *#
138 *# DATE NAME CHANGES
139 *# ---- ---- -------
140 *# 961022 ronny Initial version
141 *#
142 *#***************************************************************************/
143
144 int
145 main(int argc, const char *argv[])
146 {
147 ParseArgs(argc, argv);
148
149 if (cmdsOnly) {
150 /* We make this a special case to avoid messing up other code. */
151 CreateBootCmds();
152 FinishBootCmds();
153 SendToDevice(&boot_cmds_packet->data[SIZE_OF_HEADER],SIZE_OF_BOOT_CMDS);
154 exit(EXIT_SUCCESS);
155 }
156
157 if (netBoot && !toFiles) {
158 /* Do not bother with this if we just want to write the packets to
159 files. Means you do not have to be root to run --tofiles. */
160 net_init();
161 }
162 else if (serBoot) {
163 /*if (!SetupSerial())*/ {
164 exit(0);
165 }
166 }
167
168 CreateBootLoader();
169 CreateBootCmds();
170 FinishBootCmds();
171
172 printf("Starting boot...\n");
173 if (doing_flash) {
174 printf("We're doing a flash write, this may take up to a few minutes...\n");
175 }
176
177 if (toFiles) {
178 udword seq = 0;
179 struct packet_buf *p;
180
181 while((p = create_packet(seq++))) {
182 SendToDevice(p->data, p->size);
183 }
184
185 exit(EXIT_SUCCESS);
186 }
187
188 if (netBoot) {
189 NetBoot();
190 }
191 else if (serBoot) {
192 /*SerBoot();*/
193 }
194
195 printf("Done.\n");
196 return EXIT_SUCCESS;
197 } /* main */
198
199 /****************************************************************************
200 *#
201 *# FUNCTION NAME: free_packet
202 *#
203 *# PARAMETERS: struct to free
204 *#
205 *# DESCRIPTION: Frees struct and data in struct.
206 *#
207 *# RETURNS: Pointer to next struct.
208 *#
209 *#---------------------------------------------------------------------------
210 *# HISTORY
211 *#
212 *# DATE NAME CHANGES
213 *# ---- ---- -------
214 *# 2000 02 07 ronny Initial version
215 *#
216 *#***************************************************************************/
217
218 struct packet_buf*
219 free_packet(struct packet_buf *p)
220 {
221 struct packet_buf *next_p;
222
223 next_p = p->next;
224 free(p->data);
225 free(p);
226 return(next_p);
227 }
228
229 /****************************************************************************
230 *#
231 *# FUNCTION NAME: create_packet
232 *#
233 *# PARAMETERS: Sequence number of desired packet.
234 *#
235 *# DESCRIPTION:
236 *#
237 *#---------------------------------------------------------------------------
238 *# HISTORY
239 *#
240 *# DATE NAME CHANGES
241 *# ---- ---- -------
242 *# 2000 06 28 ronny Initial version
243 *#
244 *#***************************************************************************/
245
246 struct packet_buf*
247 create_packet(udword seq)
248 {
249 struct packet_buf *p = first_packet;
250 /* Should check last first? */
251
252 if (db4) printf("> create_packet seq %d\n", seq);
253
254 while (p) {
255 if (p->seq == seq) {
256 return(p);
257 }
258 p = p->next;
259 }
260
261 return(CreateNewBootPacket());
262 }
263
264 /****************************************************************************
265 *#
266 *# FUNCTION NAME: find_string
267 *#
268 *# PARAMETERS: New string to search.
269 *#
270 *# DESCRIPTION: Searches a number of strings for needle[], including strings
271 *# overlapping between different calls.
272 *#
273 *#---------------------------------------------------------------------------
274 *# HISTORY
275 *#
276 *# DATE NAME CHANGES
277 *# ---- ---- -------
278 *# 020502 ronny Initial version
279 *#
280 *#***************************************************************************/
281
282 void
283 find_string(char *str)
284 {
285 static int matched = 0;
286 int hs[MAX_STRING_LEN];
287 static int cur_hs = 0;
288 static int hs_len = 0;
289 static int last_hs = 0;
290
291 static int cur_needle = 0;
292
293 if (!needle[0]) {
294 return;
295 }
296 // printf("# adding >%s<\n", str);
297
298 {
299 int c = 0;
300 int s = 0;
301
302 while((c = str[s])) {
303 // printf("\n# cur_hs %d, hs_len %d\n", cur_hs, hs_len);
304 {
305 int i;
306
307 for(i = 0; i != hs_len; i++) {
308 // printf("hs[%d] = %d(%c)\n", i, (int)hs[i], hs[i] < 32 ? 'X' : hs[i]);
309 }
310 }
311
312 if (cur_hs == hs_len) {
313 // printf("adding char %d(%c) at hs[%d]\n", (int)c, c < 32 ? 'X' : c, hs_len);
314 hs[hs_len] = c;
315 hs_len++;
316 s++;
317 }
318
319 // printf("testing %d at cur_hs %d against %d at cur_needle %d\n",
320 // (int)hs[cur_hs], cur_hs, (int)needle[cur_needle], cur_needle);
321
322 if (hs[cur_hs] == needle[cur_needle]) {
323 if (cur_needle+1 == needle_len) {
324 int exitcode = EXIT_SUCCESS;
325
326 // printf("\nFound needle from --find option.\n");
327 if (exitonfind) {
328 int ret;
329 // printf("scanf (s=%d)'%s'\n", s, &str[s+1]);
330 ret = sscanf(&str[s+1], "%i", &exitcode);
331 // printf("ret %d, '%s'\n", ret, &str[s+1]);
332 }
333 printf("Exiting with code %d\n", exitcode);
334 exit(exitcode);
335 }
336 cur_needle++;
337 cur_hs++;
338 }
339 else {
340 // printf("no match, shifting hs.\n");
341 {
342 int i;
343 for(i=0; i!= hs_len-1; i++) {
344 hs[i] = hs[i+1];
345 }
346 }
347 hs_len--;
348 cur_needle = 0;
349 cur_hs = 0;
350 }
351 }
352 }
353 }
354
355 /****************************************************************************
356 *#
357 *# FUNCTION NAME: Fopen
358 *#
359 *# PARAMETERS: Name and mode, both strings.
360 *#
361 *# DESCRIPTION: Opens a file and returns its fd, or NULL.
362 *#
363 *#---------------------------------------------------------------------------
364 *# HISTORY
365 *#
366 *# DATE NAME CHANGES
367 *# ---- ---- -------
368 *# 961022 ronny Initial version
369 *#
370 *#***************************************************************************/
371
372 FILE *
373 Fopen(const char *name, const char *mode)
374 {
375 FILE *fd;
376
377 if (db2) printf(">>> Fopen '%s', mode '%s'\n", name, mode);
378
379 fd = fopen(name, mode);
380
381 if (fd == NULL) {
382 printf("<<< Fopen failed on '%s', mode '%s'\n", name, mode);
383 return ((FILE*) NULL);
384 }
385
386 if (strncmp(mode, "a", 1) == 0) {
387 if (db3) printf("* Append mode, seeking to end.\n");
388 fseek(fd, 0L, SEEK_SET);
389 }
390
391 if (db2) printf("<<< Fopen: '%s'\n", name);
392
393 return(fd);
394 }
395
396 /****************************************************************************
397 *#
398 *# FUNCTION NAME: ParseArgs
399 *#
400 *# PARAMETERS: Standard command line args.
401 *#
402 *# DESCRIPTION: Parses command line arguments.
403 *#
404 *#---------------------------------------------------------------------------
405 *# HISTORY
406 *#
407 *# DATE NAME CHANGES
408 *# ---- ---- -------
409 *# 960909 ronny Initial version
410 *#***************************************************************************/
411
412 void
413 ParseArgs (int argc, const char *argv[])
414 {
415 int argi;
416 int i;
417 int printHelp = FALSE;
418 int exitCode = EXIT_SUCCESS;
419 char dbStr[MAX_STRING_LEN]; /* Debug option string. */
420 int number;
421 int argCount;
422 const char **argVect;
423 struct stat st;
424
425 if (db4) printf(">>> ParseArgs\n");
426 argCount = argc;
427 argVect = argv;
428
429 for (argi = 1; argi < argCount; argi++) {
430 if (db4) printf("argv[%d] = '%s'\n", argi, argVect[argi]);
431 if (strncmp(argVect[argi], "--from", 6) == 0) {
432 if (GetStringOption(&argi, argCount, argVect, host1, "--from") == 0) {
433 printHelp = TRUE;
434 exitCode = EXIT_FAILURE;
435 }
436 else {
437 printf("Host: %s %s\n", host1, host2);
438 if (sscanf(host1, "%x-%x-%x-%x-%x-%x", &i, &i, &i, &i, &i, &i) == 6) {
439 printf("Ethernet address\n");
440 }
441 }
442 }
443
444 else if (strncmp(argVect[argi], "--device", 8) == 0) {
445 if (GetStringOption(&argi, argCount, argVect, device, "--device") == 0) {
446 printHelp = TRUE;
447 exitCode = EXIT_FAILURE;
448 }
449 }
450
451 else if (strncmp(argVect[argi], "--network", 9) == 0) {
452 netBoot = TRUE;
453 serBoot = FALSE;
454 strcpy(boot_loader_file, INTERNAL_NW);
455 }
456
457 else if (strncmp(argVect[argi], "--serial", 8) == 0) {
458 serBoot = TRUE;
459 netBoot = FALSE;
460 strcpy(device, "/dev/ttyS0");
461 strcpy(boot_loader_file, INTERNAL_SER);
462 }
463
464 else if (strncmp(argVect[argi], "--noleds", 8) == 0) {
465 noleds = TRUE;
466 }
467
468 else if (strncmp(argVect[argi], "--images", 8) == 0) {
469 int i = 0;
470
471 printf("Internal images:\n");
472
473 while(boot_image_info[i].name) {
474 printf("'%s', %s, size %lu bytes.\n",
475 boot_image_info[i].name,
476 boot_image_info[i].info,
477 boot_image_info[i].len
478 );
479 i++;
480 }
481 exit(EXIT_SUCCESS);
482 }
483
484 else if (strncmp(argv[argi], "--baudrate", 10) == 0) {
485 /* if (GetNumberOption (&argi, argCount, argVect, &set_baudrate, "--baudrate", 10) == 0)*/ {
486 printHelp = TRUE;
487 exitCode = EXIT_FAILURE;
488 }
489 }
490
491 else if (strncmp(argVect[argi], "--tofiles", 9) == 0) {
492 toFiles = TRUE;
493 }
494
495 else if (strncmp(argVect[argi], "--cmdsonly", 10) == 0) {
496 cmdsOnly = TRUE;
497 }
498
499 else if (strncmp(argVect[argi], "--to", 4) == 0) {
500 if ((GetStringOption(&argi, argCount, argVect, host2, "--to") == 0)) {
501 printHelp = TRUE;
502 exitCode = EXIT_FAILURE;
503 }
504 else {
505 printf("Host: %s %s\n", host1, host2);
506 both_addresses = TRUE;
507 if (sscanf(host2, "%x-%x-%x-%x-%x-%x", &i, &i, &i, &i, &i, &i) == 6) {
508 printf("Ethernet address\n");
509 }
510 }
511 }
512
513 else if (strncmp(argVect[argi], "--printp", 8) == 0) {
514 pPacket = 1;
515 }
516
517 else if (strncmp(argVect[argi], "--printascii", 11) == 0) {
518 pPacket = 1;
519 printPacketType = ASCII;
520 }
521
522 else if (strncmp(argVect[argi], "--printudec", 11) == 0) {
523 pPacket = 1;
524 printPacketType = UDEC;
525 }
526
527 else if (strncmp(argVect[argi], "--printhex", 10) == 0) {
528 pPacket = 1;
529 printPacketType = HEX;
530 }
531
532 else if (strncmp(argVect[argi], "--bpl", 5) == 0) {
533 if (GetNumberOption(&argi, argCount, argVect, &p_packet_bpl, "--bpl", 10) == 0) {
534 printHelp = TRUE;
535 exitCode = EXIT_FAILURE;
536 }
537 }
538
539 else if (strncmp(argVect[argi], "--promisc", 11) == 0) {
540 promisc = 1;
541 }
542
543 else if (strncmp(argVect[argi], "--5400", 6) == 0) {
544 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
545 boot_cmds[boot_cmds_cnt++] = 0xb0000000;
546 boot_cmds[boot_cmds_cnt++] = 0x000095b6;
547 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
548 boot_cmds[boot_cmds_cnt++] = 0xb0000008;
549 boot_cmds[boot_cmds_cnt++] = 0x0000e751;
550 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
551 boot_cmds[boot_cmds_cnt++] = 0xb000000c;
552 boot_cmds[boot_cmds_cnt++] = 0x12604040;
553 }
554
555 else if (strncmp(argVect[argi], "--5600", 6) == 0) {
556 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
557 boot_cmds[boot_cmds_cnt++] = 0xb0000000;
558 boot_cmds[boot_cmds_cnt++] = 0x000095b6;
559 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
560 boot_cmds[boot_cmds_cnt++] = 0xb0000008;
561 boot_cmds[boot_cmds_cnt++] = 0x00006751;
562 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
563 boot_cmds[boot_cmds_cnt++] = 0xb000000c;
564 boot_cmds[boot_cmds_cnt++] = 0x12204040;
565 }
566
567 else if (strncmp(argVect[argi], "--testcardlx", 12) == 0) {
568 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
569 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_DRAM_CONFIG;
570 boot_cmds[boot_cmds_cnt++] = 0x12604040;
571 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
572 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_DRAM_TIMING;
573 boot_cmds[boot_cmds_cnt++] = 0x0000e751;
574 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
575 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_WAITSTATES;
576 boot_cmds[boot_cmds_cnt++] = 0x00b395b5;
577 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
578 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_BUS_CONFIG;
579 boot_cmds[boot_cmds_cnt++] = 0x00000207;
580 }
581
582 else if (strncmp(argVect[argi], "--testcard", 10) == 0) {
583 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
584 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_WAITSTATES;
585 boot_cmds[boot_cmds_cnt++] = 0x000010b3;
586 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
587 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_DRAM_TIMING;
588 boot_cmds[boot_cmds_cnt++] = 0x00006543;
589 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
590 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_DRAM_CONFIG;
591 boot_cmds[boot_cmds_cnt++] = 0x12966060;
592 }
593
594 else if (strncmp(argVect[argi], "--devboard", 10) == 0) {
595 /* Printing on serial port will not work until PORT_PB is set... */
596 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
597 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_PORT_PB_SET;
598 boot_cmds[boot_cmds_cnt++] = 0x01001ef3;
599 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
600 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_PORT_PA_SET;
601 boot_cmds[boot_cmds_cnt++] = 0x00001df0;
602 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
603 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_WAITSTATES;
604 boot_cmds[boot_cmds_cnt++] = 0x000095a6;
605 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
606 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_DRAM_CONFIG;
607 boot_cmds[boot_cmds_cnt++] = 0x1a200040;
608 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
609 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_DRAM_TIMING;
610 boot_cmds[boot_cmds_cnt++] = 0x00005611;
611 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
612 boot_cmds[boot_cmds_cnt++] = (unsigned int)R_BUS_CONFIG;
613 boot_cmds[boot_cmds_cnt++] = 0x00000104;
614 }
615
616 else if (strncmp(argVect[argi], "--verify", 8) == 0) {
617 boot_cmds[boot_cmds_cnt++] = MEM_VERIFY;
618 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--verify", 16);
619 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--verify", 16);
620 }
621
622 else if (strncmp(argVect[argi], "--setreg", 8) == 0) {
623 boot_cmds[boot_cmds_cnt++] = SET_REGISTER;
624 if ((argVect[argi+1][0] >= 'A') && (argVect[argi+1][0] <= 'Z')) {
625 GetRegisterOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--setreg", 16);
626 }
627 else {
628 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--setreg", 16);
629 }
630 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--setreg", 16);
631 }
632
633 else if (strncmp(argVect[argi], "--getreg", 8) == 0) {
634 boot_cmds[boot_cmds_cnt++] = GET_REGISTER;
635 if ((argVect[argi+1][0] >= 'A') && (argVect[argi+1][0] <= 'Z')) {
636 GetRegisterOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--getreg", 16);
637 }
638 else {
639 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--getreg", 16);
640 }
641 }
642
643 else if (strncmp(argVect[argi], "--pause", 7) == 0) {
644 boot_cmds[boot_cmds_cnt++] = PAUSE_LOOP;
645 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--pause", 16);
646 }
647
648 else if (strncmp(argVect[argi], "--memtest", 9) == 0) {
649 boot_cmds[boot_cmds_cnt++] = MEM_TEST;
650 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memtest", 16);
651 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memtest", 16);
652 }
653
654 else if (strncmp(argVect[argi], "--loop", 6) == 0) {
655 char str[MAX_STRING_LEN];
656 boot_cmds[boot_cmds_cnt++] = LOOP;
657 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--loop", 16);
658 GetStringOption(&argi, argCount, argVect, str, argVect[argi]);
659 new_label(&loop_label, boot_cmds_cnt+1, str);
660 boot_cmds_cnt++;
661 }
662
663 else if (strncmp(argVect[argi], "--label", 7) == 0) {
664 char str[MAX_STRING_LEN];
665 GetStringOption(&argi, argCount, argVect, str, "--label");
666 new_label(&label, boot_cmds_cnt, str);
667 }
668
669 else if (strncmp(argVect[argi], "--memdump", 9) == 0) {
670 boot_cmds[boot_cmds_cnt++] = MEM_DUMP;
671 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memdump", 16);
672 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memdump", 16);
673 }
674
675 else if (strncmp(argVect[argi], "--memclear", 10) == 0) {
676 boot_cmds[boot_cmds_cnt++] = MEM_CLEAR;
677 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memclear", 16);
678 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--memclear", 16);
679 }
680
681 else if (strncmp(argVect[argi], "--flash", 7) == 0) {
682 boot_cmds[boot_cmds_cnt++] = FLASH;
683 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--flash", 16);
684 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--flash", 16);
685 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--flash", 16);
686 doing_flash = TRUE;
687 }
688
689 else if (strncmp(argVect[argi], "--jump", 6) == 0) {
690 boot_cmds[boot_cmds_cnt++] = JUMP;
691 GetNumberOption(&argi, argCount, argVect, &boot_cmds[boot_cmds_cnt++], "--jump", 16);
692 }
693
694 else if (strncmp(argVect[argi], "--file", 6) == 0) {
695 char str[MAX_STRING_LEN];
696 boot_cmds[boot_cmds_cnt++] = PACKET_INFO;
697 GetStringOption(&argi, argCount, argVect,
698 str, "--file"); /* file name */
699 GetNumberOption(&argi, argCount, argVect,
700 &boot_cmds[boot_cmds_cnt++], str, 16); /* address */
701 last_boot_file = allocate_boot_file(last_boot_file);
702 first_boot_file = first_boot_file ? first_boot_file : last_boot_file;
703 last_boot_file->fileName = malloc(strlen(str) + 1);
704 strcpy(last_boot_file->fileName, str);
705 last_boot_file->size_p = &boot_cmds[boot_cmds_cnt];
706 last_boot_file->fd = NULL;
707 last_boot_file->size_sent = 0;
708 if (strncmp(str, "-", 1) != 0) {
709 if (stat(last_boot_file->fileName, &st) == -1) {
710 printf("Cannot get size of file '%s'. %s.\n",
711 last_boot_file->fileName, strerror(errno));
712 exit(EXIT_FAILURE);
713 }
714 if (db2) printf("* size is %d 0x%8.8x\n",
715 (int)st.st_size, (unsigned int)st.st_size);
716 last_boot_file->size = st.st_size;
717 boot_cmds[boot_cmds_cnt++] = st.st_size;
718 }
719 else {
720 GetNumberOption(&argi, argCount, argVect,
721 &last_boot_file->size , str, 16); /* size */
722
723 boot_cmds[boot_cmds_cnt++] = last_boot_file->size;
724 printf("* size is %d 0x%8.8x\n", last_boot_file->size,
725 last_boot_file->size);
726 }
727 }
728
729 else if (strncmp(argVect[argi], "--bootfile", 10) == 0) {
730 GetStringOption(&argi, argCount, argVect,
731 boot_loader_file, "--bootfile");
732 }
733
734 else if (strncmp(argVect[argi], "-d", 2) == 0) {
735 if (GetNumberOption (&argi, argCount, argVect, &number, "-d", 10) == 0) {
736 printHelp = TRUE;
737 exitCode = EXIT_FAILURE;
738 }
739 else {
740 sprintf(dbStr, "%d", number);
741 for (i = 0; i != (int) strlen(dbStr); i++) {
742 switch (dbStr[i] - '0') {
743 case 1:
744 db1 = TRUE;
745 break;
746 case 2:
747 db2 = TRUE;
748 break;
749 case 3:
750 db3 = TRUE;
751 break;
752 case 4:
753 db4 = TRUE;
754 break;
755 default:
756 printf("ERROR! Debug level %d is not defined.\n", dbStr[i] - '0');
757 printHelp = TRUE;
758 exitCode = EXIT_FAILURE;
759 break;
760 }
761 }
762 }
763 }
764
765 else if (strncmp(argVect[argi], "--find", 6) == 0) {
766 GetStringOption(&argi, argCount, argVect, needle, "--find");
767 /* convert control characters like /n to the real ascii valure */
768 {
769 int i;
770 int j = 0;
771 char c;
772 int esc = 0;
773
774 for (i = 0; (c = needle[i]); i++,j++) {
775 // printf("c = %d, i %d, j %d\n", (int)c, i, j);
776 if (c == '\\') {
777 // printf("esc\n");
778 esc = 1;
779 continue;
780 }
781 else if (esc) {
782 esc = 0;
783 switch(c) {
784 case 'r':
785 c = '\r';
786 break;
787
788 case 'n':
789 c = '\n';
790 break;
791
792 case '\\':
793 c = '\\';
794 break;
795
796 default:
797 printf("Uknown escape sequence '\\%c'\n", c);
798 exit(EXIT_FAILURE);
799 }
800 j--;
801 }
802 // printf("setting j %d to %d\n", j, (int)c);
803 needle[j] = c;
804 }
805 needle_len = j;
806 }
807
808 for (i = 0; needle[i]; i++) {
809 //printf("i = %d, c %d\n", i,(int)needle[i]);
810 }
811 }
812
813 else if (strncmp(argVect[argi], "--exitonfind", 12) == 0) {
814 exitonfind = TRUE;
815 }
816
817 else if (strncmp(argVect[argi], "--help", 6) == 0) {
818 printHelp = TRUE;
819 }
820
821 else {
822 printf("ERROR! Don't understand option '%s'\n", argVect[argi]);
823 printHelp = TRUE;
824 exitCode = EXIT_FAILURE;
825 }
826 }
827
828 if (printHelp == TRUE) {
829 PrintHelp();
830 exit(exitCode);
831 }
832
833 if (noleds) {
834 strcpy(&boot_loader_file[strlen(boot_loader_file)], "_NOLEDS");
835 }
836
837 handle_labels();
838 }
839
840 /****************************************************************************
841 *#
842 *# FUNCTION NAME: handle_labels
843 *#
844 *# PARAMETERS: global loop_label, label
845 *#
846 *# DESCRIPTION: Checks and matches labels from --loop and --label commands
847 *# and inserts the resolved addresses into boot commands.
848 *#
849 *#---------------------------------------------------------------------------
850 *# HISTORY
851 *#
852 *# DATE NAME CHANGES
853 *# ---- ---- -------
854 *# 20020204 ronny Initial version
855 *#
856 *#***************************************************************************/
857
858 void
859 handle_labels(void)
860 {
861 struct label_t *ll = loop_label;
862 struct label_t *l = label;
863 struct label_t *last_l = l;
864
865 while(ll) {
866 int match = 0;
867
868 l = last_l;
869 while(l) {
870 match = 0;
871
872 if (l->name && ll->name && (strcmp(l->name, ll->name) == 0)) {
873 match = 1;
874 boot_cmds[ll->addr] = IO_BUF_START+(l->addr*4);
875 break;
876 }
877 l = l->prev;
878 }
879 if (!match) {
880 printf("Error. No label '%s' defined as needed by --loop command.\n", ll->name);
881 exit(EXIT_FAILURE);
882 }
883 ll = ll->prev;
884 }
885 }
886
887 /****************************************************************************
888 *#
889 *# FUNCTION NAME: new_label
890 *#
891 *# PARAMETERS:
892 *#
893 *# DESCRIPTION:
894 *#
895 *#---------------------------------------------------------------------------
896 *# HISTORY
897 *#
898 *# DATE NAME CHANGES
899 *# ---- ---- -------
900 *# 20020201 ronny Initial version
901 *#
902 *#***************************************************************************/
903
904 void
905 new_label(struct label_t **label, udword addr, const char *name)
906 {
907 struct label_t *new_p;
908
909 new_p = malloc(sizeof(struct label_t));
910
911 if (*label == NULL) { /* first one? */
912 *label = new_p;
913 new_p->prev = NULL;
914 }
915 else {
916 new_p->prev = *label;
917 }
918 *label = new_p;
919 new_p->addr = boot_cmds_cnt;
920 new_p->name = malloc(strlen(name));
921 strcpy(new_p->name, name);
922 }
923
924 /****************************************************************************
925 *#
926 *# FUNCTION NAME: GetStringOption
927 *#
928 *# PARAMETERS: int *argNr : Returns next argc here.
929 *# int argCount : Index of last argument.
930 *# char *argVect[] : argv.
931 *# char *ret : Copy string here.
932 *# char *option : Name of the option.
933 *#
934 *# DESCRIPTION: Extracts a string option from argv, and updates argnr.
935 *# Returns TRUE/FALSE and string in *ret.
936 *#
937 *#---------------------------------------------------------------------------
938 *# HISTORY
939 *#
940 *# DATE NAME CHANGES
941 *# ---- ---- -------
942 *# 960930 ronny Initial version
943 *# 961203 ronny Handles filenames with spaces within 'file name'.
944 *#
945 *#***************************************************************************/
946
947 int
948 GetStringOption(int *argNr, int argCount, const char *argVect[], char *ret,
949 const char *option)
950 {
951 int startChar = strlen(option);
952
953 *ret = '\0';
954
955 /* Are there any more chars after option? If not skip to next argv. */
956 if (strlen(argVect[*argNr]) <= (unsigned int)startChar) {
957 (*argNr)++;
958 startChar = 0;
959 }
960
961 /* Any args left? */
962 if (*argNr >= argCount) {
963 printf("ERROR! The option '%s' needs a string argument.\n", option);
964 PrintHelp();
965 exit(EXIT_FAILURE);
966 }
967
968 /* avoid stack overflow hacks */
969 if (strlen(&argVect[*argNr][startChar]) > MAX_STRING_LEN) {
970 printf("Argument '%s' longer than maximum allowable %d characters.\n",
971 &argVect[*argNr][startChar], MAX_STRING_LEN);
972 exit(EXIT_FAILURE);
973 }
974
975 strcpy(ret, &argVect[*argNr][startChar]);
976 if (db4) printf("<<< GetStringOption '%s'\n", ret);
977
978 return TRUE;
979 }
980
981 /****************************************************************************
982 *#
983 *# FUNCTION NAME: GetNumberOption
984 *#
985 *# PARAMETERS:
986 *#
987 *# DESCRIPTION:
988 *#
989 *#---------------------------------------------------------------------------
990 *# HISTORY
991 *#
992 *# DATE NAME CHANGES
993 *# ---- ---- -------
994 *# 960930 ronny Initial version
995 *#
996 *#***************************************************************************/
997
998 int
999 GetNumberOption(int *argNr, int argCount, const char *argVect[],
1000 unsigned int *ret, const char *option, int base)
1001 {
1002 int startChar = 0;
1003 int add_io_base = 0;
1004
1005 (*argNr)++;
1006
1007 if (*argNr >= argCount) {
1008 printf("ERROR! The option '%s' needs a number argument.\n", option);
1009 PrintHelp();
1010 exit(EXIT_FAILURE);
1011 }
1012
1013 if (argVect[*argNr][startChar] == '+') {
1014 add_io_base = 1;
1015 startChar++;
1016 }
1017
1018 *ret = strtoul(&argVect[*argNr][startChar], NULL, base);
1019
1020 if (add_io_base) {
1021 *ret += IO_BUF_START;
1022 if (*ret < IO_BUF_START || *ret >= IO_BUF_END) {
1023 printf("ERROR! '%s' is outside the IO buffer (option '%s').\n",
1024 argVect[*argNr], option);
1025 exit(EXIT_FAILURE);
1026 }
1027 }
1028
1029 if (db4) printf("<<< GetNumberOption %08x\r\n", *ret);
1030
1031 return TRUE;
1032 }
1033
1034 /****************************************************************************
1035 *#
1036 *# FUNCTION NAME: GetRegisterOption
1037 *#
1038 *# PARAMETERS:
1039 *#
1040 *# DESCRIPTION:
1041 *#
1042 *#---------------------------------------------------------------------------
1043 *# HISTORY
1044 *#
1045 *# DATE NAME CHANGES
1046 *# ---- ---- -------
1047 *# 960930 ronny Initial version
1048 *#
1049 *#***************************************************************************/
1050
1051 int
1052 GetRegisterOption(int *argNr, int argCount, const char *argVect[],
1053 unsigned int *ret, const char *option, int base)
1054 {
1055 int startChar = 0;
1056
1057 (*argNr)++;
1058
1059 if (*argNr >= argCount) {
1060 printf("Error! The option '%s' needs a register name.\n", option);
1061 PrintHelp();
1062 exit(EXIT_FAILURE);
1063 }
1064
1065 {
1066 int r = 0;
1067
1068 while (reg_des[r].name) {
1069 if (strcmp(reg_des[r].name, argVect[*argNr]) == 0) {
1070 *ret = reg_des[r].addr;
1071 return TRUE;
1072 break;
1073 }
1074 r++;
1075 }
1076 }
1077
1078 printf("Error! Didn't find a register name matching '%s'.\n",
1079 argVect[*argNr]);
1080
1081 exit(EXIT_FAILURE);
1082
1083 return FALSE;
1084 }
1085
1086 /****************************************************************************
1087 *#
1088 *# FUNCTION NAME: PrintHelp
1089 *#
1090 *# PARAMETERS: None.
1091 *#
1092 *# DESCRIPTION: Prints help info.
1093 *#
1094 *#---------------------------------------------------------------------------
1095 *# DATE NAME CHANGES
1096 *# ---- ---- -------
1097 *# 960909 ronny Initial version
1098 *#
1099 *#***************************************************************************/
1100
1101 void
1102 PrintHelp(void)
1103 {
1104 printf("e100boot version %s.\n", version);
1105
1106 printf("\ne100boot [--device devicename] [--file filename|- addr [size]]\n"
1107 " [--flash ram-source flash-offset size]\n"
1108 " [--pause iter]\n"
1109 " [--memtest addr addr]\n"
1110 " [--memclear addr addr] [--memdump addr addr]\n"
1111 " [--setreg addr|regname val] [--getreg addr|regname]\n"
1112 " [--verify addr val] [--label label] [--loop addr label]\n"
1113 " [--5400] [--5600] [--testcard] [--devboard]\n"
1114 " [--testcardlx] [--network] [--serial]\n"
1115 " [--baudrate baudrate] [--bootfile file] [--jump addr]\n"
1116 " [--tofiles] [--cmdsonly] [--images] [--noleds]\n"
1117 " [--help]\n\n");
1118
1119 printf(" The commands sent to the cbl, and which are parsed by the cbl,\n"
1120 " are stored at 0x%8.8x-0x%8.8x.\n\n", IO_BUF_START, IO_BUF_END);
1121
1122 printf(" See the man page for more details about e100boot.\n\n");
1123 }
1124
1125 /****************************************************************************
1126 *#
1127 *# FUNCTION NAME: CreateBootLoader
1128 *#
1129 *# PARAMETERS: None.
1130 *#
1131 *# DESCRIPTION: Creates boot packets from boot file or internal loader.
1132 *#
1133 *#---------------------------------------------------------------------------
1134 *# DATE NAME CHANGES
1135 *# ---- ---- -------
1136 *# 960909 ronny Initial version
1137 *#***************************************************************************/
1138
1139 void
1140 CreateBootLoader(void)
1141 {
1142 struct stat st;
1143 char *buf = NULL;
1144 // int size_pos = 0x18;
1145 // int addr_pos = 0x28;
1146 struct packet_header_T *ph;
1147 int packet_size;
1148 int header_size;
1149 int buf_cnt = 0;
1150 int i;
1151 udword sum = 0;
1152
1153 if (create_boot_loader) {
1154 int image_nbr = 0;
1155 int found = 0;
1156 const struct boot_image_info_type *info;
1157
1158 if (db4) printf("> CreateBootLoader\n");
1159
1160 info = &boot_image_info[image_nbr];
1161
1162 /* Use internal boot loader? */
1163 while (!found && info->name != NULL) {
1164 if (strcmp(boot_loader_file, info->name) == 0) {
1165 st.st_size = info->len;
1166 buf = (char*) malloc(st.st_size);
1167 memcpy(buf, info->ptr, st.st_size); /* unnecessary? */
1168 found = TRUE;
1169 printf("Using internal boot loader: %s - %s.\n",
1170 info->name, info->info);
1171 }
1172 else {
1173 image_nbr++;
1174 info = &boot_image_info[image_nbr];
1175 }
1176 }
1177
1178 /* No internal? Load it from file instead. */
1179 if (!found) {
1180 FILE *fd;
1181
1182 /* We didn't find an internal match, load the boot file from disk. */
1183 if ((fd = Fopen(boot_loader_file, "r")) == NULL) {
1184 printf("Cannot open bootloader '%s'. %s.\n",
1185 boot_loader_file, strerror(errno));
1186 exit(EXIT_FAILURE);
1187 }
1188
1189 if (fstat(fileno(fd), &st) == -1) {
1190 printf("Cannot get filestatus of bootloader '%s'. %s.\n",
1191 boot_loader_file, strerror(errno));
1192 exit(EXIT_FAILURE);
1193 }
1194
1195 buf = (char*) malloc(st.st_size);
1196 // printf("CreateBootLoader: buf = (char*) malloc(st.st_size); 2\n");
1197 if (read(fileno(fd), buf, st.st_size) != st.st_size) {
1198 printf("Read fewer bytes than there should be in %s.\n",
1199 boot_loader_file);
1200 exit(EXIT_FAILURE);
1201 }
1202
1203 fclose(fd);
1204 }
1205
1206 /* Alright, got loader in buf[] and size in st. */
1207 if (netBoot) {
1208 /* The etrax code for all boot methods are linked to adress
1209 380000f0 but since network boot starts execution at 380000f4
1210 we have two nops in the beginning of the code which we do not
1211 transmit to etrax in the network case. The link adress
1212 doesn't change though. */
1213 buf += 4;
1214 st.st_size -= 4;
1215 packet_size = DATA_SIZE;
1216 }
1217 else {
1218 packet_size = st.st_size;
1219 }
1220
1221 /* Hack binary, insert size and address. */
1222
1223 #define SIZE_PATTERN 0x12345678
1224 #define ADDR_PATTERN 0x87654321
1225 #define SIZE_POS (netBoot ? 0x0c : 0x10)
1226 #define ADDR_POS (netBoot ? 0x10 : 0x14)
1227
1228 if (*(udword*)&buf[SIZE_POS] != SIZE_PATTERN) {
1229 printf("Bootloader corrupt. Should contain ret/nop (0x%8.8x) at 0x%x, but contains %x\n",
1230 SIZE_PATTERN, SIZE_POS, *(udword*)&buf[SIZE_POS]);
1231 exit(EXIT_FAILURE);
1232 }
1233
1234 /* How much data to load except data in first packet. */
1235
1236 if (netBoot) {
1237 *(udword*)(&buf[SIZE_POS]) = st.st_size - DATA_SIZE;
1238 }
1239 else {
1240 *(udword*)(&buf[SIZE_POS]) = st.st_size - 784;
1241 }
1242
1243 if (db3) printf("Inserting boot size 0x%x at 0x%x.\n",
1244 (unsigned int) *(udword*)(&buf[SIZE_POS]),
1245 (unsigned int)&buf[SIZE_POS]);
1246
1247 if (*(udword*)&buf[ADDR_POS] != ADDR_PATTERN) {
1248 printf("Bootloader corrupt. Should contain ret/nop (0x%8.8x) at 0x%x, but contains %x\n",
1249 ADDR_PATTERN, ADDR_POS, *(udword*)&buf[ADDR_POS]);
1250 exit(EXIT_FAILURE);
1251 }
1252
1253 if (netBoot) {
1254 *(udword*)(&buf[ADDR_POS]) = BOOT_ADDRESS + DATA_SIZE;
1255 }
1256 else {
1257 *(udword*)(&buf[ADDR_POS]) = BOOT_ADDRESS-4 + 784;
1258 }
1259
1260 if (db3) printf("Inserting boot address 0x%x at 0x%x.\n",
1261 (unsigned int)*(udword*)(&buf[ADDR_POS]),
1262 (unsigned int)&buf[ADDR_POS]);
1263
1264
1265 for (i = 0; i != st.st_size; i++) {
1266 sum += ((byte*)buf)[i];
1267 }
1268 if (db1) printf("Checksum 0x%x, bytes %d\n", sum, i);
1269
1270 if (db4) {
1271 int i;
1272
1273 for(i=0; i<st.st_size; i+=8) {
1274 int j;
1275
1276 printf("0x%8.8x[%4.4x]: ", BOOT_ADDRESS+i, i);
1277 for(j=0; i+j<st.st_size && j<8; j++) {
1278 printf("%2.2x ", (unsigned char) buf[i+j]);
1279 }
1280 printf("\n");
1281 }
1282 }
1283 /* Now create list of packets. */
1284 while (buf_cnt <= st.st_size) {
1285
1286 header_size = seq_nr == 0 ?
1287 SIZE_OF_FIRST_HEADER : sizeof(struct packet_header_T);
1288
1289 if (netBoot) {
1290 packet_size = ((st.st_size - buf_cnt) < DATA_SIZE ?
1291 st.st_size - buf_cnt : DATA_SIZE) + header_size;
1292 }
1293 else {
1294 packet_size = st.st_size;
1295 header_size = 0;
1296 }
1297
1298 if (db4) printf("seq_nr %d, header_size %d, packet_size %d\n",
1299 seq_nr, header_size, packet_size);
1300
1301 last_packet = allocate_packet(last_packet);
1302
1303 first_packet = first_packet ? first_packet : last_packet;
1304
1305 last_packet->size = packet_size;
1306 last_packet->data = (char*)malloc(packet_size);
1307 last_packet->seq = seq_nr;
1308 last_packet->baud_rate = 9600;
1309
1310 last_packet->boot_file = allocate_boot_file(NULL);
1311 last_packet->boot_file->fileName = boot_loader_file;
1312
1313 // printf("last_packet->size %8.8x\n", last_packet->size);
1314 // printf("last_packet->data %8.8x\n",last_packet->data);
1315
1316 if (netBoot) {
1317 ph = (struct packet_header_T*) last_packet->data;
1318 memcpy(ph->dest, dst_addr_of_device, 6);
1319 memcpy(ph->src, eth_addr_local, 6);
1320 ph->length = htons(packet_size);
1321 ph->snap1 = htonl(SNAP1);
1322 ph->snap2 = htonl(SNAP2);
1323 ph->tag = htonl(SERVER_TAG);
1324 ph->seq = htonl(seq_nr);
1325 if (seq_nr != 0) {
1326 ph->type = htonl(BOOT_PACKET);
1327 ph->id = htonl(0);
1328 }
1329 }
1330
1331 memcpy(&last_packet->data[header_size], &buf[buf_cnt],
1332 packet_size - header_size);
1333 if (db3) DecodeSvintoBoot(last_packet->data);
1334
1335 if (netBoot) {
1336 buf_cnt += DATA_SIZE;
1337 }
1338 else {
1339 buf_cnt += packet_size +1;
1340 }
1341
1342 seq_nr++;
1343 }
1344 }
1345
1346 if (db4) printf("< CreateBootLoader\n");
1347 }
1348
1349 /****************************************************************************
1350 *#
1351 *# FUNCTION NAME: allocate_packet
1352 *#
1353 *# PARAMETERS: None.
1354 *#
1355 *# DESCRIPTION:
1356 *#
1357 *#---------------------------------------------------------------------------
1358 *# DATE NAME CHANGES
1359 *# ---- ---- -------
1360 *# 960909 ronny Initial version
1361 *#***************************************************************************/
1362
1363 struct packet_buf*
1364 allocate_packet(struct packet_buf *p)
1365 {
1366 if (db4) printf("> allocate_packet\n");
1367
1368 if (p) {
1369 p->next = (struct packet_buf*) malloc(sizeof(struct packet_buf));
1370 p = p->next;
1371 }
1372 else {
1373 p = (struct packet_buf*) malloc(sizeof(struct packet_buf));
1374 }
1375 p->next = NULL;
1376
1377 return(p);
1378 }
1379
1380 /****************************************************************************
1381 *#
1382 *# FUNCTION NAME: allocate_boot_file
1383 *#
1384 *# PARAMETERS: None.
1385 *#
1386 *# DESCRIPTION:
1387 *#
1388 *#---------------------------------------------------------------------------
1389 *# DATE NAME CHANGES
1390 *# ---- ---- -------
1391 *# 960909 ronny Initial version
1392 *#***************************************************************************/
1393
1394 struct boot_files_T*
1395 allocate_boot_file(struct boot_files_T *bf)
1396 {
1397 if (bf) {
1398 bf->next = (struct boot_files_T*) malloc(sizeof(struct boot_files_T));
1399 bf = bf->next;
1400 }
1401 else {
1402 bf = (struct boot_files_T*) malloc(sizeof(struct boot_files_T));
1403 }
1404 bf->next = NULL;
1405
1406 return(bf);
1407 }
1408
1409 /****************************************************************************
1410 *#
1411 *# FUNCTION NAME: CreateBootCmds
1412 *#
1413 *# PARAMETERS: None.
1414 *#
1415 *# DESCRIPTION: Creates a boot packet from the boot commands. The data is
1416 *# filled in later by FinishBootCmds().
1417 *#
1418 *#---------------------------------------------------------------------------
1419 *# DATE NAME CHANGES
1420 *# ---- ---- -------
1421 *# 980818 ronny Initial version
1422 *#***************************************************************************/
1423
1424 void
1425 CreateBootCmds(void)
1426 {
1427 struct packet_header_T *ph;
1428
1429 if (db4) printf("***> CreateBootCmds\n");
1430
1431 last_packet = allocate_packet(last_packet);
1432
1433 boot_cmds_packet = last_packet;
1434
1435 last_packet->boot_file = allocate_boot_file(NULL);
1436 last_packet->boot_file->fileName = BOOT_CMDS_FILE;
1437 last_packet->baud_rate = 9600;
1438
1439 last_packet->size = netBoot ? SIZE_OF_BOOT_CMDS + sizeof(struct packet_header_T)
1440 : SIZE_OF_BOOT_CMDS;
1441
1442 last_packet->data = (char *) malloc(last_packet->size);
1443 last_packet->seq = seq_nr;
1444
1445 if (netBoot) {
1446 /* Create packet header. */
1447 ph = (struct packet_header_T *) last_packet->data;
1448 memcpy(ph->dest, dst_addr_of_device, 6);
1449 memcpy(ph->src, eth_addr_local, 6);
1450 ph->length = htons(last_packet->size);
1451 ph->snap1 = htonl(SNAP1);
1452 ph->snap2 = htonl(SNAP2);
1453 ph->tag = htonl(SERVER_TAG);
1454 ph->seq = htonl(seq_nr);
1455 seq_nr++;
1456 ph->type = htonl(BOOT_CMDS);
1457 ph->id = htonl(0);
1458 }
1459
1460 if (db3) DecodeSvintoBoot(last_packet->data);
1461 if (db4) printf("<*** CreateBootCmds\n");
1462 }
1463
1464 /****************************************************************************
1465 *#
1466 *# FUNCTION NAME: FinishBootCmds
1467 *#
1468 *# PARAMETERS: None.
1469 *#
1470 *# DESCRIPTION: Copies the boot commands into the correct packet and changes
1471 *# the dwords to network order.
1472 *#
1473 *#---------------------------------------------------------------------------
1474 *# DATE NAME CHANGES
1475 *# ---- ---- -------
1476 *# 960909 ronny Initial version
1477 *#***************************************************************************/
1478
1479 void
1480 FinishBootCmds(void)
1481 {
1482 int i;
1483 unsigned int offset = 0;
1484
1485 for (i = 0; i != boot_cmds_cnt; i++) {
1486 boot_cmds[i] = htonl(boot_cmds[i]);
1487 if (db3) printf("%8.8x\n", boot_cmds[i]);
1488 }
1489
1490 /* Copy boot commands into packet. */
1491 if (netBoot) {
1492 offset = sizeof(struct packet_header_T);
1493 }
1494
1495 memcpy(&boot_cmds_packet->data[offset], boot_cmds,
1496 boot_cmds_cnt * sizeof(udword));
1497 }
1498
1499 /****************************************************************************
1500 *#
1501 *# FUNCTION NAME: CreateNewBootPacket
1502 *#
1503 *# PARAMETERS: None.
1504 *#
1505 *# DESCRIPTION: Creates next packet for the files specified by '--file'.
1506 *#
1507 *# RETURNS: Next packet, or NULL.
1508 *#
1509 *#---------------------------------------------------------------------------
1510 *# DATE NAME CHANGES
1511 *# ---- ---- -------
1512 *# 960909 ronny Initial version
1513 *#***************************************************************************/
1514
1515 struct packet_buf*
1516 CreateNewBootPacket(void)
1517 {
1518 static char buf[DATA_SIZE];
1519 struct packet_header_T *ph;
1520 int packet_size;
1521 int header_size;
1522 int i;
1523 udword sum;
1524 int size = 0;
1525 int padding = 0;
1526
1527 static struct boot_files_T *bf = NULL;
1528
1529 if (db3) printf("> CreateNewBootPacket\n");
1530
1531 bf = bf ? bf : first_boot_file;
1532
1533 while (bf) {
1534 if (!bf->fd) {
1535 if (strcmp(bf->fileName, "-") == 0) {
1536 bf->fd = stdin;
1537 }
1538 else {
1539 bf->fd = fopen(bf->fileName, "rb");
1540 }
1541
1542 if (bf->fd == NULL) {
1543 printf("Cannot open boot file %s. Exiting\n", bf->fileName);
1544 exit(EXIT_FAILURE);
1545 }
1546 if (db3) printf("Opening boot file %s\n", bf->fileName);
1547 }
1548
1549 if (!padding) {
1550 size = fread(buf, 1, DATA_SIZE, bf->fd);
1551 if (size == 0) {
1552 if (db3) printf("Nothing more to read. Read: %d/%d\n",
1553 bf->size_sent, bf->size);
1554 padding = 1;
1555 }
1556 }
1557
1558 if (padding) {
1559 if (bf->size_sent < bf->size) {
1560 if (db3) printf("padding...\n");
1561 size = (bf->size - bf->size_sent > DATA_SIZE) ?
1562 DATA_SIZE : bf->size - bf->size_sent;
1563 memset(buf, 0, size);
1564 }
1565 else {
1566 if (db3) printf("All written\n");
1567 padding = 0;
1568 size = 0;
1569 }
1570 }
1571
1572 if (size != 0) {
1573 if (db3) printf("size: %d %d/%d\n", size, bf->size_sent, bf->size);
1574 bf->size_sent += size;
1575 last_packet = allocate_packet(last_packet);
1576
1577 /* Calculate checksum. */
1578 sum = 0;
1579 for (i = 0; i != size; i++) {
1580 sum += ((byte*)buf)[i];
1581 }
1582 if (db2) printf("Checksum 0x%x, bytes %d\n", sum, i);
1583
1584 /* Figure out size of packet. */
1585 if (netBoot) {
1586 header_size = seq_nr == 0 ?
1587 SIZE_OF_FIRST_HEADER : sizeof(struct packet_header_T);
1588
1589 packet_size = ((size) < DATA_SIZE ? size : DATA_SIZE) + header_size;
1590 }
1591 else {
1592 header_size = 0;
1593 packet_size = size;
1594 }
1595
1596 if (packet_size < 60) { /* CRC adds 4 bytes to 64 */
1597 printf(
1598 "Last packet from file '%s', is smaller than 64 bytes. \n"
1599 "This is not allowed in the Ethernet standard. Will pad with %d "
1600 "bytes.\n", bf->fileName, 60-packet_size);
1601
1602 *(bf->size_p) += 60-packet_size;
1603 packet_size = 60;
1604 }
1605
1606 last_packet->size = packet_size;
1607 last_packet->data = (char*)malloc(packet_size);
1608 last_packet->boot_file = bf;
1609 last_packet->baud_rate = 0;/*set_baudrate;*/
1610
1611 /* printf("size %8.8x\n", last_packet->size);*/
1612 /* printf("data %8.8x\n",last_packet->data);*/
1613
1614 if (netBoot) {
1615 /* Initialize ethernet header. */
1616 ph = (struct packet_header_T*) last_packet->data;
1617 memcpy(ph->dest, dst_addr_of_device, 6);
1618 memcpy(ph->src, eth_addr_local, 6);
1619 /* printf("packet_size %d\n", packet_size);*/
1620 ph->length = htons(packet_size);
1621 ph->snap1 = htonl(SNAP1);
1622 ph->snap2 = htonl(SNAP2);
1623 ph->tag = htonl(SERVER_TAG);
1624 ph->seq = htonl(seq_nr);
1625 last_packet->seq = seq_nr;
1626 if (seq_nr != 0) {
1627 ph->type = htonl(BOOT_PACKET);
1628 ph->id = htonl(0); /* id doesn't matter, we send to a unicast address */
1629 }
1630 }
1631
1632 /* Copy data in place. */
1633 memcpy(&last_packet->data[header_size], buf, packet_size - header_size);
1634 if (db2) DecodeSvintoBoot(last_packet->data);
1635 /* PrintPacket(last_packet->data, last_packet->size, HEX);*/
1636 seq_nr++;
1637
1638 if (db3) printf("< CreateNewBootPacket\n");
1639 return(last_packet);
1640 }
1641 else { /* Nothing read from fd. */
1642 fclose(bf->fd);
1643 bf = bf->next;
1644 }
1645 }
1646
1647 if (db3) printf("< CreateNewBootPacket\n");
1648 return(NULL);
1649 }
1650
1651 /****************** END OF FILE common.c ************************************/