Commit 8f5fbd6d03d359f61775bf325b296a1477f60227

Stefan Reinauer 2010-04-26T15:43:25

SUN OPB on the SPARC (Enterprise) platforms (especially): M3000, M4000, M9000 expects a checksum algorithm that is not compliant with IEEE 1275-1994 section 5.2.2.5. Add flag "Sun-Style-Checksum" to switch to the other algorithm. git-svn-id: svn://coreboot.org/openbios/trunk/fcode-utils-devel@757 f158a5a8-5612-0410-a976-696ce0be7e32

diff --git a/toke/clflags.c b/toke/clflags.c
index 1a67a3b..69fba57 100644
--- a/toke/clflags.c
+++ b/toke/clflags.c
@@ -5,7 +5,7 @@
  *  This program is part of a free implementation of the IEEE 1275-1994
  *  Standard for Boot (Initialization Configuration) Firmware.
  *
- *  Copyright (C) 2001-2005 Stefan Reinauer, <stepan@openbios.org>
+ *  Copyright (C) 2001-2010 Stefan Reinauer <stepan@openbios.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -94,6 +94,7 @@ bool ibm_locals_legacy_separator = TRUE ;
 bool ibm_legacy_separator_message = TRUE ;
 bool enable_abort_quote = TRUE ;
 bool sun_style_abort_quote = TRUE ;
+bool sun_style_checksum = FALSE ;
 bool abort_quote_throw = TRUE ;
 bool string_remark_escape = TRUE ;
 bool hex_remark_escape = TRUE ;
@@ -181,6 +182,11 @@ static const cl_flag_t cl_flags_list[] = {
 	"\t",
 	    "Use -2 THROW in an Abort\" phrase, rather than ABORT"     } ,
 
+  { "Sun-Style-Checksum",
+        &sun_style_checksum,
+	"\t\t",
+	    "Use this for SPARC (Enterprise) platforms (especially): M3000, M4000, M9000"     } ,
+
   { "String-remark-escape",
         &string_remark_escape,
 	"\t",
@@ -640,7 +646,7 @@ void cl_flags_help(void )
 
    for ( indx = 0 ; indx < number_of_cl_flags ; indx++ )
     {
-	printf("  %s    %s%s%s\n",
+	printf(" %s    %s%s%s\n",
 	    *(cl_flags_list[indx].flag_var) ? "  " : "no" ,
 	    cl_flags_list[indx].clflag_name,
 	    cl_flags_list[indx].clflag_tabs,
diff --git a/toke/clflags.h b/toke/clflags.h
index 25818ab..1d1bd9c 100644
--- a/toke/clflags.h
+++ b/toke/clflags.h
@@ -8,7 +8,7 @@
  *  This program is part of a free implementation of the IEEE 1275-1994
  *  Standard for Boot (Initialization Configuration) Firmware.
  *
- *  Copyright (C) 2001-2005 Stefan Reinauer, <stepan@openbios.org>
+ *  Copyright (C) 2001-2010 Stefan Reinauer <stepan@openbios.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -56,6 +56,7 @@
  *          ibm_legacy_separator_message
  *          enable_abort_quote
  *          sun_style_abort_quote
+ *          sun_style_checksum
  *          string_remark_escape
  *          hex_remark_escape
  *          c_style_string_escape
@@ -111,6 +112,7 @@ extern bool ibm_locals_legacy_separator;
 extern bool ibm_legacy_separator_message;
 extern bool enable_abort_quote;
 extern bool sun_style_abort_quote;
+extern bool sun_style_checksum;
 extern bool abort_quote_throw;
 extern bool string_remark_escape;
 extern bool hex_remark_escape;
diff --git a/toke/emit.c b/toke/emit.c
index bbc59b6..e237611 100644
--- a/toke/emit.c
+++ b/toke/emit.c
@@ -7,7 +7,7 @@
  *  This program is part of a free implementation of the IEEE 1275-1994 
  *  Standard for Boot (Initialization Configuration) Firmware.
  *
- *  Copyright (C) 2001-2005 Stefan Reinauer, <stepan@openbios.org>
+ *  Copyright (C) 2001-2010 Stefan Reinauer <stepan@openbios.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -317,7 +317,7 @@ void finish_fcodehdr(void)
 	/*  Calculate and place checksum and length, if haven't already  */
 	if ( fcode_start_ob_off != -1 )
 	{
-	    u16 checksum;
+	    u32 checksum;
 	    int length;
 
 	    u8 *fcode_body = ostart+fcode_body_ob_off;
@@ -331,13 +331,23 @@ void finish_fcodehdr(void)
 	              fcode_body < ob_end ;
 		          checksum += *(fcode_body++) ) ;
 
-	    BIG_ENDIAN_WORD_STORE(fcode_hdr->checksum , checksum);
+	    if (sun_style_checksum) {
+		/* SUN OPB on the SPARC (Enterprise) platforms (especially):
+                 * M3000, M4000, M9000 expects a checksum algorithm that is
+                 * not compliant with IEEE 1275-1994 section 5.2.2.5.
+		 */
+		checksum = (checksum & 0xffff) + (checksum >> 16);
+		checksum = (checksum & 0xffff) + (checksum >> 16);
+	    }
+
+	    BIG_ENDIAN_WORD_STORE(fcode_hdr->checksum, 
+		    (u16)(checksum & 0xffff));
 	    BIG_ENDIAN_LONG_STORE(fcode_hdr->length , length);
 
 	if (verbose)
 	    {
 		printf( "toke: checksum is 0x%04x (%d bytes).  ",
-		    checksum, length);
+                        (u16)checksum, length);
 		list_fcode_ranges( TRUE);
 	    }
 	}