35
35
#include <getopt.h>
36
36
#include <sfl.h>
37
37
38
+ #ifdef __linux__
39
+ #include <linux/serial.h>
40
+ #endif
41
+
38
42
#define DEFAULT_KERNELADR (0x40000000)
39
43
#define DEFAULT_CMDLINEADR (0x41000000)
40
44
#define DEFAULT_INITRDADR (0x41002000)
@@ -375,7 +379,7 @@ static void gdb_process_packet(int infd, int outfd, int altfd)
375
379
}
376
380
377
381
static void do_terminal (char * serial_port ,
378
- int doublerate , int gdb_passthrough ,
382
+ int baud , int gdb_passthrough ,
379
383
const char * kernel_image , unsigned int kernel_address ,
380
384
const char * cmdline , unsigned int cmdline_address ,
381
385
const char * initrd_image , unsigned int initrd_address ,
@@ -390,6 +394,8 @@ static void do_terminal(char *serial_port,
390
394
struct pollfd fds [3 ];
391
395
int flags ;
392
396
int rsp_pending = 0 ;
397
+ int c_cflag ;
398
+ int custom_divisor ;
393
399
394
400
/* Open and configure the serial port */
395
401
if (log_path != NULL ) {
@@ -406,11 +412,41 @@ static void do_terminal(char *serial_port,
406
412
return ;
407
413
}
408
414
415
+ custom_divisor = 0 ;
416
+ switch (baud ) {
417
+ case 9600 : c_cflag = B9600 ; break ;
418
+ case 19200 : c_cflag = B19200 ; break ;
419
+ case 38400 : c_cflag = B38400 ; break ;
420
+ case 57600 : c_cflag = B57600 ; break ;
421
+ case 115200 : c_cflag = B115200 ; break ;
422
+ case 230400 : c_cflag = B230400 ; break ;
423
+ default :
424
+ c_cflag = B38400 ;
425
+ custom_divisor = 1 ;
426
+ break ;
427
+ }
428
+
429
+ #ifdef __linux__
430
+ if (custom_divisor ) {
431
+ struct serial_struct serial_info ;
432
+ ioctl (serialfd , TIOCGSERIAL , & serial_info );
433
+ serial_info .custom_divisor = serial_info .baud_base / baud ;
434
+ serial_info .flags &= ~ASYNC_SPD_MASK ;
435
+ serial_info .flags |= ASYNC_SPD_CUST ;
436
+ ioctl (serialfd , TIOCSSERIAL , & serial_info );
437
+ }
438
+ #else
439
+ if (custom_divisor ) {
440
+ fprintf (stderr , "[FLTERM] baudrate not supported\n" );
441
+ return ;
442
+ }
443
+ #endif
444
+
409
445
/* Thanks to Julien Schmitt (GTKTerm) for figuring out the correct parameters
410
446
* to put into that weird struct.
411
447
*/
412
448
tcgetattr (serialfd , & my_termios );
413
- my_termios .c_cflag = doublerate ? B230400 : B115200 ;
449
+ my_termios .c_cflag = c_cflag ;
414
450
my_termios .c_cflag |= CS8 ;
415
451
my_termios .c_cflag |= CREAD ;
416
452
my_termios .c_iflag = IGNPAR | IGNBRK ;
@@ -535,7 +571,7 @@ static void do_terminal(char *serial_port,
535
571
enum {
536
572
OPTION_PORT ,
537
573
OPTION_GDB_PASSTHROUGH ,
538
- OPTION_DOUBLERATE ,
574
+ OPTION_SPEED ,
539
575
OPTION_DEBUG ,
540
576
OPTION_KERNEL ,
541
577
OPTION_KERNELADR ,
@@ -563,9 +599,9 @@ static const struct option options[] = {
563
599
.val = OPTION_DEBUG
564
600
},
565
601
{
566
- .name = "double-rate " ,
567
- .has_arg = 0 ,
568
- .val = OPTION_DOUBLERATE
602
+ .name = "speed " ,
603
+ .has_arg = 1 ,
604
+ .val = OPTION_SPEED
569
605
},
570
606
{
571
607
.name = "kernel" ,
@@ -609,7 +645,7 @@ static const struct option options[] = {
609
645
610
646
static void print_usage ()
611
647
{
612
- fprintf (stderr , "Serial boot program for Milkymist SoC - v. 2.2 \n" );
648
+ fprintf (stderr , "Serial boot program for Milkymist SoC - v. 2.3 \n" );
613
649
fprintf (stderr , "Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq\n" );
614
650
fprintf (stderr , "Copyright (C) 2011 Michael Walle\n" );
615
651
fprintf (stderr , "Copyright (C) 2004 MontaVista Software, Inc\n\n" );
@@ -619,7 +655,7 @@ static void print_usage()
619
655
fprintf (stderr , "the Free Software Foundation, version 3 of the License.\n\n" );
620
656
621
657
fprintf (stderr , "Usage: flterm --port <port>\n" );
622
- fprintf (stderr , " [--double-rate ] [--gdb-passthrough] [--debug]\n" );
658
+ fprintf (stderr , " [--speed <speed> ] [--gdb-passthrough] [--debug]\n" );
623
659
fprintf (stderr , " [--kernel <kernel_image> [--kernel-adr <address>]]\n" );
624
660
fprintf (stderr , " [--cmdline <cmdline> [--cmdline-adr <address>]]\n" );
625
661
fprintf (stderr , " [--initrd <initrd_image> [--initrd-adr <address>]]\n" );
@@ -634,7 +670,7 @@ int main(int argc, char *argv[])
634
670
{
635
671
int opt ;
636
672
char * serial_port ;
637
- int doublerate ;
673
+ int baud ;
638
674
int gdb_passthrough ;
639
675
char * kernel_image ;
640
676
unsigned int kernel_address ;
@@ -648,7 +684,7 @@ int main(int argc, char *argv[])
648
684
649
685
/* Fetch command line arguments */
650
686
serial_port = NULL ;
651
- doublerate = 0 ;
687
+ baud = 115200 ;
652
688
gdb_passthrough = 0 ;
653
689
kernel_image = NULL ;
654
690
kernel_address = DEFAULT_KERNELADR ;
@@ -667,8 +703,12 @@ int main(int argc, char *argv[])
667
703
free (serial_port );
668
704
serial_port = strdup (optarg );
669
705
break ;
670
- case OPTION_DOUBLERATE :
671
- doublerate = 1 ;
706
+ case OPTION_SPEED :
707
+ baud = strtoul (optarg , & endptr , 0 );
708
+ if (* endptr != 0 ) {
709
+ fprintf (stderr , "[FLTERM] Couldn't parse baudrate\n" );
710
+ return 1 ;
711
+ }
672
712
break ;
673
713
case OPTION_DEBUG :
674
714
debug = 1 ;
@@ -682,23 +722,32 @@ int main(int argc, char *argv[])
682
722
break ;
683
723
case OPTION_KERNELADR :
684
724
kernel_address = strtoul (optarg , & endptr , 0 );
685
- if (* endptr != 0 ) kernel_address = 0 ;
725
+ if (* endptr != 0 ) {
726
+ fprintf (stderr , "[FLTERM] Couldn't parse kernel address\n" );
727
+ return 1 ;
728
+ }
686
729
break ;
687
730
case OPTION_CMDLINE :
688
731
free (cmdline );
689
732
cmdline = strdup (optarg );
690
733
break ;
691
734
case OPTION_CMDLINEADR :
692
735
cmdline_address = strtoul (optarg , & endptr , 0 );
693
- if (* endptr != 0 ) cmdline_address = 0 ;
736
+ if (* endptr != 0 ) {
737
+ fprintf (stderr , "[FLTERM] Couldn't parse cmdline address\n" );
738
+ return 1 ;
739
+ }
694
740
break ;
695
741
case OPTION_INITRD :
696
742
free (initrd_image );
697
743
initrd_image = strdup (optarg );
698
744
break ;
699
745
case OPTION_INITRDADR :
700
746
initrd_address = strtoul (optarg , & endptr , 0 );
701
- if (* endptr != 0 ) initrd_address = 0 ;
747
+ if (* endptr != 0 ) {
748
+ fprintf (stderr , "[FLTERM] Couldn't parse initrd address\n" );
749
+ return 1 ;
750
+ }
702
751
break ;
703
752
case OPTION_LOG :
704
753
free (log_path );
@@ -708,7 +757,7 @@ int main(int argc, char *argv[])
708
757
}
709
758
710
759
if (serial_port == NULL ) {
711
- print_usage ( );
760
+ fprintf ( stderr , "[FLTERM] No port given\n" );
712
761
return 1 ;
713
762
}
714
763
@@ -722,7 +771,7 @@ int main(int argc, char *argv[])
722
771
tcsetattr (0 , TCSANOW , & ntty );
723
772
724
773
/* Do the bulk of the work */
725
- do_terminal (serial_port , doublerate , gdb_passthrough ,
774
+ do_terminal (serial_port , baud , gdb_passthrough ,
726
775
kernel_image , kernel_address ,
727
776
cmdline , cmdline_address ,
728
777
initrd_image , initrd_address ,
0 commit comments