Changeset 879

Show
Ignore:
Timestamp:
09/21/00 04:24:30 (14 years ago)
Author:
mds
Message:

(mds) replace with updated version from Christian Zuckschwerdt

<zany@…>. Updated according to SPD Spec 1.2B;
add html output option -f.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/prog/eeprom/decode-dimms.pl

    r534 r879  
    22# 
    33# Copyright 1998, 1999 Philip Edelbrock <phil@netroedge.com> 
    4 # 
    5 # Version 0.4 
     4# modified by Christian Zuckschwerdt <zany@triq.net> 
     5# 
     6# Version 0.4  1999  Philip Edelbrock <phil@netroedge.com> 
     7# Version 0.5  2000-03-30  Christian Zuckschwerdt <zany@triq.net> 
     8#  html output (selectable by commandline switches) 
     9# Version 0.6  2000-09-16  Christian Zuckschwerdt <zany@triq.net> 
     10#  updated according to SPD Spec Rev 1.2B 
     11#  see http://developer.intel.com/ 
     12#             technology/memory/pc133sdram/spec/Spdsd12b.htm 
    613# 
    714# EEPROM data decoding for SDRAM DIMM modules.  
    815# 
    9 # Two assumptions: lm_sensors-2.0.2 installed, 
     16# Two assumptions: lm_sensors-2.x installed, 
    1017# and Perl is at /usr/bin/perl 
    1118# 
     19# use the following command line switches 
     20#  -f, --format            print nice html output 
     21#  -b, --bodyonly          don't printhtml header 
     22#                          (useful for postprocessing the output) 
     23#  -h, --help              display this usage summary 
    1224# 
    1325# References:  
    1426# PC SDRAM Serial Presence  
    1527# Detect (SPD) Specification, Intel,  
    16 # Dec '97, Rev 1.2A 
    17 # 
     28# 1997,1999, Rev 1.2B 
    1829# 
    1930# Jedec Standards 4.1.x & 4.5.x 
     
    2132# 
    2233 
    23 print "PC-100 DIMM Serial Presence Detect Tester/Decoder\n"; 
    24 print "Written by Philip Edelbrock.  Copyright 1998, 1999.\n"; 
    25 print "Version 0.2\n\n"; 
     34sub printl ($$) # print a line w/ label and value 
     35{ 
     36   my ($label, $value) = @_; 
     37   if ($opt_html) { 
     38       $value =~ s%\n%<br>%sg; 
     39       print "<tr><td valign=top>$label</td><td>$value</td></tr>\n"; 
     40   } else { 
     41       $value =~ s%\n%\n\t\t%sg; 
     42       print "$label\t$value\n"; 
     43   } 
     44} 
     45 
     46sub prints ($) # print seperator w/ given text 
     47{ 
     48   my ($label) = @_; 
     49   if ($opt_html) { 
     50       print "<tr><td align=center colspan=2><b>$label</b></td></tr>\n"; 
     51   } else { 
     52       print "\n---=== $label ===---\n"; 
     53   } 
     54} 
     55 
     56sub printh ($) # print header w/ given text 
     57{ 
     58   my ($label) = @_; 
     59   if ($opt_html) { 
     60       $label =~ s%\n%<br>%sg; 
     61       print "<h1>$label</h1>\n"; 
     62   } else { 
     63        print "\n$label\n"; 
     64   } 
     65} 
     66 
     67for (@ARGV) { 
     68    if (/-h/) { 
     69        print "Usage: $0 [-f|-b|-h] 
     70 
     71  -f, --format            print nice html output 
     72  -b, --bodyonly          don't printhtml header 
     73                          (useful for postprocessing the output) 
     74  -h, --help              display this usage summary 
     75"; 
     76        exit; 
     77    } 
     78    $opt_html = 1 if (/-f/); 
     79    $opt_bodyonly = 1 if (/-b/); 
     80} 
     81$opt_body = $opt_html and not $opt_bodyonly; 
     82 
     83print "<html><head></head><body>\n" if $opt_body; 
     84 
     85printh ' 
     86PC DIMM Serial Presence Detect Tester/Decoder 
     87Written by Philip Edelbrock.  Copyright 1998, 1999. 
     88Modified by Christian Zuckschwerdt <zany@triq.net> 
     89Version 0.6 
     90'; 
     91 
     92print "<table border=1>\n" if $opt_html; 
    2693 
    2794$dimm_count=0; 
     
    35102                $dimm_count=$dimm_count + 1; 
    36103                 
    37                 print "\nDecoding EEPROM: /proc/sys/dev/sensors/$dimm_list[$i]\n"; 
     104                printl "Decoding EEPROM", "/proc/sys/dev/sensors/$dimm_list[$i]"; 
    38105                if (/^[^-]+-[^-]+-[^-]+-([^-]+)$/) { 
    39106                        $dimm_num=$1 - 49; 
    40                         print "Guessing DIMM is in bank $dimm_num\n"; 
     107                        printl "Guessing DIMM is in", "bank $dimm_num"; 
    41108                } 
    42109# Decode first 16 bytes 
    43                 print "\t\t----=== The Following is Required Data and is Applicable to all DIMM Types ===----\n"; 
     110                prints "The Following is Required Data and is Applicable to all DIMM Types"; 
    44111 
    45112                $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/data0-15`; 
     
    47114                for $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j];  } 
    48115                 
    49                 print "\t# of bytes written to SDRAM EEPROM:\t\t$bytes[0]\n"; 
    50  
    51                 print "\tTotal number of bytes in EEPROM:\t\t"; 
    52                 if ($bytes[1] < 13) { 
    53                         print 2**$bytes[1]; 
    54                         print "\n"; 
     116                printl "# of bytes written to SDRAM EEPROM",$bytes[0]; 
     117 
     118                $l = "Total number of bytes in EEPROM"; 
     119                if ($bytes[1] <= 13) { 
     120                        printl $l, 2**$bytes[1]; 
    55121                } elsif ($bytes[1] == 0) { 
    56                         print "RFU\n";  
    57                 } else { print "ERROR!\n"; } 
    58  
    59                 print "\tFundemental Memory type:\t\t\t"; 
    60                 if ($bytes[2] == 2) { print "EDO\n"; } elsif ($bytes[2] == 4) { print "SDRAM\n"; 
    61                         } else { print "???\n"; } 
    62  
    63                 print "\tNumber of Row Address Bits (SDRAM only):\t"; 
    64                 if ($bytes[3] == 0) { print "Undefined!\n" }             
    65                 elsif ($bytes[3] == 1) { print "1/16\n" }                
    66                 elsif ($bytes[3] == 2) { print "2/17\n" }                
    67                 elsif ($bytes[3] == 3) { print "3/18\n" } 
    68                 else { print $bytes[3]; print "\n"; } 
    69  
    70                 print "\tNumber of Col Address Bits (SDRAM only):\t"; 
    71                 if ($bytes[4] == 0) { print "Undefined!\n" }             
    72                 elsif ($bytes[4] == 1) { print "1/16\n" }                
    73                 elsif ($bytes[4] == 2) { print "2/17\n" }                
    74                 elsif ($bytes[4] == 3) { print "3/18\n" } 
    75                 else { print $bytes[4]; print "\n"; } 
    76  
    77                 print "\tNumber of Module Rows:\t\t\t\t"; 
    78                 if ($bytes[5] == 0 ) { print "Undefined!\n"; } else { print $bytes[5]; print "\n"; } 
    79  
    80                 print "\tData Width (SDRAM only):\t\t\t"; 
    81                 if ($bytes[7] > 1) { print "Undefined!\n" } else { 
     122                        printl $l, "RFU";  
     123                } else { printl $l, "ERROR!"; } 
     124 
     125                $l = "Fundemental Memory type"; 
     126                if ($bytes[2] == 2) { printl $l, "EDO"; } 
     127                elsif ($bytes[2] == 4) { printl $l, "SDRAM"; } 
     128                else { printl $l, "???"; } 
     129 
     130                $l = "Number of Row Address Bits (SDRAM only)"; 
     131                if ($bytes[3] == 0) { printl $l, "Undefined!" }                  
     132                elsif ($bytes[3] == 1) { printl $l, "1/16" }             
     133                elsif ($bytes[3] == 2) { printl $l, "2/17" }             
     134                elsif ($bytes[3] == 3) { printl $l, "3/18" } 
     135                else { printl $l, $bytes[3]; } 
     136 
     137                $l = "Number of Col Address Bits (SDRAM only)"; 
     138                if ($bytes[4] == 0) { printl $l, "Undefined!" }                  
     139                elsif ($bytes[4] == 1) { printl $l, "1/16" }             
     140                elsif ($bytes[4] == 2) { printl $l, "2/17" }             
     141                elsif ($bytes[4] == 3) { printl $l, "3/18" } 
     142                else { printl $l, $bytes[4]; } 
     143 
     144                $l = "Number of Module Rows"; 
     145                if ($bytes[5] == 0 ) { printl $l, "Undefined!"; } 
     146                else { printl $l, $bytes[5]; } 
     147 
     148                $l = "Data Width (SDRAM only)"; 
     149                if ($bytes[7] > 1) { printl $l, "Undefined!" } else { 
    82150                        $temp=($bytes[7]*256) + $bytes[6]; 
    83                         print $temp; print "\n"; } 
    84  
    85                 print "\tModule Interface Signal Levels:\t\t\t"; 
    86                 if ($bytes[8] == 0) { print "5.0 Volt/TTL\n";} elsif ($bytes[8] == 1) {  
    87                         print "LVTTL\n";} elsif ($bytes[8] == 2) { print "HSTL 1.5\n";} elsif ($bytes[8] == 3) {  
    88                         print "SSTL 3.3\n";} elsif ($bytes[8] == 4) { print "SSTL 2.5\n";} else { print "Undefined!\n";} 
    89                  
    90                 print "\tCycle Time (SDRAM):\t\t\t\t"; 
    91                 $temp=($bytes[9] >> 4) + (($bytes[9] - (($bytes[9] >> 4)<< 4)) * 0.1); 
    92                 print $temp; print "ns\n"; 
    93                  
    94                 print "\tAccess Time (SDRAM):\t\t\t\t"; 
    95                 $temp=($bytes[10] >> 4) + (($bytes[10] - (($bytes[10] >> 4)<< 4)) * 0.1); 
    96                 print $temp; print "ns\n"; 
    97                  
    98                 print "\tModule Configuration Type:\t\t\t"; 
    99                 if ($bytes[11] == 0) { print "No Parity\n"; } elsif ($bytes[11] == 1) { print "Parity\n";  
    100                         } elsif ($bytes[11] == 2) { print "ECC\n"; } else { print "Undefined!"; } 
     151                        printl $l, $temp; } 
     152 
     153                $l = "Module Interface Signal Levels"; 
     154                if ($bytes[8] == 0) { printl $l, "5.0 Volt/TTL";} 
     155                elsif ($bytes[8] == 1) { printl $l, "LVTTL";} 
     156                elsif ($bytes[8] == 2) { printl $l, "HSTL 1.5";} 
     157                elsif ($bytes[8] == 3) { printl $l, "SSTL 3.3";} 
     158                elsif ($bytes[8] == 4) { printl $l, "SSTL 2.5";} 
     159                elsif ($bytes[8] == 255) { printl $l, "New Table";} 
     160                else { printl $l, "Undefined!";} 
     161                 
     162                $l = "Cycle Time (SDRAM) highest CAS latency"; 
     163                $temp=($bytes[9] >> 4) + ($bytes[9] & 0xf) * 0.1; 
     164                printl $l, "${temp}ns"; 
     165                 
     166                $l = "Access Time (SDRAM)"; 
     167                $temp=($bytes[10] >> 4) + ($bytes[10] & 0xf) * 0.1; 
     168                printl $l, "${temp}ns"; 
     169                 
     170                $l = "Module Configuration Type"; 
     171                if ($bytes[11] == 0) { printl $l, "No Parity"; } 
     172                elsif ($bytes[11] == 1) { printl $l, "Parity"; } 
     173                elsif ($bytes[11] == 2) { printl $l, "ECC"; } 
     174                else { printl $l, "Undefined!"; } 
    101175                         
    102                 print "\tRefresh Type:\t\t\t\t\t"; 
    103                 if ($bytes[12] > 126) { print "Self Refreshing\n"; $temp=$bytes[12] - 127; 
    104                         } else { print "Not Self Refreshing\n"; $temp=$bytes[12];} 
    105                  
    106                 print "\tRefresh Rate:\t\t\t\t\t"; 
    107                 if ($temp == 0) { print "Normal (15.625uS)\n"; } elsif ($temp == 1) { print "Reduced (3.9uS)\n";  
    108                 } elsif ($temp == 2) { print "Reduced (7.8uS)\n"; } elsif ($temp == 3) { print "Extended (31.3uS)\n";  
    109                 } elsif ($temp == 4) { print "Extended (62.5uS)\n"; } elsif ($temp == 5) { print "Extended (125uS)\n"; 
    110                 } else { print "Undefined!";} 
    111                  
    112                 print "\tPrimary SDRAM Component Bank Config:\t\t"; 
    113                 if ($bytes[13]>126) {$temp=$bytes[13]-127; print "Bank2 = 2 x Bank1\n";} else { 
    114                         $temp=$bytes[13]; print "No Bank2 OR Bank2 = Bank1 width\n";} 
    115                  
    116                 print "\tPrimary SDRAM Component Widths:\t\t\t"; 
    117                 if ($temp == 0) { print "Undefined!\n"; } else { print "$temp\n"; } 
    118                  
    119                 print "\tError Checking SDRAM Component Bank Config:\t"; 
    120                 if ($bytes[14]>126) {$temp=$bytes[14]-127; print "Bank2 = 2 x Bank1\n";} else { 
    121                         $temp=$bytes[14]; print "No Bank2 OR Bank2 = Bank1 width\n";} 
    122                  
    123                 print "\tError Checking SDRAM Component Widths:\t\t"; 
    124                 if ($temp == 0) { print "Undefined!\n"; } else { print "$temp\n"; } 
    125                  
    126                 print "\tMin Clock Delay for Back to Back Random Access:\t"; 
    127                 if ($bytes[15] == 0) { print "Undefined!\n"; } else { print "$bytes[15]\n"; } 
    128                  
    129                 print "\t\t----=== The Following Apply to SDRAM DIMMs ONLY ===----\n"; 
     176                $l = "Refresh Type"; 
     177                if ($bytes[12] > 126) { printl $l, "Self Refreshing"; } 
     178                else { printl $l, "Not Self Refreshing"; } 
     179                 
     180                $l = "Refresh Rate"; 
     181                $temp=$bytes[12] & 0x7f; 
     182                if ($temp == 0) { printl $l, "Normal (15.625uS)"; } 
     183                elsif ($temp == 1) { printl $l, "Reduced (3.9uS)"; } 
     184                elsif ($temp == 2) { printl $l, "Reduced (7.8uS)"; } 
     185                elsif ($temp == 3) { printl $l, "Extended (31.3uS)"; } 
     186                elsif ($temp == 4) { printl $l, "Extended (62.5uS)"; } 
     187                elsif ($temp == 5) { printl $l, "Extended (125uS)"; } 
     188                else { printl $l, "Undefined!";} 
     189                 
     190                $l = "Primary SDRAM Component Bank Config"; 
     191                if ($bytes[13]>126) { printl $l, "Bank2 = 2 x Bank1";} 
     192                else { printl $l, "No Bank2 OR Bank2 = Bank1 width";} 
     193                 
     194                $l = "Primary SDRAM Component Widths"; 
     195                $temp=$bytes[13] & 0x7f; 
     196                if ($temp == 0) { printl $l, "Undefined!\n"; } 
     197                else { printl $l, $temp; } 
     198                 
     199                $l = "Error Checking SDRAM Component Bank Config"; 
     200                if ($bytes[14]>126) { printl $l, "Bank2 = 2 x Bank1";} 
     201                else { printl $l, "No Bank2 OR Bank2 = Bank1 width";} 
     202                 
     203                $l = "Error Checking SDRAM Component Widths"; 
     204                $temp=$bytes[14] & 0x7f; 
     205                if ($temp == 0) { printl $l, "Undefined!"; } 
     206                else { printl $l, $temp; } 
     207                 
     208                $l = "Min Clock Delay for Back to Back Random Access"; 
     209                if ($bytes[15] == 0) { printl $l, "Undefined!"; } 
     210                else { printl $l, $bytes[15]; } 
     211                 
     212                prints "The Following Apply to SDRAM DIMMs ONLY"; 
    130213                 
    131214# Decode next 16 bytes 
    132215                $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/data16-31`; 
    133216                @bytes=split(" "); 
    134                 for $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j];  } 
    135                  
    136                 print "\tBurst lengths supported:\t\t\t"; 
    137                 $temp=""; 
    138                 if (($bytes[0] & 1) > 0) { print "${temp}Burst Length = 1\n"; $temp="\t\t\t\t\t\t\t";} 
    139                 if (($bytes[0] & 2) > 0) { print "${temp}Burst Length = 2\n"; $temp="\t\t\t\t\t\t\t"; } 
    140                 if (($bytes[0] & 4) > 0) { print "${temp}Burst Length = 4\n"; $temp="\t\t\t\t\t\t\t"; } 
    141                 if (($bytes[0] & 8) > 0) { print "${temp}Burst Length = 8\n"; $temp="\t\t\t\t\t\t\t"; } 
    142                 if (($bytes[0] & 16) > 0) { print "${temp}Undefined! (bit 4)\n"; $temp="\t\t\t\t\t\t\t"; } 
    143                 if (($bytes[0] & 32) > 0) { print "${temp}Undefined! (bit 5)\n"; $temp="\t\t\t\t\t\t\t"; } 
    144                 if (($bytes[0] & 64) > 0) { print "${temp}Undefined! (bit 6)\n"; $temp="\t\t\t\t\t\t\t"; } 
    145                 if (($bytes[0] & 128) > 0) { print "${temp}Burst Length = Page\n"; $temp="\t\t\t\t\t\t\t"; } 
    146                 if ($bytes[0] == 0) { print "(None Supported)\n";} 
    147                  
    148                 print "\tNumber of Device Banks:\t\t\t\t"; 
    149                 if ($bytes[1] == 0) { print "Undefined/Reserved!\n"; } else { print "$bytes[1]\n"; } 
    150                  
    151                 print "\tSupported CAS Latencies:\t\t\t"; 
    152                 $temp=""; 
    153                 if (($bytes[2] & 1) > 0) { print "${temp}CAS Latency = 1\n"; $temp="\t\t\t\t\t\t\t";} 
    154                 if (($bytes[2] & 2) > 0) { print "${temp}CAS Latency = 2\n"; $temp="\t\t\t\t\t\t\t"; } 
    155                 if (($bytes[2] & 4) > 0) { print "${temp}CAS Latency = 3\n"; $temp="\t\t\t\t\t\t\t"; } 
    156                 if (($bytes[2] & 8) > 0) { print "${temp}CAS Latency = 4\n"; $temp="\t\t\t\t\t\t\t"; } 
    157                 if (($bytes[2] & 16) > 0) { print "${temp}CAS Latency = 5\n"; $temp="\t\t\t\t\t\t\t"; } 
    158                 if (($bytes[2] & 32) > 0) { print "${temp}CAS Latency = 6\n"; $temp="\t\t\t\t\t\t\t"; } 
    159                 if (($bytes[2] & 64) > 0) { print "${temp}CAS Latency = 7\n"; $temp="\t\t\t\t\t\t\t"; } 
    160                 if (($bytes[2] & 128) > 0) { print "${temp}Undefined (bit 7)\n"; $temp="\t\t\t\t\t\t\t"; } 
    161                 if ($bytes[2] == 0) { print "(None Supported)\n";} 
    162                  
    163                 print "\tSupported CS Latencies:\t\t\t\t"; 
    164                 $temp=""; 
    165                 if (($bytes[3] & 1) > 0) { print "${temp}CS Latency = 0\n"; $temp="\t\t\t\t\t\t\t";} 
    166                 if (($bytes[3] & 2) > 0) { print "${temp}CS Latency = 1\n"; $temp="\t\t\t\t\t\t\t"; } 
    167                 if (($bytes[3] & 4) > 0) { print "${temp}CS Latency = 2\n"; $temp="\t\t\t\t\t\t\t"; } 
    168                 if (($bytes[3] & 8) > 0) { print "${temp}CS Latency = 3\n"; $temp="\t\t\t\t\t\t\t"; } 
    169                 if (($bytes[3] & 16) > 0) { print "${temp}CS Latency = 4\n"; $temp="\t\t\t\t\t\t\t"; } 
    170                 if (($bytes[3] & 32) > 0) { print "${temp}CS Latency = 5\n"; $temp="\t\t\t\t\t\t\t"; } 
    171                 if (($bytes[3] & 64) > 0) { print "${temp}CS Latency = 6\n"; $temp="\t\t\t\t\t\t\t"; } 
    172                 if (($bytes[3] & 128) > 0) { print "${temp}Undefined (bit 7)\n"; $temp="\t\t\t\t\t\t\t"; } 
    173                 if ($bytes[3] == 0) { print "(None Supported)\n";} 
    174                  
    175                 print "\tSupported WE Latencies:\t\t\t\t"; 
    176                 $temp=""; 
    177                 if (($bytes[4] & 1) > 0) { print "${temp}WE Latency = 0\n"; $temp="\t\t\t\t\t\t\t";} 
    178                 if (($bytes[4] & 2) > 0) { print "${temp}WE Latency = 1\n"; $temp="\t\t\t\t\t\t\t"; } 
    179                 if (($bytes[4] & 4) > 0) { print "${temp}WE Latency = 2\n"; $temp="\t\t\t\t\t\t\t"; } 
    180                 if (($bytes[4] & 8) > 0) { print "${temp}WE Latency = 3\n"; $temp="\t\t\t\t\t\t\t"; } 
    181                 if (($bytes[4] & 16) > 0) { print "${temp}WE Latency = 4\n"; $temp="\t\t\t\t\t\t\t"; } 
    182                 if (($bytes[4] & 32) > 0) { print "${temp}WE Latency = 5\n"; $temp="\t\t\t\t\t\t\t"; } 
    183                 if (($bytes[4] & 64) > 0) { print "${temp}WE Latency = 6\n"; $temp="\t\t\t\t\t\t\t"; } 
    184                 if (($bytes[4] & 128) > 0) { print "${temp}Undefined (bit 7)\n"; $temp="\t\t\t\t\t\t\t"; } 
    185                 if ($bytes[4] == 0) { print "(None Supported)\n";} 
    186                  
    187                 print "\tSDRAM Module Attributes:\t\t\t"; 
    188                 $temp=""; 
    189                 if (($bytes[5] & 1) > 0) { print "${temp}Buffered Address/Control Inputs\n"; $temp="\t\t\t\t\t\t\t";} 
    190                 if (($bytes[5] & 2) > 0) { print "${temp}Registered Address/Control Inputs\n"; $temp="\t\t\t\t\t\t\t"; } 
    191                 if (($bytes[5] & 4) > 0) { print "${temp}On card PLL (clock)\n"; $temp="\t\t\t\t\t\t\t"; } 
    192                 if (($bytes[5] & 8) > 0) { print "${temp}Buffered DQMB Inputs\n"; $temp="\t\t\t\t\t\t\t"; } 
    193                 if (($bytes[5] & 16) > 0) { print "${temp}Registered DQMB Inputs\n"; $temp="\t\t\t\t\t\t\t"; } 
    194                 if (($bytes[5] & 32) > 0) { print "${temp}Differential Clock Input\n"; $temp="\t\t\t\t\t\t\t"; } 
    195                 if (($bytes[5] & 64) > 0) { print "${temp}Redundant Row Address\n"; $temp="\t\t\t\t\t\t\t"; } 
    196                 if (($bytes[5] & 128) > 0) { print "${temp}Undefined (bit 7)\n"; $temp="\t\t\t\t\t\t\t"; } 
    197                 if ($bytes[5] == 0) { print "(None Reported)\n";} 
    198                  
    199                 print "\tSDRAM Device Attributes (General):\t\t"; 
    200                 $temp=""; 
    201                 if (($bytes[6] & 1) > 0) { print "${temp}Supports Early RAS# Recharge\n"; $temp="\t\t\t\t\t\t\t";} 
    202                 if (($bytes[6] & 2) > 0) { print "${temp}Supports Auto-Precharge\n"; $temp="\t\t\t\t\t\t\t"; } 
    203                 if (($bytes[6] & 4) > 0) { print "${temp}Supports Precharge All\n"; $temp="\t\t\t\t\t\t\t"; } 
    204                 if (($bytes[6] & 8) > 0) { print "${temp}Supports Write1/Read Burst\n"; $temp="\t\t\t\t\t\t\t"; } 
    205                 if (($bytes[6] & 16) > 0) { print "${temp}Lower VCC Tolerance:5%\n"; $temp="\t\t\t\t\t\t\t"; } 
    206                 if (($bytes[6] & 16) == 0) { print "${temp}Lower VCC Tolerance:10%\n"; $temp="\t\t\t\t\t\t\t"; } 
    207                 if (($bytes[6] & 32) > 0) { print "${temp}Upper VCC Tolerance:5%\n"; $temp="\t\t\t\t\t\t\t"; } 
    208                 if (($bytes[6] & 32) == 0) { print "${temp}Upper VCC Tolerance:10%\n"; $temp="\t\t\t\t\t\t\t"; } 
    209                 if (($bytes[6] & 64) > 0) { print "${temp}Undefined (bit 6)\n"; $temp="\t\t\t\t\t\t\t"; } 
    210                 if (($bytes[6] & 128) > 0) { print "${temp}Undefined (bit 7)\n"; $temp="\t\t\t\t\t\t\t"; } 
    211                  
    212                 print "\tSDRAM Cycle Time (2ns highest CAS):\t\t"; 
    213                 $temp=$bytes[7] >> 4; 
    214                 if ($temp == 0) { print "Undefined!\n"; } else { 
     217                for $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j]; } 
     218                 
     219                $l = "Burst lengths supported"; 
     220                $temp=""; 
     221                if (($bytes[0] & 1) > 0) { $temp .= "Burst Length = 1\n"; } 
     222                if (($bytes[0] & 2) > 0) { $temp .= "Burst Length = 2\n"; } 
     223                if (($bytes[0] & 4) > 0) { $temp .= "Burst Length = 4\n"; } 
     224                if (($bytes[0] & 8) > 0) { $temp .= "Burst Length = 8\n"; } 
     225                if (($bytes[0] & 16) > 0) { $temp .= "Undefined! (bit 4)\n"; } 
     226                if (($bytes[0] & 32) > 0) { $temp .= "Undefined! (bit 5)\n"; } 
     227                if (($bytes[0] & 64) > 0) { $temp .= "Undefined! (bit 6)\n"; } 
     228                if (($bytes[0] & 128) > 0) { $temp .= "Burst Length = Page\n"; } 
     229                if ($bytes[0] == 0) { $temp .= "(None Supported)\n";} 
     230                printl $l, $temp; 
     231                 
     232                $l = "Number of Device Banks"; 
     233                if ($bytes[1] == 0) { printl $l, "Undefined/Reserved!"; } 
     234                else { printl $l, $bytes[1]; } 
     235                 
     236                $l = "Supported CAS Latencies"; 
     237                $temp=""; 
     238                if (($bytes[2] & 1) > 0) { $temp .= "CAS Latency = 1\n";} 
     239                if (($bytes[2] & 2) > 0) { $temp .= "CAS Latency = 2\n"; } 
     240                if (($bytes[2] & 4) > 0) { $temp .= "CAS Latency = 3\n"; } 
     241                if (($bytes[2] & 8) > 0) { $temp .= "CAS Latency = 4\n"; } 
     242                if (($bytes[2] & 16) > 0) { $temp .= "CAS Latency = 5\n"; } 
     243                if (($bytes[2] & 32) > 0) { $temp .= "CAS Latency = 6\n"; } 
     244                if (($bytes[2] & 64) > 0) { $temp .= "CAS Latency = 7\n"; } 
     245                if (($bytes[2] & 128) > 0) { $temp .= "Undefined (bit 7)\n"; } 
     246                if ($bytes[2] == 0) { $temp .= "(None Supported)\n";} 
     247                printl $l, $temp; 
     248                 
     249                $l = "Supported CS Latencies"; 
     250                $temp=""; 
     251                if (($bytes[3] & 1) > 0) { $temp .= "CS Latency = 0\n";} 
     252                if (($bytes[3] & 2) > 0) { $temp .= "CS Latency = 1\n"; } 
     253                if (($bytes[3] & 4) > 0) { $temp .= "CS Latency = 2\n"; } 
     254                if (($bytes[3] & 8) > 0) { $temp .= "CS Latency = 3\n"; } 
     255                if (($bytes[3] & 16) > 0) { $temp .= "CS Latency = 4\n"; } 
     256                if (($bytes[3] & 32) > 0) { $temp .= "CS Latency = 5\n"; } 
     257                if (($bytes[3] & 64) > 0) { $temp .= "CS Latency = 6\n"; } 
     258                if (($bytes[3] & 128) > 0) { $temp .= "Undefined (bit 7)\n"; } 
     259                if ($bytes[3] == 0) { $temp .= "(None Supported)\n";} 
     260                printl $l, $temp; 
     261                 
     262                $l = "Supported WE Latencies"; 
     263                $temp=""; 
     264                if (($bytes[4] & 1) > 0) { $temp .= "WE Latency = 0\n";} 
     265                if (($bytes[4] & 2) > 0) { $temp .= "WE Latency = 1\n"; } 
     266                if (($bytes[4] & 4) > 0) { $temp .= "WE Latency = 2\n"; } 
     267                if (($bytes[4] & 8) > 0) { $temp .= "WE Latency = 3\n"; } 
     268                if (($bytes[4] & 16) > 0) { $temp .= "WE Latency = 4\n"; } 
     269                if (($bytes[4] & 32) > 0) { $temp .= "WE Latency = 5\n"; } 
     270                if (($bytes[4] & 64) > 0) { $temp .= "WE Latency = 6\n"; } 
     271                if (($bytes[4] & 128) > 0) { $temp .= "Undefined (bit 7)\n"; } 
     272                if ($bytes[4] == 0) { $temp .= "(None Supported)\n";} 
     273                printl $l, $temp; 
     274                 
     275                $l = "SDRAM Module Attributes"; 
     276                $temp=""; 
     277                if (($bytes[5] & 1) > 0) { $temp .= "Buffered Address/Control Inputs\n";} 
     278                if (($bytes[5] & 2) > 0) { $temp .= "Registered Address/Control Inputs\n"; } 
     279                if (($bytes[5] & 4) > 0) { $temp .= "On card PLL (clock)\n"; } 
     280                if (($bytes[5] & 8) > 0) { $temp .= "Buffered DQMB Inputs\n"; } 
     281                if (($bytes[5] & 16) > 0) { $temp .= "Registered DQMB Inputs\n"; } 
     282                if (($bytes[5] & 32) > 0) { $temp .= "Differential Clock Input\n"; } 
     283                if (($bytes[5] & 64) > 0) { $temp .= "Redundant Row Address\n"; } 
     284                if (($bytes[5] & 128) > 0) { $temp .= "Undefined (bit 7)\n"; } 
     285                if ($bytes[5] == 0) { $temp .= "(None Reported)\n";} 
     286                printl $l, $temp; 
     287                 
     288                $l = "SDRAM Device Attributes (General)"; 
     289                $temp=""; 
     290                if (($bytes[6] & 1) > 0) { $temp .= "Supports Early RAS# Recharge\n";} 
     291                if (($bytes[6] & 2) > 0) { $temp .= "Supports Auto-Precharge\n"; } 
     292                if (($bytes[6] & 4) > 0) { $temp .= "Supports Precharge All\n"; } 
     293                if (($bytes[6] & 8) > 0) { $temp .= "Supports Write1/Read Burst\n"; } 
     294                if (($bytes[6] & 16) > 0) { $temp .= "Lower VCC Tolerance:5%\n"; } 
     295                if (($bytes[6] & 16) == 0) { $temp .= "Lower VCC Tolerance:10%\n"; } 
     296                if (($bytes[6] & 32) > 0) { $temp .= "Upper VCC Tolerance:5%\n"; } 
     297                if (($bytes[6] & 32) == 0) { $temp .= "Upper VCC Tolerance:10%\n"; } 
     298                if (($bytes[6] & 64) > 0) { $temp .= "Undefined (bit 6)\n"; } 
     299                if (($bytes[6] & 128) > 0) { $temp .= "Undefined (bit 7)\n"; } 
     300                printl $l, $temp; 
     301                 
     302                $l = "SDRAM Cycle Time (2nd highest CAS)"; 
     303                $temp = $bytes[7] >> 4; 
     304                if ($temp == 0) { printl $l, "Undefined!"; } 
     305                else { 
    215306                        if ($temp < 4 ) {$temp=$temp + 15;} 
    216                         print $temp + (($bytes[7] & 15) / 10); 
    217                         print "nS\n"; 
     307                        printl $l, $temp + (($bytes[7] & 0xf) * 0.1) . "nS"; 
    218308                } 
    219309                 
    220                 print "\tSDRAM Access from Clock Time (2nd highest CAS):\t"; 
    221                 $temp=$bytes[8] >> 4; 
    222                 if ($temp == 0) { print "Undefined!\n"; } else { 
     310                $l = "SDRAM Access from Clock Time (2nd highest CAS)"; 
     311                $temp = $bytes[8] >> 4; 
     312                if ($temp == 0) { printl $l, "Undefined!"; } 
     313                else { 
    223314                        if ($temp < 4 ) {$temp=$temp + 15;} 
    224                         print $temp + (($bytes[8] & 15) / 10.0); 
    225                         print "nS\n"; 
     315                        printl $l, $temp + (($bytes[8] & 0xf) * 0.1) . "nS"; 
    226316                } 
    227317                 
    228                 print "\t\t----=== The Following are Optional (may be Bogus) ===----\n"; 
    229                  
    230                 print "\tSDRAM Cycle Time (3rd highest CAS):\t\t"; 
    231                 $temp=$bytes[9] >> 2; 
    232                 if ($temp == 0) { print "Undefined!\n"; } else { 
    233                         print $temp + (($bytes[9] & 3) / 4.0); 
    234                         print "nS\n"; 
    235                 } 
    236                  
    237                 print "\tSDRAM Access from Clock Time (3rd highest CAS):\t"; 
    238                 $temp=$bytes[10] >> 2; 
    239                 if ($temp == 0) { print "Undefined!\n"; } else { 
    240                         print $temp + (($bytes[10] & 3) / 4.0); 
    241                         print "nS\n"; 
    242                 } 
    243                  
    244                 print "\t\t----=== The Following are Required (for SDRAMs) ===----\n"; 
    245                  
    246                 print "\tMinumum Row Precharge Time:\t\t\t"; 
    247                 if ($bytes[11] == 0) { print "Undefined!\n"; } else { print "$bytes[11]nS\n"; } 
    248                  
    249                 print "\tRow Active to Row Active Min:\t\t\t"; 
    250                 if ($bytes[12] == 0) { print "Undefined!\n"; } else { print "$bytes[12]nS\n"; } 
    251                  
    252                 print "\tRAS to CAS Delay:\t\t\t\t"; 
    253                 if ($bytes[13] == 0) { print "Undefined!\n"; } else { print "$bytes[13]nS\n"; } 
    254                  
    255                 print "\tMin RAS Pulse Width:\t\t\t\t"; 
    256                 if ($bytes[14] == 0) { print "Undefined!\n"; } else { print "$bytes[14]nS\n"; } 
    257                  
    258                  
    259                 print "\t\t----=== The Following are Required and Apply to ALL DIMMs ===----\n"; 
    260                  
    261                 print "\tRow Densities:\t\t\t\t\t"; 
    262                 $temp=""; 
    263                 if (($bytes[15] & 1) > 0) { print "${temp}4 MByte\n"; $temp="\t\t\t\t\t\t\t";} 
    264                 if (($bytes[15] & 2) > 0) { print "${temp}8 MByte\n"; $temp="\t\t\t\t\t\t\t"; } 
    265                 if (($bytes[15] & 4) > 0) { print "${temp}16 MByte\n"; $temp="\t\t\t\t\t\t\t"; } 
    266                 if (($bytes[15] & 8) > 0) { print "${temp}32 MByte\n"; $temp="\t\t\t\t\t\t\t"; } 
    267                 if (($bytes[15] & 16) > 0) { print "${temp}64 MByte\n"; $temp="\t\t\t\t\t\t\t"; } 
    268                 if (($bytes[15] & 32) > 0) { print "${temp}128 MByte\n"; $temp="\t\t\t\t\t\t\t"; } 
    269                 if (($bytes[15] & 64) > 0) { print "${temp}256 MByte\n"; $temp="\t\t\t\t\t\t\t"; } 
    270                 if (($bytes[15] & 128) > 0) { print "${temp}512 MByte\n"; $temp="\t\t\t\t\t\t\t"; } 
    271                 if ($bytes[15] == 0) { print "(Undefined! -- None Reported!)\n";} 
     318                prints "The Following are Optional (may be Bogus)"; 
     319                 
     320                $l = "SDRAM Cycle Time (3rd highest CAS)"; 
     321                $temp = $bytes[9] >> 2; 
     322                if ($temp == 0) { printl $l, "Undefined!"; } 
     323                else { printl $l, $temp + ($bytes[9] & 0x3) * 0.25 . "nS"; } 
     324                 
     325                $l = "SDRAM Access from Clock Time (3rd highest CAS)"; 
     326                $temp = $bytes[10] >> 2; 
     327                if ($temp == 0) { printl $l, "Undefined!"; } 
     328                else { printl $l, $temp + ($bytes[10] & 0x3) * 0.25 . "nS"; } 
     329                 
     330                prints "The Following are Required (for SDRAMs)"; 
     331                 
     332                $l = "Minumum Row Precharge Time"; 
     333                if ($bytes[11] == 0) { printl $l, "Undefined!"; } 
     334                else { printl $l, "$bytes[11]nS"; } 
     335                 
     336                $l = "Row Active to Row Active Min"; 
     337                if ($bytes[12] == 0) { printl $l, "Undefined!"; } 
     338                else { printl $l, "$bytes[12]nS"; } 
     339                 
     340                $l = "RAS to CAS Delay"; 
     341                if ($bytes[13] == 0) { printl $l, "Undefined!"; } 
     342                else { printl $l, "$bytes[13]nS"; } 
     343                 
     344                $l = "Min RAS Pulse Width"; 
     345                if ($bytes[14] == 0) { printl $l, "Undefined!"; } 
     346                else { printl $l, "$bytes[14]nS"; } 
     347                 
     348                 
     349                prints "The Following are Required and Apply to ALL DIMMs"; 
     350                 
     351                $l = "Row Densities"; 
     352                $temp=""; 
     353                if (($bytes[15] & 1) > 0) { $temp .= "4 MByte\n";} 
     354                if (($bytes[15] & 2) > 0) { $temp .= "8 MByte\n"; } 
     355                if (($bytes[15] & 4) > 0) { $temp .= "16 MByte\n"; } 
     356                if (($bytes[15] & 8) > 0) { $temp .= "32 MByte\n"; } 
     357                if (($bytes[15] & 16) > 0) { $temp .= "64 MByte\n"; } 
     358                if (($bytes[15] & 32) > 0) { $temp .= "128 MByte\n"; } 
     359                if (($bytes[15] & 64) > 0) { $temp .= "256 MByte\n"; } 
     360                if (($bytes[15] & 128) > 0) { $temp .= "512 MByte\n"; } 
     361                if ($bytes[15] == 0) { $temp .= "(Undefined! -- None Reported!)\n";} 
     362                printl $l, $temp; 
    272363                 
    273364                 
     
    277368                for $j ( 0 .. 15 ) { $dimm_checksum = $dimm_checksum + $bytes[$j];  } 
    278369                 
    279                 print "\t\t----=== The Following are Proposed and Apply to SDRAM DIMMs ===----\n"; 
    280                  
    281                 print "\tCommand and Address Signal Setup Time:\t\t"; 
    282                 if ($bytes[0] > 127) { $temp=($bytes[0]-128)>>4; $temp2=-1; } else { $temp=$bytes[0]>>4; $temp2=1;} 
    283                 print $temp2 * ($temp + (($bytes[0] & 15) / 10.0)); 
    284                 print "nS\n"; 
    285                  
    286                 print "\tCommand and Address Signal Hold Time:\t\t"; 
    287                 if ($bytes[1] > 127) { $temp=($bytes[1]-128)>>4; $temp2=-1; } else { $temp=$bytes[1]>>4; $temp2=1;} 
    288                 print $temp2 * ($temp + (($bytes[1] & 15) / 10.0)); 
    289                 print "nS\n"; 
    290                  
    291                 print "\tData Signal Setup Time:\t\t\t\t"; 
    292                 if ($bytes[2] > 127) { $temp=($bytes[2]-128)>>4; $temp2=-1; } else { $temp=$bytes[2]>>4; $temp2=1;} 
    293                 print $temp2 * ($temp + (($bytes[2] & 15) / 10.0)); 
    294                 print "nS\n"; 
    295                  
    296                 print "\tData Signal Hold Time:\t\t\t\t"; 
    297                 if ($bytes[3] > 127) { $temp=($bytes[3]-128)>>4; $temp2=-1; } else { $temp=$bytes[3]>>4; $temp2=1;} 
    298                 print $temp2 * ($temp + (($bytes[3] & 15) / 10.0)); 
    299                 print "nS\n"; 
     370                prints "The Following are Proposed and Apply to SDRAM DIMMs"; 
     371                 
     372                $l = "Command and Address Signal Setup Time"; 
     373                $temp = (($bytes[0] & 0x7f) >> 4) + ($bytes[0] & 0xf) * 0.1; 
     374                printl $l, ( ($bytes[0] >> 7) ? -$temp : $temp ) . "nS"; 
     375                 
     376                $l = "Command and Address Signal Hold Time"; 
     377                $temp = (($bytes[1] & 0x7f) >> 4) + ($bytes[1] & 0xf) * 0.1; 
     378                printl $l, ( ($bytes[1] >> 7) ? -$temp : $temp ) . "nS"; 
     379                 
     380                $l = "Data Signal Setup Time"; 
     381                $temp =(($bytes[2] & 0x7f) >> 4) + ($bytes[2] & 0xf) * 0.1; 
     382                printl $l, ( ($bytes[2] >> 7) ? -$temp : $temp ) . "nS"; 
     383                 
     384                $l = "Data Signal Hold Time"; 
     385                $temp = (($bytes[3] & 0x7f) >> 4) + ($bytes[3] & 0xf) * 0.1; 
     386                printl $l, ( ($bytes[3] >> 7) ? -$temp : $temp ) . "nS"; 
    300387 
    301388# That's it for the lower part of an SDRAM EEPROM's memory! 
     
    305392                for $j ( 0 .. 14 ) { $dimm_checksum = $dimm_checksum + $bytes[$j];  } 
    306393 
    307                 print "\tSPD Revision code:\t\t\t\t$bytes[14]\n"; 
    308                 print "\tEEPROM Checksum of bytes 0-62:\t\t\t"; 
    309                 printf("0x%.2X (verses calculated: 0x%.2X)\n",$bytes[15],$dimm_checksum & 255); 
    310                  
     394                printl "SPD Revision code ", sprintf("%x", $bytes[14]); 
     395                $l = "EEPROM Checksum of bytes 0-62"; 
     396                $temp = sprintf("0x%.2X (verses calculated: 0x%.2X)\n",$bytes[15],$dimm_checksum & 255); 
     397                printl $l, $temp; 
     398 
    311399# Decode next 16 bytes (64-79) 
    312400                $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/data64-79`; 
    313401                @bytes=split(" "); 
    314402                 
    315                 print "\tManufacturer's JEDEC ID Code:\t\t\t"; 
    316                 printf("0x%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X\n",$bytes[0],$bytes[1],$bytes[2],$bytes[3],$bytes[4],$bytes[5],$bytes[6],$bytes[7]); 
    317                 print "\t\t\t\t\t\t\t(\""; 
    318                 print pack("cccccccc", 
     403                $l = "Manufacturer's JEDEC ID Code"; 
     404                $temp = sprintf("0x%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X\n",$bytes[0],$bytes[1],$bytes[2],$bytes[3],$bytes[4],$bytes[5],$bytes[6],$bytes[7]); 
     405                printl $l, $temp; 
     406                $temp = pack("cccccccc", 
    319407                        $bytes[0],$bytes[1],$bytes[2],$bytes[3],$bytes[4],$bytes[5],$bytes[6],$bytes[7]); 
    320                 print "\")\n"; 
    321                  
    322                 print "\tManufacturing Location Code:\t\t\t"; 
    323                 printf("0x%.2X\n",$bytes[8]); 
    324                  
    325                 print "\tManufacurer's Part Number:\t\t\t\""; 
     408                printl $l, "(\"$temp\")"; 
     409                 
     410                $l = "Manufacturing Location Code"; 
     411                $temp = sprintf("0x%.2X\n",$bytes[8]); 
     412                printl $l, $temp; 
     413                 
     414                $l = "Manufacurer's Part Number:\""; 
    326415# Decode next 16 bytes (80-95) 
    327416                $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/data80-95`; 
    328417                @bytes2=split(" "); 
    329                 print pack("cccccccccccccccccc",$bytes[9],$bytes[10],$bytes[11],$bytes[12],$bytes[13],$bytes[14],$bytes[15], 
     418                $temp = pack("cccccccccccccccccc",$bytes[9],$bytes[10],$bytes[11],$bytes[12],$bytes[13],$bytes[14],$bytes[15], 
    330419                        $bytes2[0],$bytes2[1],$bytes2[2],$bytes2[3],$bytes2[4],$bytes2[5],$bytes2[6],$bytes2[7],$bytes2[8],$bytes2[9]); 
    331                 print "\"\n"; 
    332                  
    333                 print "\tRevision Code:\t\t\t\t\t"; 
    334                 printf("0x%.2X%.2X\n",$bytes2[10],$bytes2[11]); 
    335                  
    336                 print "\tManufacturing Date:\t\t\t\t"; 
    337                 printf("0x%.2X%.2X\n",$bytes2[12],$bytes2[13]); 
    338                  
    339                 print "\tAssembly Serial Number:\t\t\t\t"; 
     420                printl $l, $temp; 
     421                 
     422                $l = "Revision Code"; 
     423                $temp = sprintf("0x%.2X%.2X\n",$bytes2[10],$bytes2[11]); 
     424                printl $l, $temp; 
     425                 
     426                $l = "Manufacturing Date"; 
     427                $temp = sprintf("0x%.2X%.2X\n",$bytes2[12],$bytes2[13]); 
     428                printl $l, $temp; 
     429                 
     430                $l = "Assembly Serial Number"; 
    340431# Decode next 16 bytes (96-111) 
    341432                $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/data96-111`; 
    342433                @bytes=split(" "); 
    343434                 
    344                 printf("0x%.2X%.2X%.2X%.2X\n",$bytes2[15],$bytes[0],$bytes[1],$bytes[2]); 
     435                $temp = sprintf("0x%.2X%.2X%.2X%.2X\n",$bytes2[15],$bytes[0],$bytes[1],$bytes[2]); 
    345436# Decode next 16 bytes (112-127) 
    346437                $_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/data112-127`; 
    347438                @bytes=split(" "); 
    348439                 
    349                 print "\tIntel Specification for Frequency:\t\t"; 
    350                 if ($bytes[14] == 102) { print "66MHz\n"; } elsif ($bytes[14] == 100) { print "100MHz\n"; } else { print "Undefined!\n"; } 
    351                  
    352                 print "\tIntel Spec Details for 100MHz Support:\t\t"; 
    353                 $temp=""; 
    354                 if (($bytes[15] & 1) > 0) { print "${temp}Intel Concurrent AutoPrecharge\n"; $temp="\t\t\t\t\t\t\t";} 
    355                 if (($bytes[15] & 2) > 0) { print "${temp}CAS Latency = 2\n"; $temp="\t\t\t\t\t\t\t";} 
    356                 if (($bytes[15] & 4) > 0) { print "${temp}CAS Latency = 3\n"; $temp="\t\t\t\t\t\t\t";} 
    357                 if (($bytes[15] & 8) > 0) { print "${temp}Junction Temp A (90 degrees C)\n"; $temp="\t\t\t\t\t\t\t";} 
    358                 if (($bytes[15] & 8) == 0) { print "${temp}Junction Temp B (100 degrees C)\n"; $temp="\t\t\t\t\t\t\t";} 
    359                 if (($bytes[15] & 16) > 0) { print "${temp}CLK 3 Connected\n"; $temp="\t\t\t\t\t\t\t";} 
    360                 if (($bytes[15] & 32) > 0) { print "${temp}CLK 2 Connected\n"; $temp="\t\t\t\t\t\t\t";} 
    361                 if (($bytes[15] & 64) > 0) { print "${temp}CLK 1 Connected\n"; $temp="\t\t\t\t\t\t\t";} 
    362                 if (($bytes[15] & 128) > 0) { print "${temp}CLK 0 Connected\n"; $temp="\t\t\t\t\t\t\t";} 
    363                 if ($bytes[15] > 175) { print "${temp}Double Sided DIMM\n"; $temp="\t\t\t\t\t\t\t"; 
    364                         } else {print "${temp}Single Sided DIMM\n"; $temp="\t\t\t\t\t\t\t";} 
     440                $l = "Intel Specification for Frequency"; 
     441                if ($bytes[14] == 102) { printl $l, "66MHz\n"; } 
     442                elsif ($bytes[14] == 100) { printl $l, "100MHz\n"; } 
     443                else { printl $l, "Undefined!\n"; } 
     444                 
     445                $l = "Intel Spec Details for 100MHz Support"; 
     446                $temp=""; 
     447                if (($bytes[15] & 1) > 0) { $temp .= "Intel Concurrent AutoPrecharge\n";} 
     448                if (($bytes[15] & 2) > 0) { $temp .= "CAS Latency = 2\n";} 
     449                if (($bytes[15] & 4) > 0) { $temp .= "CAS Latency = 3\n";} 
     450                if (($bytes[15] & 8) > 0) { $temp .= "Junction Temp A (90 degrees C)\n";} 
     451                if (($bytes[15] & 8) == 0) { $temp .= "Junction Temp B (100 degrees C)\n";} 
     452                if (($bytes[15] & 16) > 0) { $temp .= "CLK 3 Connected\n";} 
     453                if (($bytes[15] & 32) > 0) { $temp .= "CLK 2 Connected\n";} 
     454                if (($bytes[15] & 64) > 0) { $temp .= "CLK 1 Connected\n";} 
     455                if (($bytes[15] & 128) > 0) { $temp .= "CLK 0 Connected\n";} 
     456                if ($bytes[15] > 175) { $temp .= "Double Sided DIMM\n"; } 
     457                else { $temp .= "Single Sided DIMM\n";} 
     458                printl $l, $temp; 
    365459                 
    366460                 
    367461        } 
    368462} 
    369 print "\n\nNumber of SDRAM DIMMs detected and decoded: $dimm_count\n"; 
     463printl "Number of SDRAM DIMMs detected and decoded", $dimm_count; 
     464 
     465print "</table>\n" if $opt_html; 
     466print "</body></html>\n" if $opt_body; 
     467print "\nTry '$0 --format' for html output.\n" unless $opt_html;