PERL   62

memconf

Guest on 29th July 2021 12:47:56 AM

  1. #!/usr/bin/env perl
  2. #
  3. # @(#) memconf - Identify sizes of SIMM/DIMM memory modules installed on a
  4. # @(#)           Sun SPARC workstation or server.
  5. # @(#) Micron Technology, Inc. - Tom Schmidt 04-Nov-2002 V1.51
  6. #
  7. # Maintained by Tom Schmidt (tschmidt@micron.com)
  8. #
  9. #   If memconf does not recognize a system, then please E-mail the output of
  10. #   'memconf -v', '/usr/sbin/prtconf -pv' (or '/usr/etc/devinfo -pv' on Solaris
  11. #   1.X) and '/usr/platform/`uname -i`/sbin/prtdiag -v' if available to
  12. #   tschmidt@micron.com so that memconf can be enhanced to recognize it.
  13. #   If the unrecognized system is a Sun clone, please also send any hardware
  14. #   documentation on the memory layout that you may have. Check my website
  15. #   at http://www.4schmidts.com/unix.html to get the latest version of memconf.
  16. #
  17. # Usage: memconf [ -v | -D | -h ] [explorer_dir]
  18. #                  -v            verbose mode
  19. #                  -D            E-mail results to memconf maintainer
  20. #                  -h            print help
  21. #                  explorer_dir  Sun Explorer output directory
  22. #
  23. # memconf reports the size of each SIMM/DIMM memory module installed in a
  24. # system. It also reports the system type and any empty memory sockets.
  25. # In verbose mode, it also reports:
  26. #  - banner name, model and CPU/system frequencies
  27. #  - address range and bank numbers for each module
  28. #
  29. # memconf is Y2K compliant. There are no date calls in the program. Your
  30. # Operating System or Perl version may not be Y2K compliant.
  31. #
  32. # memconf is free software; you can redistribute it and/or modify it under
  33. # the terms of the GNU General Public License as published by the Free
  34. # Software Foundation; either version 2 of the License, or (at your option)
  35. # any later version.
  36. #
  37. # Original version based on SunManagers SUMMARY by Howard Modell
  38. # (h.modell@ieee.org) on 29-Jan-1997.
  39. #
  40. # Tested to work on:
  41. # - sun4c Sun SS1, SS2, IPC, IPX, ELC with Open Boot PROM V2.X
  42. # - sun4m Sun 4/6x0, SS4, SS5, SS10, SS10SX, SS20, LX/ZX, Classic, Voyager
  43. # - sun4d Sun SPARCserver-1000, 1000E, SPARCcenter-2000, 2000E
  44. # - sun4u Sun Ultra 1, 2, 5, 10, 30, 60, 450
  45. # - sun4u Sun Ultra Enterprise 220R, 250, 450
  46. # - sun4u Sun Ultra Enterprise 3000, 3500, 4000/5000, 4500/5500, 6000, 6500
  47. # - sun4u1 Sun Ultra Enterprise 10000
  48. # - sun4u Sun SPARCengine Ultra AX, AXi, AXmp, AXmp+, AXe
  49. # - sun4u Sun SPARCengine CP 1400, CP 1500
  50. # - sun4u Sun Netra t1 100/105, t1120/1125, ft1800, X1, T1 200, AX1105-500, 120
  51. # - sun4u Sun Netra 20 (Netra T4)
  52. # - sun4u Sun Netra ct400, ct800
  53. # - sun4u Sun Blade 1000, 2000, 100, 150
  54. # - sun4u Sun Fire 280R
  55. # - sun4u Sun Fire 3800, 4800, 4810, and 6800
  56. # - sun4u Sun Fire V480, V880
  57. # - sun4u Sun Fire V100, V120
  58. # - sun4u Sun Fire 15000
  59. # - sun4m Tatung COMPstation 5, 10, 20AL, 20S and 20SL clones
  60. # - sun4m transtec SPARCstation 20I clone
  61. # - sun4m Rave Axil-255 SPARCstation 5 clone
  62. # - sun4m Rave Axil-245, 311 and 320 clones (no verbose output)
  63. # - sun4u AXUS Ultra 250
  64. # - sun4u Cycle CycleQUAD
  65. # - sun4u Tatung COMPstation U2, U60 and U80D clones
  66. # - Force Computers SPARC clones (no verbose output)
  67. # - Tadpole SPARCbook 3 and RDI PowerLite-170 (no verbose output)
  68. # - Tadpole VoyagerIIi
  69. # - Auspex 7000/650 (no verbose output)
  70. # - Fujitsu S-4/10H, S-4/20L and S-4/20H clones (no verbose output)
  71. # - Fujitsu GP7000 and GP7000F
  72. # - Fujitsu Siemens PrimePower 200, 400, 600 and 800
  73. # - Twinhead TWINstation 5G and 20G
  74. # - Detects VSIMMs for SX graphics on SS10SX/SS20 (1st VSIMM only)
  75. # - Detects Prestoserve NVSIMMs on SS10/SS20/SS1000/SC2000
  76. #
  77. # Untested systems that should work:
  78. # - sun4c Sun SS1+ with Open Boot PROM V2.X
  79. # - sun4u Sun Fire 12000
  80. # - sun4m Tatung COMPstation 20A clone
  81. # - May not work properly on Sun clones
  82. #
  83. # Won't work on:
  84. # - sun4u Sun Ultra 80, Ultra Enterprise 420R, and Netra t1400/1405.
  85. #   Not enough information is provided about the memory in the prtconf and
  86. #   prtdiag outputs by the Open Boot PROM.
  87. # - Systems without /dev/openprom
  88. # - sun4c Sun SS1, SS1+, SLC, IPC with Open Boot PROM V1.X (no 'memory' lines
  89. #   in devinfo/prtconf output)
  90. # - sun4 kernel architecture, and sun3 and older systems
  91. # - i86pc Solaris on Intel-based (x86) machines only show total memory
  92. # - Perl 5.001 is known to have problems with hex number conversions
  93. # - Does not detect unused VSIMMs (another FB installed) or second VSIMM
  94. #
  95. # To Do list and Revision History can be found on the maintainers web site at
  96. # http://www.4schmidts.com/unix.html
  97.  
  98. # Uncomment for debugging (perl 5 only)
  99. #use diagnostics;
  100.  
  101. $version="V1.51";
  102. $version_date="04-Nov-2002";
  103. $URL="http://www.4schmidts.com/unix.html";
  104. $ENV{PATH}="/usr/sbin:/bin:/usr/bin:/usr/ucb:/usr/local/bin:/var/local/bin:$ENV{PATH}";
  105. $_=$];
  106. $^W=1; # Enables -w warning switch, put here for SunOS4 compatibility.
  107. ($PERL_VERSION_MAJOR)=/(\d).*/;
  108. if ($PERL_VERSION_MAJOR < 5) {
  109.         ($PERL_VERS)=/(\d\.\d)/;
  110.         ($PERL_PATCH)=/(\d{2})$/;
  111.         $PERL_VERSION="$PERL_VERS$PERL_PATCH";
  112. } else {
  113.         ($PERL_VERSION)=/(\d\.\d{3}).*/;
  114. }
  115.  
  116. if (-x '/usr/bin/uname') {
  117.         $hostname=`/usr/bin/uname -n`;
  118.         chop $hostname;
  119.         $machine=`/usr/bin/uname -m`;
  120.         chop $machine;
  121.         $operating_system=`/usr/bin/uname`;
  122.         chop $operating_system;
  123.         $sunos=`/usr/bin/uname -r`;
  124.         chop $sunos;
  125.         $platform=$machine;
  126. } else {
  127.         $hostname="";
  128.         $machine="";
  129.         $operating_system="this unsupported";
  130.         $sunos="";
  131. }
  132. $prtdiag_cmd="";
  133. $prtdiag_exec="";
  134. if (-d '/usr/platform') {
  135.         $platform=`/usr/bin/uname -i`;
  136.         chop $platform;
  137.         if (-x "/usr/platform/$platform/sbin/prtdiag") {
  138.                 $prtdiag_cmd="/usr/platform/$platform/sbin/prtdiag";
  139.         } elsif (-x "/usr/platform/$machine/sbin/prtdiag") {
  140.                 $prtdiag_cmd="/usr/platform/$machine/sbin/prtdiag";
  141.         }
  142. } elsif (-x '/usr/kvm/prtdiag') {
  143.         $platform=$machine;
  144.         $prtdiag_cmd='/usr/kvm/prtdiag';
  145. }
  146. if ($prtdiag_cmd ne "") {
  147.         if (-x $prtdiag_cmd) {
  148.                 # Force C locale so that prtdiag output is in English
  149.                 $prtdiag_exec="/bin/sh -c 'LC_ALL=C $prtdiag_cmd'";
  150.         }
  151. }
  152. $buffer="";
  153. $filename="";
  154. $memory_size="";
  155. $installed_memory=0;
  156. $ultra=0;
  157. $simmbanks=0;
  158. $simmspergroup=1;
  159. $bankcnt=0;
  160. $slot0=0;
  161. $smallestsimm=16777216;
  162. $largestsimm=0;
  163. $found8mb=0;
  164. $found16mb=0;
  165. $found32mb=0;
  166. $found10bit=0;
  167. $found11bit=0;
  168. $foundbank1or3=0;
  169. $sxmem=0;
  170. $nvmem=0;
  171. $nvmem1=0;
  172. $nvmem2=0;
  173. $memtype="SIMM";
  174. $sockettype="socket";
  175. $verbose=0;
  176. $recognized=1;
  177. $untested=1;
  178. $untested_type="";
  179. $perlhexbug=0;
  180. $exitstatus=0;
  181. $meg=1048576;
  182. @socketstr=("");
  183. @orderstr=("");
  184. @groupstr=("");
  185. @bankstr=("");
  186. @banksstr=("");
  187. @bytestr=("");
  188. @slotstr=("");
  189. @simmsizes=(0,16777216);
  190. @simmsizesfound=();
  191. @memorylines=("");
  192. $socket="";
  193. $order="";
  194. $group="";
  195. $slotnum="";
  196. $bank="";
  197. $dualbank=0;
  198. $byte="";
  199. $gotmemory="";
  200. $gotmodule="";
  201. $gotmodulenames="";
  202. $slotname0="";
  203. @boards_cpu="";
  204. @boards_mem="";
  205. @new_boards_mem="";
  206. $empty_banks="";
  207. $banks_used="";
  208. $nvsimm_banks="";
  209. $boardslot_cpu=" ";
  210. $boardslot_cpus=" ";
  211. @boardslot_cpus=();
  212. $boardslot_mem=" ";
  213. $boardslot_mems=" ";
  214. @boardslot_mems=();
  215. $boardfound_cpu=0;
  216. $boardfound_mem=0;
  217. $prtdiag_has_mem=0;
  218. $prtdiag_failed=0;
  219. $flag_cpu=0;
  220. $flag_mem=0;
  221. $format_cpu=0;
  222. $format_mem=0;
  223. $foundname=0;
  224. $sockets_used="";
  225. $sockets_empty="";
  226. $sortslots=1;
  227. $devtype="";
  228. $interleave=0;
  229. $freq=0;
  230. $sysfreq=0;
  231. $cpufreq=0;
  232. $cputype="";
  233. $ncpu=0;
  234. $header_shown=0;
  235. $romver="";
  236. $romvernum="";
  237. $SUNWexplo=0;
  238. $banner="";
  239. $bannermore="";
  240. $model="";
  241. $modelmore="";
  242. $BSD=1; # Initially assume SunOS 4.X
  243. $config_cmd="/usr/etc/devinfo -pv";
  244. $config_command="devinfo";
  245. $config_permission=0;
  246. $devname="";    # Sun internal development code name
  247. $clone=0;
  248.  
  249. #
  250. # Parse options
  251. #
  252. if ($#ARGV >= 0) {
  253.         foreach $name (@ARGV) {
  254.                 if ($name eq "-v") {
  255.                         # verbose mode
  256.                         $verbose=1;
  257.                 } elsif ($name eq "-d") {
  258.                         # more verbose debug mode
  259.                         $verbose=2;
  260.                 } elsif ($name eq "-D") {
  261.                         # E-mail information of system to maintainer
  262.                         $verbose=3;
  263.                         open(MAILFILE, ">/tmp/memconf.output") || die "can't open /tmp/memconf.output: $!";
  264.                         print MAILFILE "Output from 'memconf -d' on $hostname\n";
  265.                         print MAILFILE "----------------------------------------------------\n";
  266.                         close(MAILFILE);
  267.                         open(STDOUT, "| tee -a /tmp/memconf.output") || die "can't open /tmp/memconf.output: $!";
  268.                 } elsif (-f "$name/sysconfig/prtconf-vp.out") {
  269.                         # Sun Explorer output
  270.                         $SUNWexplo=1;
  271.                         open(FILE, "<$name/sysconfig/prtconf-vp.out");
  272.                         @config=<FILE>;
  273.                         close(FILE);
  274.                         if (-f "$name/sysconfig/prtdiag-v.out") {
  275.                                 open(FILE, "<$name/sysconfig/prtdiag-v.out");
  276.                                 @prtdiag=<FILE>;
  277.                                 close(FILE);
  278.                         }
  279.                         if (-f "$name/sysconfig/uname-a.out") {
  280.                                 open(FILE, "<$name/sysconfig/uname-a.out");
  281.                                 $uname=<FILE>;
  282.                                 close(FILE);
  283.                                 chop($uname);
  284.                                 @unamearr=split(/\s/, $uname);
  285.                                 $hostname=$unamearr[1];
  286.                                 $machine=$unamearr[4];
  287.                                 $sunos=$unamearr[2];
  288.                                 $platform=$unamearr[6];
  289.                                 $prtdiag_cmd="/usr/platform/$platform/sbin/prtdiag";
  290.                         } else {
  291.                                 if ($config[0] =~ /System Configuration:/) {
  292.                                         @machinearr=split(/\s+/, $config[0]);
  293.                                         $machine=$machinearr[4];
  294.                                 }
  295.                                 $sunos="";
  296.                                 $hostname="";
  297.                         }
  298.                         if (-f "$name/sysconfig/prtconf-V.out") {
  299.                                 open(FILE, "<$name/sysconfig/prtconf-V.out");
  300.                                 $romver=<FILE>;
  301.                                 close(FILE);
  302.                                 chop $romver;
  303.                         }
  304.                         $filename="$name";
  305.                 } elsif (-f $name) {
  306.                         # Test file with prtconf/devinfo output
  307.                         open(FILE, "<$name");
  308.                         @config=<FILE>;
  309.                         close(FILE);
  310.                         # Test file may also have prtdiag output
  311.                         @prtdiag=@config;
  312.                         $hostname="";
  313.                         if ($config[0] =~ /System Configuration:/) {
  314.                                 @machinearr=split(/\s+/, $config[0]);
  315.                                 $machine=$machinearr[4];
  316.                         }
  317.                         $sunos="";
  318.                         $filename="$name";
  319.                 } else {
  320.                         &show_help;
  321.                 }
  322.         }
  323. }
  324. if ($filename eq "") {
  325.         if ("$operating_system" ne "SunOS") {
  326.                 print "ERROR: memconf is only supported on SPARC and i86pc ";
  327.                 print "systems running SunOS\n       4.X or 5.X, not on ";
  328.                 print "$operating_system $machine systems.\n";
  329.                 print "       It may be able to process Sun Explorer data ";
  330.                 print "on this machine.\n";
  331.                 exit 1;
  332.         }
  333.         if (-f '/vmunix') {
  334.                 # SunOS 4.X (Solaris 1.X)
  335.                 $BSD=1;
  336.                 if (! -x '/usr/etc/devinfo') {
  337.                         print "ERROR: no 'devinfo' command. Aborting.\n";
  338.                         exit 1;
  339.                 }
  340.                 $config_cmd="/usr/etc/devinfo -pv";
  341.                 $config_command="devinfo";
  342.         } else {
  343.                 # Solaris 2.X or later
  344.                 $BSD=0;
  345.                 if (! -x '/usr/sbin/prtconf') {
  346.                         print "ERROR: no 'prtconf' command. Aborting.\n";
  347.                         exit 1;
  348.                 }
  349.                 $config_cmd="/usr/sbin/prtconf -pv";
  350.                 $config_command="prtconf";
  351.         }
  352. }
  353. $kernbit="";
  354. $hasprtconfV=0;
  355. $solaris="";
  356. if ($sunos eq "4.1.1") { $solaris="1.0"; }
  357. if ($sunos eq "4.1.2") { $solaris="1.0.1"; }
  358. if ($sunos =~ /4.1.3/) { $solaris="1.1"; }
  359. if ($sunos eq "4.1.3_U1") { $solaris="1.1.1"; }
  360. if ($sunos eq "4.1.4") { $solaris="1.1.2"; }
  361. if ($sunos =~ /5./) {
  362.         $sunosminor=$sunos;
  363.         $sunosminor =~ s/5.//;
  364.         $release="";
  365.         if ($SUNWexplo == 1) {
  366.                 if (-f "$filename/etc/release") {
  367.                         open(FILE, "<$filename/etc/release");
  368.                         $release=<FILE>;
  369.                         close(FILE);
  370.                 }
  371.         } else {
  372.                 if (-f '/etc/release') {
  373.                         open(FILE, "</etc/release");
  374.                         $release=<FILE>;
  375.                         close(FILE);
  376.                 }
  377.         }
  378.         if ($release =~ "Solaris") {
  379.                 $release =~ s/\s+//;
  380.                 chop $release;
  381.                 $solaris="$release";
  382.         }
  383.         if ($sunosminor =~ /[7-9]|1[0-9]/) {
  384.                 $hasprtconfV=1;
  385.                 $solaris=$sunosminor if ($solaris eq "");
  386.                 $kernbit=32;
  387.                 $cpuarch="";
  388.                 if ($SUNWexplo == 1) {
  389.                         if (-f "$filename/sysconfig/isainfo.out") {
  390.                                 open(FILE, "<$filename/sysconfig/isainfo.out");
  391.                                 $cpuarch=<FILE>;
  392.                                 close(FILE);
  393.                         } elsif (-f "$filename/sysconfig/isainfo-kv.out") {
  394.                                 open(FILE, "<$filename/sysconfig/isainfo-kv.out");
  395.                                 $cpuarch=<FILE>;
  396.                                 close(FILE);
  397.                         }
  398.                 } elsif (-x '/bin/isainfo') {
  399.                         $cpuarch=`/bin/isainfo -k`;
  400.                 }
  401.                 if ($cpuarch =~ /sparcv9/) {
  402.                         $kernbit=64;
  403.                 }
  404.         } elsif ($sunosminor =~ /[4-6]/) {
  405.                 $hasprtconfV=1;
  406.                 $solaris="2.$sunosminor" if ($solaris eq "");
  407.         } else {
  408.                 $solaris="2.$sunosminor";
  409.         }
  410.         if ("$machine" eq "i86pc" & $sunosminor =~ /[0-5]/) {
  411.                 # x86 Solaris 2.5.1 and earlier has different syntax than SPARC
  412.                 $hasprtconfV=0;
  413.                 $config_cmd="/usr/sbin/prtconf -v";
  414.         }
  415. }
  416. if ($filename eq "") {
  417.         @config=`$config_cmd`;
  418.         if ($hasprtconfV) {
  419.                 # Solaris 2.4 or later
  420.                 $romver=`/usr/sbin/prtconf -V 2>/dev/null`;
  421.                 chop $romver;
  422.                 @romverarr=split(/\s/, $romver);
  423.                 $romvernum=$romverarr[1];
  424.         } else {
  425.                 # Solaris 2.3 or older
  426.                 # Try to use sysinfo if installed to determine the OBP version.
  427.                 # sysinfo is available from http://www.MagniComp.com/sysinfo/
  428.                 close(STDERR);
  429.                 $romver=`sysinfo -show romver 2>/dev/null | tail -1`;
  430.                 open(STDERR);
  431.                 if ($romver eq "") {
  432.                         # Assume it is old
  433.                         $romver="2.X" if ($machine =~ /sun4/);
  434.                 } else {
  435.                         chop $romver;
  436.                         @romverarr=split(/\s/, $romver);
  437.                         $romver=$romverarr[$#romverarr];
  438.                 }
  439.                 $romvernum=$romver;
  440.         }
  441. }
  442.  
  443. sub show_help {
  444.         print "Usage: memconf [ -v | -D | -h ] [explorer_dir]\n";
  445.         print "                 -v            verbose mode\n";
  446.         print "                 -D            E-mail results to memconf maintainer\n";
  447.         print "                 -h            print help\n";
  448.         print "                 explorer_dir  Sun Explorer output directory\n";
  449.         print "\nThis is memconf, $version $version_date\n\n";
  450.         print "Please send bug reports and enhancement requests along with ";
  451.         print "the output of\n\"$config_cmd\" ";
  452.         print "and \"$prtdiag_cmd -v\" " if ($prtdiag_exec ne "");
  453.         print "\nto tschmidt\@micron.com as E-mail attachments so that ";
  454.         print "memconf can be enhanced.\nYou can do this using the 'memconf ";
  455.         print "-D' command. Check my website at\n";
  456.         print "$URL to get the latest version of memconf.\n";
  457.         exit;
  458. }
  459.  
  460. sub show_header {
  461.         if ($header_shown == 1) {
  462.                 return;
  463.         }
  464.         $header_shown=1;
  465.         undef %saw;
  466.         @saw{@simmsizesfound}=();
  467.         @simmsizesfound=sort keys %saw;
  468.         print "memconf:  $version $version_date $URL\n" if ($verbose);
  469.         print "hostname: $hostname\n" if ($hostname);
  470.         if ($filename) {
  471.                 if ($SUNWexplo == 1) {
  472.                         print "Sun Explorer directory: $filename\n";
  473.                 } else {
  474.                         print "filename: $filename\n";
  475.                 }
  476.         }
  477.         if ($verbose) {
  478.                 if ($banner) {
  479.                         print "banner:   $banner";
  480.                         print " $bannermore" if ($bannermore);
  481.                         print "\n";
  482.                 }
  483.                 if ($model) {
  484.                         print "model:    ";
  485.                         print "$manufacturer " if ($manufacturer);
  486.                         print "$model";
  487.                         print " $modelmore" if ($modelmore);
  488.                         print " $realmodel" if ($realmodel);
  489.                         print "\n";
  490.                 }
  491.                 if ($devname ne "" & ! $clone) {
  492.                         print "Sun development name: $devname\n";
  493.                 }
  494.                 if ($filename eq "" | $SUNWexplo == 1) {
  495.                         if ($solaris) {
  496.                                 print "Solaris " if ($solaris !~ /Solaris/);
  497.                                 print "${solaris}, ";
  498.                         }
  499.                         print "${kernbit}-bit kernel, " if ($kernbit);
  500.                         print "SunOS ${sunos}\n";
  501.                 } elsif ($BSD) {
  502.                         print "Solaris 1.X, SunOS 4.X\n";
  503.                 } else {
  504.                         print "Solaris 2.X, SunOS 5.X\n";
  505.                 }
  506.                 if ($ncpu > 0 & $cpufreq > 0) {
  507.                         print "$ncpu $cputype cpu";
  508.                         print "s" if ($ncpu > 1);
  509.                 }
  510.                 if ($cpufreq) {
  511.                         print ", cpu freq: ${cpufreq}MHz";
  512.                         if ($sysfreq) {
  513.                                 print ", ";
  514.                         } else {
  515.                                 print "\n";
  516.                         }
  517.                 }
  518.                 print "system freq: ${sysfreq}MHz\n" if ($sysfreq);
  519.         } else {
  520.                 if ($manufacturer ne "" & $banner !~ /^$manufacturer/) {
  521.                         print "$manufacturer ";
  522.                 }
  523.                 if ($bannermore) {
  524.                         print "$banner $bannermore";
  525.                 } elsif ($modelmore) {
  526.                         print "$model $modelmore";
  527.                 } elsif ($banner) {
  528.                         print "$banner";
  529.                         print " $bannermore" if ($bannermore);
  530.                 } elsif ($model) {
  531.                         print "$model";
  532.                 }
  533.                 print " $realmodel" if ($realmodel);
  534.                 print "\n";
  535.         }
  536.         # debug output
  537.         if ($verbose > 1) {
  538.                 print "manufacturer = $manufacturer\n" if ($manufacturer);
  539.                 print "banner = $banner\n" if ($banner);
  540.                 print "bannermore = $bannermore\n" if ($bannermore);
  541.                 print "model = $model\n" if ($model);
  542.                 print "modelmore = $modelmore\n" if ($modelmore);
  543.                 print "machine = $machine\n";
  544.                 print "platform = $platform\n";
  545.                 print "ultra = $ultra\n" if ($ultra);
  546.                 if ($ultra eq "AXi") {
  547.                         print "found10bit = $found10bit\n";
  548.                         print "found11bit = $found11bit\n";
  549.                 }
  550.                 print "motherboard = $motherboard\n" if ($motherboard);
  551.                 print "romver = $romver\n" if ($romver);
  552.                 print "perl version: $]\n";
  553.                 print "memory line: $gotmemory\n" if ($gotmemory);
  554.                 print "module info: $gotmodule\n" if ($gotmodule);
  555.                 print "module name info: $gotmodulenames\n" if ($gotmodulenames);
  556.                 print "simmsizes = @simmsizes\n";
  557.                 print "simmsizesfound = @simmsizesfound\n";
  558.         }
  559.         if ($verbose >= 1 & $boardfound_cpu) {
  560.                 if ($format_cpu == 1) {
  561.                         if ($model =~ /Ultra-Enterprise/ | $ultra eq "e") {
  562.                                 print "CPU Units: Frequency Cache-Size Version\n";
  563.                         }
  564.                 } else {
  565.                         print "CPU Units:\n";
  566.                 }
  567.                 if ($model ne "SPARCserver-1000" & $model ne "SPARCcenter-2000") {
  568.                         print @boards_cpu;
  569.                         print "Memory Units:\n";
  570.                 }
  571.         }
  572.         if ($interleave) {
  573.                 print "Memory Interleave Factor = " . $interleave . "-way\n";
  574.         }
  575. }
  576.  
  577. sub show_unrecognized {
  578.         print "       This is most likely because memconf $version does not ";
  579.         print "completely\n";
  580.         print "       recognize this SunOS $sunos $platform system.\n";
  581.         &show_request if ($untested == 0);
  582. }
  583.  
  584. sub show_untested {
  585.         if ($untested_type eq "OS") {
  586.                 print "WARNING: This is an untested SunOS $sunos operating";
  587.         } elsif ($untested_type eq "OBP") {
  588.                 print "ERROR: This is an untested SunOS $sunos OBP $romvernum";
  589.         } else {
  590.                 print "ERROR: This is an untested SunOS $sunos";
  591.         }
  592.         print " system by memconf $version\n";
  593.         print "       Please let the author know how it works.\n";
  594.         $exitstatus=1;
  595.         &show_request;
  596. }
  597.  
  598. sub show_request {
  599.         print "       Check my website at $URL\n";
  600.         print "       for a newer version of memconf that may recognize this ";
  601.         print "system better.\n";
  602.         print "       Please run 'memconf -D' to E-mail the output of the ";
  603.         print "following commands\n       to Tom Schmidt ";
  604.         print "(tschmidt\@micron.com) so that memconf $version can be\n";
  605.         print "       enhanced to properly recognize this system:\n";
  606.         print "            memconf -d\n            $config_cmd\n";
  607.         print "            $prtdiag_cmd -v\n" if ($prtdiag_exec ne "");
  608.         if ($untested) {
  609.                 print "       If this system is a Sun clone, ";
  610.                 print "please also send any hardware\n       documentation ";
  611.                 print "on the memory layout that you may have.\n";
  612.         }
  613. }
  614.  
  615. sub check_prtdiag {
  616.         if ("$prtdiag_exec" eq "" & $filename eq "") {
  617.                 return;
  618.         }
  619.         @prtdiag=`$prtdiag_exec` if ($filename eq "");
  620.         foreach $line (@prtdiag) {
  621.                 if ($line =~ /[Pp]rtdiag [Ff]ailed/) {
  622.                         $prtdiag_failed=1;
  623.                 }
  624.                 if ($line =~ /=====/) {
  625.                         $flag_cpu=0;    # End of CPU section
  626.                         $flag_mem=0;    # End of memory section
  627.                 }
  628.                 if ($line =~ /Memory Units: Group Size/) {
  629.                         # Start of CPU and memory section on SS1000/SC2000
  630.                         $flag_cpu=1;
  631.                         $flag_mem=1;
  632.                 }
  633.                 $line="Memory $line" if ($line =~ /^Segment Table:/);
  634.                 if ($flag_mem >= 1 & $line ne "\n") {
  635.                         push(@boards_mem, "$line");
  636.                         $boardfound_mem=1;
  637.                         $boardfound_mem=0 if ($line =~ /Cannot find/);
  638.                         @linearr=split(' ', $line);
  639.                         if ($#linearr >= 1) {
  640.                                 if ($linearr[1] =~ /\b\d+MB\b/) {
  641.                                         # Sun Blade 100 format
  642.                                         $simmsize=$linearr[1];
  643.                                         $simmsize =~ s/MB//g;
  644.                                         push(@simmsizesfound, "$simmsize");
  645.                                 }
  646.                         }
  647.                         if ($#linearr >= 2) {
  648.                                 if ($linearr[2] =~ /\bU\d\d\d\d\b/) {
  649.                                         # Sun Ultra-250 format
  650.                                         $sockets_used .= " $linearr[2]";
  651.                                 } elsif ($linearr[2] =~ /\b\d\d\d\d\b/) {
  652.                                         # Sun Ultra-4 format
  653.                                         $sockets_used .= " U$linearr[2]";
  654.                                 }
  655.                         }
  656.                         if ($#linearr >= 3) {
  657.                                 if ($model eq "Ultra-250" | $ultra eq 250 | $model eq "Ultra-4" | $ultra eq 450 | $model eq "Ultra-4FT" | $ultra eq "Netra ft1800") {
  658.                                         if ($linearr[3] =~ /\b\d+\b/) {
  659.                                                 $simmsize=$linearr[3];
  660.                                                 push(@simmsizesfound, "$simmsize");
  661.                                         }
  662.                                 }
  663.                         }
  664.                         if ($linearr[$#linearr] =~ /\bDIMM\d/) {
  665.                                 $sockets_used .= " $linearr[$#linearr]";
  666.                         }
  667.                         if ($linearr[$#linearr] eq "-") {
  668.                                 $sockets_used .= " $linearr[$#linearr]";
  669.                         }
  670.                         if ($linearr[$#linearr] =~ /\b[UJ]\d\d\d\d[\b,]/) {
  671.                                 $sockets_used .= " $linearr[$#linearr]";
  672.                                 $sockets_used =~ s/,/ /g;
  673.                         }
  674.                         if ($ultra eq "Sun Fire 280R") {
  675.                                 if ($line =~ / CA    0     [0-3] .+4-way/) {
  676.                                         $sockets_used="J0100 J0202 J0304 J0406 J0101 J0203 J0305 J0407";
  677.                                 } elsif ($line =~ / CA    0     [02] /) {
  678.                                         $sockets_used .= " J0100 J0202 J0304 J0406" if ($sockets_used !~ / J0100 /);
  679.                                 } elsif ($line =~ / CA    1     [13] /) {
  680.                                         $sockets_used .= " J0101 J0203 J0305 J0407" if ($sockets_used !~ / J0101 /);
  681.                                 }
  682.                         }
  683.                         # Memory on Sun Fire systems
  684.                         if ($line =~ /^\/N\d\/SB\d\/P\d\/B\d\b/) {
  685.                                 $boardslot_mem=substr($line,0,13);
  686.                                 push(@boardslot_mems, "$boardslot_mem");
  687.                                 $boardslot_mems .= $boardslot_mem . " ";
  688.                         } elsif ($line =~ /^\/N\d\/SB\d\d\/P\d\/B\d\b/) {
  689.                                 $boardslot_mem=substr($line,0,14);
  690.                                 push(@boardslot_mems, "$boardslot_mem");
  691.                                 $boardslot_mems .= $boardslot_mem . " ";
  692.                         } elsif ($line =~ /^\/SB\d\d\/P\d\/B\d\b/) {
  693.                                 $boardslot_mem=substr($line,0,11);
  694.                                 push(@boardslot_mems, "$boardslot_mem");
  695.                                 $boardslot_mems .= $boardslot_mem . " ";
  696.                         }
  697.                         if ($ultra =~ /Sun Fire/ & $#linearr >= 5) {
  698.                                 if ($linearr[5] =~ /\b\d+MB\b/) {
  699.                                         $simmsize=$linearr[5];
  700.                                         $simmsize =~ s/MB//g;
  701.                                         push(@simmsizesfound, "$simmsize");
  702.                                 }
  703.                         }
  704.                 }
  705.                 if ($line =~ /CPU Units:/) {
  706.                         $flag_cpu=1;    # Start of CPU section
  707.                         $flag_mem=0;    # End of memory section
  708.                         $format_cpu=1;
  709.                 }
  710.                 if ($line =~ /===== CPU/) {
  711.                         $flag_cpu=1;    # Start of CPU section
  712.                         $flag_mem=0;    # End of memory section
  713.                         $format_cpu=2;
  714.                 }
  715.                 if ($line =~ /Memory Units:/ | $line =~ /===== Memory / | $line =~ /Used Memory:/) {
  716.                         $flag_cpu=0;    # End of CPU section
  717.                         $flag_mem=1;    # Start of memory section
  718.                 }
  719.                 if ($line =~ /CPU Units:/ & $line =~ /Memory Units:/) {
  720.                         $flag_cpu=1;    # Start of CPU section
  721.                         $flag_mem=1;    # Start of memory section
  722.                 }
  723.                 if ($flag_cpu >= 1 & $line ne "\n") {
  724.                         if ($model eq "Ultra-5_10" | $ultra eq "5_10" | $ultra eq 5 | $ultra eq 10) {
  725.                                 $newline=$line;
  726.                                 $newline =~ s/^       //g if ($line !~ /Run   Ecache   CPU    CPU/);
  727.                                 push(@boards_cpu, "$newline");
  728.                         } else {
  729.                                 push(@boards_cpu, "$line");
  730.                         }
  731.                         $boardfound_cpu=1;
  732.                         # CPUs on Sun Fire systems
  733.                         if ($line =~ /^\/N\d\/SB\d\/P\d\b/) {
  734.                                 $boardslot_cpu=substr($line,0,10);
  735.                                 push(@boardslot_cpus, "$boardslot_cpu");
  736.                                 $boardslot_cpus .= $boardslot_cpu . " ";
  737.                         } elsif ($line =~ /^\/N\d\/SB\d\d\/P\d\b/) {
  738.                                 $boardslot_cpu=substr($line,0,11);
  739.                                 push(@boardslot_cpus, "$boardslot_cpu");
  740.                                 $boardslot_cpus .= $boardslot_cpu . " ";
  741.                         } elsif ($line =~ /^\/SB\d\d\/P\d\b/) {
  742.                                 $boardslot_cpu=substr($line,0,8);
  743.                                 push(@boardslot_cpus, "$boardslot_cpu");
  744.                                 $boardslot_cpus .= $boardslot_cpu . " ";
  745.                         }
  746.                 }
  747.                 if ($flag_cpu == 1 & $line =~ /------/) {
  748.                         # Next lines are the CPUs on each system board
  749.                         $flag_cpu=2;
  750.                 }
  751.                 if ($flag_mem == 1 & $line =~ /------/) {
  752.                         # Next lines are the memory on each system board
  753.                         $flag_mem=2;
  754.                 }
  755.         }
  756.         # Rewrite prtdiag output to include DIMM information on SB1000 systems
  757.         if ($ultra eq "Sun Blade 1000" | $ultra eq "Sun Blade 2000" | $ultra eq "Sun Fire 280R" | $ultra eq "Netra 20") {
  758.                 foreach $line (@boards_mem) {
  759.                         chop $line;
  760.                         $newline=$line;
  761.                         if ($line eq "-----------------------------------------------------------") {
  762.                                 $newline=$line . "------";
  763.                         } elsif ($line eq "--------------------------------------------------") {
  764.                                 $newline=$line . "--------";
  765.                         } elsif ($line =~ /ControllerID  GroupID   Size/) {
  766.                                 $newline="ID       ControllerID  GroupID   Size    DIMMs    Interleave Way";
  767.                         } elsif ($line =~ /ControllerID   GroupID  Labels/) {
  768.                                 $newline=$line . "                    DIMMs";
  769.                         } elsif ($line =~ /^\d        \d/) {
  770.                                 $simmsize=substr($line,33,5);
  771.                                 if ($simmsize =~ /\dGB/) {
  772.                                         $simmsize =~ s/GB//g;
  773.                                         $simmsize=$simmsize * 1024;
  774.                                 } else {
  775.                                         $simmsize =~ s/MB//g;
  776.                                 }
  777.                                 $simmsize=$simmsize / 2;
  778.                                 push(@simmsizesfound, "$simmsize");
  779.                                 if ($simmsize >= 1024) {
  780.                                         $simmsize=$simmsize / 1024;
  781.                                         $simmsize="${simmsize}GB  ";
  782.                                 } else {
  783.                                         $simmsize="${simmsize}MB  ";
  784.                                 }
  785.                                 if (substr($line,23,1) == 0) {
  786.                                         $grpsize0=$simmsize;
  787.                                 } else {
  788.                                         $grpsize1=$simmsize;
  789.                                 }
  790.                                 $newline=substr($line,0,41) . "2x" . substr($simmsize,0,5) . substr($line,42,10);
  791.                         } elsif ($line =~ /J0100,/) {
  792.                                 $grpsize0 =~ s/ //g;
  793.                                 $newline=$line . "   4x$grpsize0";
  794.                         } elsif ($line =~ /J0101,/) {
  795.                                 $grpsize1 =~ s/ //g;
  796.                                 $newline=$line . "   4x$grpsize1";
  797.                         }
  798.                         push(@new_boards_mem, "$newline\n") if ($newline ne "");
  799.                 }
  800.                 @boards_mem=@new_boards_mem;
  801.         }
  802. }
  803.  
  804. sub found_empty_bank {
  805.         $empty_banks .= "," if ($empty_banks ne "");
  806.         $boardslot_mem =~ s/[: ]//g;
  807.         $empty_banks .= " Board $boardslot_mem @_";
  808. }
  809.  
  810. sub found_nvsimm_bank {
  811.         $nvsimm_banks .= ", Board $boardslot_mem @_";
  812. }
  813.  
  814. sub recommend_prtdiag_patch {
  815.         print "         This may be corrected by installing ";
  816.         if ($sunos eq "5.8") {
  817.                 print "Sun patch 109873-13 or later.\n";
  818.         } else {
  819.                 print "a Sun patch on this system.\n";
  820.         }
  821. }
  822.  
  823. $motherboard="";
  824. $realmodel="";
  825. $manufacturer="";
  826. $i=0;
  827. foreach $line (@config) {
  828.         if ($line =~ /Node /) {
  829.                 $config_permission=1;
  830.         }
  831.         if ($line =~ /banner-name:/ & $banner eq "") {
  832.                 $banner=$line;
  833.                 $banner =~ s/\s+banner-name:\s+//;
  834.                 $banner =~ s/'//g;
  835.                 $banner =~ s/SUNW,//g;
  836.                 $banner =~ s/TWS,//g;
  837.                 $banner =~ s/CYCLE,//g;
  838.                 chop $banner;
  839.                 $ultra="ultra" if ($banner =~ /Ultra/ | $banner =~ /Blade/ | $banner =~ /Fire/);
  840.                 $ultra="sparc64" if ($banner =~ /SPARC64/);
  841.                 $ultra="e" if ($banner =~ /Enterprise/);
  842.                 $ultra=1 if ($banner =~ /Ultra 1\b/);
  843.                 $ultra=2 if ($banner =~ /Ultra 2\b/);
  844.                 $ultra=5 if ($banner =~ /Ultra 5\b/);
  845.                 $ultra="5_10" if ($banner =~ /Ultra 5\/10\b/);
  846.                 $ultra=10 if ($banner =~ /Ultra 10\b/);
  847.                 $ultra=30 if ($banner =~ /Ultra 30\b/);
  848.                 $ultra=60 if ($banner =~ /Ultra 60\b/);
  849.                 $ultra="220R" if ($banner =~ /Enterprise 220R\b/);
  850.                 $ultra=80 if ($banner =~ /Ultra 80[\b\/]/);
  851.                 # E410 is prototype name of E420R, but may still be in the
  852.                 # banner as "Sun Ultra 80/Enterprise 410 UPA/PCI"
  853.                 $ultra="420R" if ($banner =~ /Enterprise 410\b/);
  854.                 $ultra="420R" if ($banner =~ /Enterprise 420R\b/);
  855.                 $ultra=250 if ($banner =~ /\b250\b/);
  856.                 $ultra=450 if ($banner =~ /\b450\b/);
  857.                 $ultra="Netra t1" if ($banner =~ /Netra t1\b/);
  858.                 $ultra="cp1400" if ($banner =~ /Ultra CP 1400\b/);
  859.                 $ultra="cp1500" if ($banner =~ /Ultra CP 1500\b/);
  860.                 $ultra="Sun Blade 1000" if ($banner =~ /Sun Excalibur\b/); # prototype
  861.                 $ultra="Sun Blade 1000" if ($banner =~ /Sun Blade 1000\b/);
  862.                 $ultra="Sun Blade 2000" if ($banner =~ /Sun Blade 2000\b/);
  863.                 $ultra="Netra 20" if ($banner =~ /Netra 20\b/);
  864.                 $ultra="Netra 20" if ($banner =~ /Netra T4\b/);
  865.                 # New Netra T12 system - untested ???
  866.                 $ultra="Netra T12" if ($banner =~ /Netra T12\b/);
  867.                 $ultra="Netra ct400" if ($banner =~ /Netra ct400\b/);
  868.                 $ultra="Netra ct800" if ($banner =~ /Netra ct800\b/);
  869.                 $ultra="Sun Blade 100" if ($banner =~ /Sun Grover\b/); # prototype
  870.                 $ultra="Sun Blade 100" if ($banner =~ /Sun Blade 100\b/);
  871.                 $ultra="Sun Blade 150" if ($banner =~ /Sun Blade 150\b/);
  872.                 $ultra="Sun Fire 280R" if ($banner =~ /Enterprise 820R\b/); # prototype
  873.                 $ultra="Sun Fire 280R" if ($banner =~ /Sun Fire 280R\b/);
  874.                 $ultra="Sun Fire" if ($banner =~ /Serengeti\b/); # prototype
  875.                 $ultra="Sun Fire" if ($banner eq "Sun Fire");
  876.                 $ultra="Sun Fire V480" if ($banner =~ /Sun Fire 480R\b/ | $banner =~ /Sun Fire V480\b/);
  877.                 $ultra="Sun Fire V880" if ($banner =~ /Sun Fire 880\b/ | $banner =~ /Sun Fire V880\b/);
  878.                 $ultra="Sun Fire 15K" if ($banner =~ /Sun Fire 15K\b/);
  879.                 $ultra="Sun Fire 15K" if ($banner =~ /Sun Fire 15000\b/);
  880.                 # New Sun Fire 12K system - untested ???
  881.                 $ultra="Sun Fire 12K" if ($banner =~ /Sun Fire 12K\b/);
  882.                 $ultra="Sun Fire 12K" if ($banner =~ /Sun Fire 12000\b/);
  883.                 if ($banner =~ /Ultra 4FT\b/) {
  884.                         $ultra="Netra ft1800";
  885.                         $bannermore="(Netra ft1800)";
  886.                         $modelmore="(Netra ft1800)";
  887.                 }
  888.                 if ($banner =~ /\bMP-250\b/) {
  889.                         $ultra="axus250";
  890.                         $bannermore="Ultra-250";
  891.                         $modelmore="(Ultra-250)";
  892.                 }
  893.                 $manufacturer="AXUS" if ($ultra =~ /\baxus\b/);
  894.                 $manufacturer="Rave" if ($banner =~ /Axil/);
  895.                 $manufacturer="Cycle" if ($banner =~ /Cycle/);
  896.                 $manufacturer="Tadpole" if ($banner =~ /Tadpole/ | $banner =~ /\bRDI\b/ | $banner =~ /\bVoyagerIIi\b/);
  897.                 $manufacturer="Tatung" if ($banner =~ /COMPstation/);
  898.                 $manufacturer="Twinhead" if ($banner =~ /TWINstation/);
  899.                 $manufacturer="Fujitsu" if ($banner =~ /Fujitsu/);
  900.                 $manufacturer="Fujitsu Siemens" if ($banner =~ /Fujitsu Siemens/);
  901.                 # Only add "Sun" to those that don't already have it
  902.                 $manufacturer="Sun" if ($banner =~ /^SPARCstation/ |
  903.                         $banner =~ /^SPARCsystem/ | $banner =~ /^SPARCclassic/ |
  904.                         $banner =~ /^SPARCserver/ | $banner =~ /^SPARCcenter/ |
  905.                         $banner =~ /Enterprise/ | $banner =~ /Premier 24/);
  906.         }
  907.         if ($line =~ /model:.*AXUS/) {
  908.                 # AXUS clones with their name on OBP
  909.                 $manufacturer="AXUS";
  910.         }
  911.         if ($line =~ /SUNW,Ultra-/ | $line =~ /SUNW,SPARC/ | $line =~ /Sun.4/ |
  912.             $line =~ /SUNW,S240/ | $line =~ /SUNW,Ultra.*Engine/ |
  913.             $line =~ /SUNW,Ultra.*Netra*/ |
  914.             $line =~ /SUNW,Premier-24/ | $line =~ /SUNW,UltraAX-/ |
  915.             $line =~ /SUNW,Netra/ | $line =~ /\s+name:.*SUNW,Sun-/ |
  916.             $line =~ /SUNW,Grover/ | $line =~ /SUNW,Enterprise/ |
  917.             $line =~ /\s+name:.*'i86pc'/ | $line =~ /^i86pc/ |
  918.             $line =~ /model:\s+'SPARC CPU-/ | $line =~ /model:\s+'SPARC CPCI-/ |
  919.             $line =~ /SUNW,Axil-/ | $line =~ /\s+name:.*COMPstation/ |
  920.             $line =~ /\s+name:.*Tadpole/ | $line =~ /\s+name:.*Auspex/ |
  921.             $line =~ /\s+name:.*S-4/ | $line =~ /\s+name:.*FJSV,GP/ |
  922.             $line =~ /\s+name:.*CompuAdd/ | $line =~ /\s+name:.*RDI,/) {
  923.                 $model=$line;
  924.                 $model =~ s/\s+name:\s+//;
  925.                 $model =~ s/\s+model:\s+//;
  926.                 $model =~ s/'//g;
  927.                 chop $model;
  928.                 if ($filename ne "") {
  929.                         $platform=$model;
  930.                         $prtdiag_cmd="/usr/platform/$platform/sbin/prtdiag" if ($prtdiag_cmd =~ /platform/);
  931.                 }
  932.                 $model =~ s/SUNW,//g;
  933.                 $model =~ s/TWS,//g;
  934.                 $model =~ s/CYCLE,//g;
  935.                 $model =~ s/Tadpole_//g;
  936.                 $model =~ s/ASPX,//g;
  937.                 $model =~ s/PFU,//g;
  938.                 $model =~ s/FJSV,//g;
  939.                 $model =~ s/CompuAdd //g;
  940.                 $model =~ s/RDI,//g;
  941.                 if ($ultra eq 0) {
  942.                         $ultra="ultra" if ($model =~ /Ultra/ | $model =~ /Blade/ | $model =~ /Fire/);
  943.                 }
  944.                 $ultra="sparc64" if ($model =~ /SPARC64/);
  945.                 $ultra=1 if ($model =~ /Ultra-1\b/);
  946.                 $ultra=2 if ($model =~ /Ultra-2\b/);
  947.                 $ultra=5 if ($model =~ /Ultra-5\b/);
  948.                 $ultra="5_10" if ($model =~ /Ultra-5_10\b/);
  949.                 $ultra=30 if ($model =~ /Ultra-30\b/);
  950.                 $ultra=60 if ($model =~ /Ultra-60\b/);
  951.                 $ultra=80 if ($model =~ /Ultra-80[\b\/]/);
  952.                 $ultra=250 if ($model =~ /Ultra-250\b/);
  953.                 $ultra=450 if ($model =~ /Ultra-4\b/);
  954.                 $ultra="Netra t1" if ($banner =~ /Netra t1\b/);
  955.                 if ($model =~ /Ultra-4FT\b/) {
  956.                         $ultra="Netra ft1800";
  957.                         $bannermore="(Netra ft1800)";
  958.                         $modelmore="(Netra ft1800)";
  959.                 }
  960.                 $ultra="Sun Blade 1000" if ($model =~ /Ultra-100\b/); # prototype
  961.                 $ultra="Sun Blade 1000" if ($model =~ /Sun-Blade-1000\b/);
  962.                 $ultra="Sun Blade 2000" if ($model =~ /Sun-Blade-2000\b/);
  963.                 $ultra="Netra 20" if ($model =~ /Netra-20\b/);
  964.                 $ultra="Netra 20" if ($model =~ /Netra-T4\b/);
  965.                 $ultra="Netra T12" if ($model =~ /Netra-T12\b/);
  966.                 $ultra="Sun Blade 100" if ($model =~ /Grover\b/); # prototype
  967.                 $ultra="Sun Blade 100" if ($model =~ /Sun-Blade-100\b/);
  968.                 $ultra="Sun Fire 280R" if ($model =~ /Enterprise-820R\b/); # prototype
  969.                 $ultra="Sun Fire 280R" if ($model =~ /Sun-Fire-280R\b/);
  970.                 $ultra="Sun Fire" if ($model =~ /Serengeti\b/); # prototype
  971.                 $ultra="Sun Fire" if ($model eq "Sun-Fire");
  972.                 $ultra="Sun Fire V480" if ($model =~ /Sun-Fire-480R\b/);
  973.                 $ultra="Sun Fire V880" if ($model =~ /Sun-Fire-880\b/);
  974.                 $ultra="Sun Fire 15K" if ($model =~ /Sun-Fire-15000\b/);
  975.                 # New Sun Fire 12K system - untested ???
  976.                 $ultra="Sun Fire 12K" if ($model =~ /Sun-Fire-12000\b/);
  977.                 $ultra="e" if ($model =~ /Ultra-Enterprise/);
  978.                 if ($banner =~ /\bMP-250\b/) {
  979.                         $ultra="axus250";
  980.                         $bannermore="Ultra-250";
  981.                         $modelmore="(Ultra-250)";
  982.                 }
  983.                 $manufacturer="AXUS" if ($ultra =~ /axus/);
  984.                 $modelmore="SPARCstation SLC" if ($model eq "Sun 4/20");
  985.                 $modelmore="SPARCstation ELC" if ($model eq "Sun 4/25");
  986.                 $modelmore="SPARCstation IPC" if ($model eq "Sun 4/40");
  987.                 $modelmore="SPARCstation IPX" if ($model eq "Sun 4/50");
  988.                 $modelmore="SPARCstation 1" if ($model eq "Sun 4/60");
  989.                 $modelmore="SPARCstation 1+" if ($model eq "Sun 4/65");
  990.                 $modelmore="SPARCstation 2" if ($model eq "Sun 4/75");
  991.                 $modelmore="(SPARCsystem 600)" if ($model =~ /Sun.4.600/ & $banner !~ /SPARCsystem/);
  992.                 $modelmore="Sun 4/30" if ($model =~ /SPARCstation-LX/);
  993.                 $modelmore="Sun 4/15" if ($model =~ /SPARCclassic/);
  994.                 $modelmore="Sun 4/10" if ($model =~ /SPARCclassic-X/);
  995.                 $modelmore="(SPARCstation 10SX)" if ($model =~ /Premier-24/);
  996.                 if ($model eq "i86pc") {
  997.                         $modelmore="(Solaris on Intel-based (x86) machine)";
  998.                         $cputype="x86";
  999.                         if ($filename eq "" & -x '/usr/sbin/psrinfo') {
  1000.                                 $ncpu=`/usr/sbin/psrinfo | wc -l`;
  1001.                                 $ncpu =~ s/\s+//;
  1002.                                 chop $ncpu;
  1003.                                 @psrinfo=`/usr/sbin/psrinfo -v`;
  1004.                                 if ($psrinfo[2] =~ /MHz/) {
  1005.                                         $cpufreq=$psrinfo[2];
  1006.                                         $cpufreq =~ s/.+ operates at //;
  1007.                                         $cpufreq =~ s/ MHz.+//;
  1008.                                         chop $cpufreq;
  1009.                                 }
  1010.                         }
  1011.                 }
  1012.                 if ($model eq "S240") {
  1013.                         $manufacturer="Sun";
  1014.                         $modelmore="SPARCstation Voyager";
  1015.                 }
  1016.                 if ($model =~ /SPARC CP/) {
  1017.                         $manufacturer="Force Computers";
  1018.                 }
  1019.                 if ($model eq "S3GX") {
  1020.                         $bannermore="(SPARCbook 3GX)";
  1021.                         $modelmore="(SPARCbook 3GX)";
  1022.                 }
  1023.                 if ($model eq "S3XP") {
  1024.                         $bannermore="(SPARCbook 3XP)";
  1025.                         $modelmore="(SPARCbook 3XP)";
  1026.                 }
  1027.                 $manufacturer="Sun" if ($model =~ /^SPARCstation/ |
  1028.                         $model =~ /^SPARCsystem/ | $model =~ /^SPARCclassic/ |
  1029.                         $model =~ /^SPARCserver/ | $model =~ /^SPARCcenter/ |
  1030.                         $model =~ /Enterprise/ | $model =~ /Premier 24/);
  1031.                 if ($model =~ /Auspex/) {
  1032.                         $manufacturer="Auspex";
  1033.                         $model =~ s/Auspex //g;
  1034.                         $bannermore="Netserver";
  1035.                         $modelmore="Netserver";
  1036.                 }
  1037.                 if ($model =~ /S-4/ | $model eq "GP" | $model eq "GPUS") {
  1038.                         $manufacturer="Fujitsu" if ($manufacturer eq "");
  1039.                         $model =~ s,_,/,g;
  1040.                 }
  1041.                 if ($line =~ /CompuAdd/) {
  1042.                         $manufacturer="CompuAdd";
  1043.                         if ($model eq "SS-2") {
  1044.                                 $banner=$model if ($banner eq "");
  1045.                                 $bannermore="SPARCstation 2";
  1046.                                 $modelmore="SPARCstation 2";
  1047.                         }
  1048.                 }
  1049.                 if ($model =~ /PowerLite-/) {
  1050.                         $bannermore=$model;
  1051.                         $bannermore =~ s/PowerLite-//g;
  1052.                 }
  1053.         }
  1054.         $foundname=1 if ($line =~ /\s+name:\s+/);
  1055.         if ($line =~ /\s+model:\s+'.+,/ & $foundname == 0) {
  1056.                 # Ultra 5/10 motherboard is 375-xxxx part number
  1057.                 # SS10/SS20 motherboard is Sxx,501-xxxx part number
  1058.                 if ($line =~ /,375-/ | $line =~ /,500-/ | $line =~ /,501-/) {
  1059.                         $motherboard=$line;
  1060.                         $motherboard =~ s/\s+model:\s+//;
  1061.                         $motherboard =~ s/'//g;
  1062.                         chop $motherboard;
  1063.                 }
  1064.         }
  1065.         if ($line =~ /\sname:\s+'memory'/) {
  1066.                 $j=$i - 2;
  1067.                 if ($config[$j] =~ /\sreg:\s/) {
  1068.                         $gotmemory=$config[$j];
  1069.                         chop $gotmemory;
  1070.                 } elsif ($config[$j - 1] =~ /\sreg:\s/) {
  1071.                         $gotmemory=$config[$j - 1];
  1072.                         chop $gotmemory;
  1073.                 } elsif ($config[$j + 1] =~ /\sreg:\s/) {
  1074.                         $gotmemory=$config[$j + 1];
  1075.                         chop $gotmemory;
  1076.                 }
  1077.         }
  1078.         if ($line =~ /\sdevice_type:\s+'memory-bank'/) {
  1079.                 $j=$i - 3;
  1080.                 if ($config[$j] =~ /\sreg:\s/ & $config[$j] !~ /.00000000$/) {
  1081.                         $config[$j] =~ s/\s+reg:\s+//;
  1082.                         if ($gotmemory) {
  1083.                                 $gotmemory .= ".$config[$j]";
  1084.                         } else {
  1085.                                 $gotmemory=$config[$j];
  1086.                         }
  1087.                         chop $gotmemory;
  1088.                 }
  1089.         }
  1090.         # The following is not used yet
  1091.         #if ($line =~ /\sdevice_type:\s+'memory-module'/) {
  1092.         #       if ($config[$i - 2] =~ /\sreg:\s/) {
  1093.         #               $config[$i - 3] =~ s/\s+socket-name:\s+//;
  1094.         #               if ($gotmodule) {
  1095.         #                       $gotmodule .= ".$config[$i - 3]";
  1096.         #               } else {
  1097.         #                       $gotmodule=$config[$i - 3];
  1098.         #               }
  1099.         #               chop $gotmodule;
  1100.         #               $config[$i - 2] =~ s/\s+reg:\s+//;
  1101.         #               @module=split(/\./, $config[$i - 2]);
  1102.         #               $gotmodule .= ".$module[3]";
  1103.         #               chop $gotmodule;
  1104.         #               $config[$i + 1] =~ s/\s+name:\s+//;
  1105.         #               $config[$i + 1] =~ y/[a-z]/[A-Z]/;
  1106.         #               $gotmodule .= ".$config[$i + 1]";
  1107.         #               chop $gotmodule;
  1108.         #               $gotmodule =~ s/'//g;
  1109.         #       }
  1110.         #}
  1111.         if ($line =~ /\ssimm-use:\s+/) {
  1112.                 # DIMM usage on Fujitsu GP7000
  1113.                 $gotmodule=$config[$i];
  1114.                 $gotmodule =~ s/\s+simm-use:\s+//;
  1115.                 chop $gotmodule;
  1116.                 $slotname0="SLOT0" if ($banner =~ /GP7000\b/);
  1117.         }
  1118.         if ($line =~ /\sdevice_type:\s+'memory-module'/) {
  1119.                 # DIMM usage on Fujitsu GP7000F and PrimePower systems
  1120.                 $slotname="";
  1121.                 if ($config[$i - 3] =~ /\scomponent-name:\s/) {
  1122.                         $slotname=$config[$i - 3];
  1123.                 }
  1124.                 if ($config[$i - 4] =~ /\scomponent-name:\s/) {
  1125.                         $slotname=$config[$i - 4];
  1126.                 }
  1127.                 if ($slotname ne "") {
  1128.                         $slotname =~ s/\s+component-name:\s+//;
  1129.                         $slotname =~ s/'//g;
  1130.                         chop $slotname;
  1131.                         if ($gotmodulenames) {
  1132.                                 $gotmodulenames .= ".$slotname";
  1133.                         } else {
  1134.                                 $gotmodulenames=$slotname;
  1135.                         }
  1136.                         $slotname0=$slotname if (! $slotname0);
  1137.                         $config[$i - 1] =~ s/\s+reg:\s+//;
  1138.                         @module=split(/\./, $config[$i - 1]);
  1139.                         $gotmodulenames .= ".$module[1]";
  1140.                         chop $gotmodulenames;
  1141.                 }
  1142.         }
  1143.         if ($line =~ /\sname:\s+'cgfourteen'/) {
  1144.                 # Determine size of VSIMM
  1145.                 # Currently assumes only one VSIMM is installed
  1146.                 if ($config[$i - 2] =~ /\sreg:\s/) {
  1147.                         $sx_line=$config[$i - 2];
  1148.                         chop $sx_line;
  1149.                 } elsif ($config[$i - 3] =~ /\sreg:\s/) {
  1150.                         $sx_line=$config[$i - 3];
  1151.                         chop $sx_line;
  1152.                 }
  1153.                 @sxline=split(/\./, $sx_line);
  1154.                 $sxmem=hex("0x$sxline[5]") / $meg;
  1155.         }
  1156.         if ($line =~ /501-2197/) {
  1157.                 # 1MB Prestoserve NVSIMMs (SS1000/SC2000)
  1158.                 if ($config[$i + 1] =~ /\sreg:\s/) {
  1159.                         $nv_line=$config[$i + 1];
  1160.                         chop $nv_line;
  1161.                 } elsif ($config[$i + 2] =~ /\sreg:\s/) {
  1162.                         $nv_line=$config[$i + 2];
  1163.                         chop $nv_line;
  1164.                 }
  1165.                 @nvline=split(/\./, $nv_line);
  1166.                 $nvmem += hex("0x$nvline[2]") / $meg;
  1167.         }
  1168.         if ($line =~ /501-2001/) {
  1169.                 # 2MB Prestoserve NVSIMMs (SS10/SS20)
  1170.                 if ($config[$i + 1] =~ /\sreg:\s/) {
  1171.                         $nv_line=$config[$i + 1];
  1172.                         chop $nv_line;
  1173.                 } elsif ($config[$i + 2] =~ /\sreg:\s/) {
  1174.                         $nv_line=$config[$i + 2];
  1175.                         chop $nv_line;
  1176.                 }
  1177.                 @nvline=split(/\./, $nv_line);
  1178.                 $nvmem += hex("0x$nvline[2]") / $meg;
  1179.                 $nvmem1=1 if ($nvline[1] eq "10000000");
  1180.                 $nvmem2=1 if ($nvline[1] eq "14000000" | $nvline[1] eq "1c000000");
  1181.         }
  1182.         if ($line =~ /Memory size:\s/ & $installed_memory == 0) {
  1183.                 $memory_size=$line;
  1184.                 chop $memory_size;
  1185.                 @memory=split(/\s/, $memory_size);
  1186.                 $installed_memory=$memory[2];
  1187.                 $installed_memory =~ s/Mb//;
  1188.                 $BSD=0; # prtconf and prtdiag only have this output
  1189.                 $config_cmd="/usr/sbin/prtconf -pv" if ($config_cmd !~ /prtconf/);
  1190.                 $config_command="prtconf";
  1191.         }
  1192.         if ($sysfreq == 0 & $freq > 0) {
  1193.                 $sysfreq=$freq;
  1194.                 $freq=0;
  1195.         }
  1196.         if ($devtype eq "cpu") {
  1197.                 $cpufreq=$freq;
  1198.                 if ($cpufreq == 0 | $cputype eq "") {
  1199.                         $cpuline=$line;
  1200.                         $j=$i;
  1201.                         while ($cpuline !~ /^$/) {
  1202.                                 if ($cpuline =~ /clock-frequency:/) {
  1203.                                         @freq_line=split(' ', $cpuline);
  1204.                                         if ($model eq "i86pc") {
  1205.                                                 $cpufreq=int(hex("0x$freq_line[1]") / 10000 + 0.5);
  1206.                                         } else {
  1207.                                                 $cpufreq=int(hex("0x$freq_line[1]") / 1000000 + 0.5);
  1208.                                         }
  1209.                                 }
  1210.                                 if ($cpuline =~ /\sname:\s/ & $cpuline !~ /Sun 4/ & $cpuline !~ /SPARCstation/ & $cpuline !~ /CompuAdd/) {
  1211.                                         $cputype=$cpuline;
  1212.                                         $cputype =~ s/\s+name:\s+//;
  1213.                                         $cputype =~ s/'//g;
  1214.                                         $cputype =~ s/SUNW,//g;
  1215.                                         chop $cputype;
  1216.                                 }
  1217.                                 $j++;
  1218.                                 if ($config[$j]) {
  1219.                                         $cpuline=$config[$j];
  1220.                                 } else {
  1221.                                         $cpuline="";
  1222.                                 }
  1223.                         };
  1224.                 }
  1225.                 $freq=0;
  1226.                 $devtype="";
  1227.                 $ncpu++;
  1228.         }
  1229.         if ($line =~ /device_type:/) {
  1230.                 @dev_line=split(/\'/, $line);
  1231.                 $devtype=$dev_line[1];
  1232.         }
  1233.         if ($line =~ /clock-frequency:/) {
  1234.                 @freq_line=split(' ', $line);
  1235.                 if ($model eq "i86pc") {
  1236.                         $freq=int(hex("0x$freq_line[1]") / 10000 + 0.5);
  1237.                 } else {
  1238.                         $freq=int(hex("0x$freq_line[1]") / 1000000 + 0.5);
  1239.                 }
  1240.         }
  1241.         if ($line =~ /\sversion:\s+'OBP/ & $romver eq "") {
  1242.                 $romver=$line;
  1243.                 $romver =~ s/\s+version:\s+//;
  1244.                 $romver =~ s/'//g;
  1245.                 chop $romver;
  1246.                 @romverarr=split(/\s/, $romver);
  1247.                 $romvernum=$romverarr[1];
  1248.         }
  1249.         if ($line =~ /compatible:\s+'sun4/ & $sunos eq "") {
  1250.                 @compatible_line=split(/\'/, $line);
  1251.                 $machine=$compatible_line[1];
  1252.         }
  1253.         $i++;
  1254. }
  1255. if ($sunos eq "") {
  1256.         if ($BSD) {
  1257.                 $sunos="4.X";
  1258.                 $config_cmd="/usr/etc/devinfo -pv";
  1259.                 $config_command="devinfo";
  1260.         } else {
  1261.                 $sunos="5.X";
  1262.                 $solaris="2.X";
  1263.                 $config_cmd="/usr/sbin/prtconf -pv";
  1264.                 $config_command="prtconf";
  1265.         }
  1266. }
  1267. $sysfreq=$freq if ($sysfreq == 0 & $freq > 0);
  1268. $cpufreq=$sysfreq if ($sysfreq > $cpufreq & $ncpu > 0);
  1269. if ($cputype eq "") {
  1270.         $cputype=$machine;
  1271.         $cputype="SPARC" if ($cputype =~ /^sun4/);
  1272.         @bannerarr=split(/\s/, $banner);
  1273.         foreach $field (@bannerarr) {
  1274.                 if ($field =~ /SPARC/ & $field !~ /SPARCstation/) {
  1275.                         $cputype=$field;
  1276.                 } elsif ($field =~ /390Z5/) {
  1277.                         $field="TI,TMS$field" if ($field =~ /^390Z5/);
  1278.                         if ($cpufreq > 70) {
  1279.                                 $cputype="SuperSPARC-II $field";
  1280.                         } else {
  1281.                                 $cputype="SuperSPARC $field";
  1282.                         }
  1283.                 } elsif ($field =~ /RT62[56]/) {
  1284.                         $cputype="hyperSPARC $field";
  1285.                         $machine="sun4m";
  1286.                 }
  1287.         }
  1288.         $cputype =~ s/[()]//g;
  1289. } elsif ($cputype =~ /MB86904/ | $cputype =~ /390S10/) {
  1290.         if ($cpufreq > 70) {
  1291.                 $cputype="microSPARC-II $cputype";
  1292.         } else {
  1293.                 $cputype="microSPARC $cputype";
  1294.         }
  1295. } elsif ($cputype =~ /^Ross,RT62[56]/) {
  1296.         $cputype="hyperSPARC $cputype";
  1297.         $machine="sun4m";
  1298. }
  1299. @romverarr=split(/\./, $romvernum) if ($romver);
  1300. $romvermajor=($romverarr[0]) ? $romverarr[0] : 2;
  1301. $romverminor=($romverarr[1]) ? $romverarr[1] : 0;
  1302. $romverminor=0 if ($romverminor eq "" | $romverminor eq "X");
  1303. if ($banner =~ /^ \(/) {
  1304.         # banner-name does not include the eeprom banner name. This happens
  1305.         # sometimes when OBP 3.23 is installed on Ultra-60/E220R and
  1306.         # Ultra-80/E420R systems.
  1307.         $bannermore="Ultra 60 or Enterprise 220R" if ($model eq "Ultra-60");
  1308.         $bannermore="Ultra 80 or Enterprise 420R" if ($model eq "Ultra-80");
  1309. }
  1310. #
  1311. # SPARCengine systems
  1312. #
  1313. $ultra="AX" if ($motherboard =~ /501-3043/);
  1314. $ultra="AX-300" if ($motherboard =~ /501-5037/);
  1315. $ultra="AXi" if ($motherboard =~ /501-4559/);
  1316. $ultra="AXmp" if ($banner =~ /UltraAX-MP/ | $model =~ /UltraAX-MP/ | $motherboard =~ /501-5296/ | $motherboard =~ /501-5487/ | $motherboard =~ /501-5670/);
  1317. $ultra="AXmp+" if ($banner =~ /UltraAX-MP\+/ | $model =~ /UltraAX-MP\+/ | $motherboard =~ /501-4324/);
  1318. $ultra="AXe" if ($banner =~ /UltraAXe\b/ | $model =~ /UltraAX-e\b/ | $motherboard =~ /375-0088/);
  1319. $ultra="AX-e2" if ($banner =~ /Netra AX1105-500\b/ | $model =~ /UltraAX-e2\b/ | $motherboard =~ /375-0128/);
  1320. $ultra="Netra X1" if ($banner =~ /Netra X1\b/ | $motherboard =~ /375-3015/);
  1321. $ultra="Netra T1 200" if ($banner =~ /Netra T1 200\b/ | $motherboard =~ /375-0132/);
  1322. $ultra="Sun Fire V100" if ($banner =~ /Sun Fire V100\b/);
  1323. # Sun Fire V120/Netra 120 can use motherboard 375-0132 like Netra T1 200 above
  1324. $ultra="Sun Fire V120" if ($banner =~ /Sun Fire V120\b/);
  1325. $ultra="Netra 120" if ($banner =~ /Netra 120\b/);
  1326. if ($ultra =~ /AX/) {
  1327.         if ($banner !~ /SPARCengine.*Ultra/) {
  1328.                 if ($bannermore) {
  1329.                         $bannermore="(SPARCengine Ultra $ultra) $bannermore";
  1330.                 } else {
  1331.                         $bannermore="(SPARCengine Ultra $ultra)";
  1332.                 }
  1333.         }
  1334. }
  1335. if ($model =~ /Ultra-5_10\b/) {
  1336.         if ($banner =~ /\bVoyagerIIi\b/) {
  1337.                 # Tadpole Voyager IIi has 8 DIMM slots, but prtconf reports
  1338.                 # it as an Ultra 5/10
  1339.                 $model="VoyagerIIi";
  1340.                 $ultra="VoyagerIIi";
  1341.         }
  1342. }
  1343. $ultra="Sun Blade 150" if ($motherboard =~ /375-3063/ | $motherboard =~ /375-3088/);
  1344.  
  1345. $need_obp2=0;
  1346. if ($model eq "Sun 4/20" | $model eq "Sun 4/25" | $model eq "Sun 4/40" | $model eq "Sun 4/50" | $model eq "Sun 4/60" | $model eq "Sun 4/65" | $model eq "Sun 4/75" | $model eq "SS-2") {
  1347.         $machine="sun4c";
  1348.         if ($model eq "Sun 4/40" | $model eq "Sun 4/60" | $model eq "Sun 4/65") {
  1349.                 $need_obp2=1;
  1350.         }
  1351. }
  1352. if ($gotmemory eq "") {
  1353.         &show_header;
  1354.         print "total memory = ${installed_memory}MB\n" if ($installed_memory);
  1355.         print "ERROR: no 'memory' line in \"$config_cmd\" output.\n";
  1356.         if (! $config_permission & $machine =~ /sun4/) {
  1357.                 print "       This user may not have permission to run $config_command.\n";
  1358.                 print "       Try running memconf as a privileged user like root.\n";
  1359.         } elsif ($need_obp2) {
  1360.                 print "       Upgrading from Open Boot PROM V1.X to V2.X will ";
  1361.                 print "allow memconf to\n       detect the memory installed.\n";
  1362.         } else {
  1363.                 print "       This is an unsupported system by memconf.\n";
  1364.         }
  1365.         if ($machine !~ /sun4/) {
  1366.                 print "       Currently it is only supported on SPARC systems, not on $machine systems.\n";
  1367.         }
  1368.         $exitstatus=1;
  1369.         &mailmaintainer if ($verbose == 3);
  1370.         exit $exitstatus;
  1371. }
  1372.  
  1373. $gotmemory =~ s/\s+reg:\s+//;
  1374. $gotmemory =~ s/'//g;
  1375. @slots=split(/\./, $gotmemory);
  1376. $slot=1;
  1377. $totmem=0;
  1378. #$start1x=0;
  1379. $manufacturer="" if (($banner =~ /^Sun\b/ | $model =~ /^Sun\b/) & $manufacturer eq "Sun");
  1380. if ($manufacturer ne "" & $manufacturer ne "Sun") {
  1381.         if ($manufacturer ne "Force Computers") {
  1382.                 $bannermore=($bannermore) ? "$bannermore clone" : "clone";
  1383.         }
  1384.         $modelmore=($modelmore) ? "$modelmore clone" : "clone";
  1385.         $clone=1;
  1386. }
  1387. # DIMMs are installed in pairs on Ultra 1, 5 and 10; quads on
  1388. # Ultra 2, 60, 80, 220R, 420R, 450; 8's in Ultra Enterprise
  1389. #
  1390. # On 64-bit systems, prtconf format is AAAAAAAA.AAAAAAAA.SSSSSSSS.SSSSSSSS
  1391. # and on 32-bit systems, prtconf format is AAAAAAAA.AAAAAAAA.SSSSSSSS
  1392. # where A is for Address, S is for Size.
  1393. # Minimum module size is 1MB (0x00100000), so strip off last 5 hex digits of LSB
  1394. # and prepend last 5 digits of MSB, which allows recognizing up to 4500TB!
  1395. #
  1396. if ($ultra) {
  1397.         $val0=3;        # simmsize is in 3rd and 4th fields
  1398.         $valaddr=2;     # address is 2 fields before simmsize
  1399.         $valinc=4;      # fields per simm
  1400.         $memtype="DIMM";
  1401. } else {
  1402.         $val0=2;        # simmsize is in 3rd field
  1403.         $valaddr=1;     # address is 1 field before simmsize
  1404.         $valinc=3;      # fields per simm
  1405. }
  1406.  
  1407. #
  1408. # Define memory layout for specific systems
  1409. #
  1410. if ($model eq "Sun 4/20") {
  1411.         # SLC accepts 4MB SIMMs on motherboard
  1412.         #   501-1676 (4MB 100ns), 501-1698 (4MB 80ns)
  1413.         #   33-bit 72-pin Fast Page Mode (36-bit work also)
  1414.         # Does not support Open Boot PROM V2.X, so devinfo/prtconf output will
  1415.         # not have memory lines.
  1416.         $devname="OffCampus";
  1417.         $untested=1;
  1418.         $simmrangex="00000010";
  1419.         $simmbanks=4;
  1420.         $simmsperbank=1;
  1421.         @simmsizes=(4);
  1422.         @socketstr=("U0502","U0501","U0602","U0601");
  1423. }
  1424. if ($model eq "Sun 4/25") {
  1425.         # ELC accepts 4MB or 16MB SIMMs on motherboard
  1426.         #   501-1698 or 501-1812 (4MB 80ns), 501-1822 (16MB 80ns)
  1427.         #   33-bit 72-pin Fast Page Mode (36-bit work also)
  1428.         $devname="NodeWarrior";
  1429.         $untested=0;
  1430.         $simmrangex="00000010";
  1431.         $simmbanks=4;
  1432.         $simmsperbank=1;
  1433.         @simmsizes=(4,16);
  1434.         @socketstr=("U0407","U0408","U0409","U0410");
  1435.         @bankstr=("MEM1","MEM2","MEM3","MEM4");
  1436. }
  1437. if ($model eq "Sun 4/40") {
  1438.         # IPC accepts 1MB or 4MB SIMMs on motherboard
  1439.         #   501-1697 (1MB 80ns), 501-1625 (4MB 100ns), 501-1739 (4MB 80ns)
  1440.         # Does not show memory with Open Boot PROM V1.X, but does with OBP V2.X
  1441.         $devname="Phoenix";
  1442.         $untested=0;
  1443.         $simmrangex="00000010";
  1444.         $simmbanks=3;
  1445.         $simmsperbank=4;
  1446.         @simmsizes=(1,4);
  1447.         @socketstr=("U0588","U0587","U0586","U0585","U0584","U0591","U0590","U0589","U0678","U0676","U0683","U0677");
  1448.         @bankstr=(0,0,0,0,1,1,1,1,2,2,2,2);
  1449.         @bytestr=(0,1,2,3,0,1,2,3,0,1,2,3);
  1450. }
  1451. if ($model eq "Sun 4/50") {
  1452.         # IPX accepts 4MB or 16MB SIMMs on motherboard
  1453.         #   501-1812 (4MB 80ns), 501-1915 or 501-1822 (16MB 80ns)
  1454.         #   33-bit 72-pin Fast Page Mode (36-bit work also)
  1455.         $devname="Hobbes";
  1456.         $untested=0;
  1457.         $simmrangex="00000010";
  1458.         $simmbanks=4;
  1459.         $simmsperbank=1;
  1460.         @simmsizes=(4,16);
  1461.         @socketstr=("U0310","U0309","U0308","U0307");
  1462.         @bankstr=(0,1,2,3);
  1463. }
  1464. if ($model eq "Sun 4/60" | $model eq "Sun 4/65") {
  1465.         # SS1 and SS1+ accepts 1MB or 4MB SIMMs on motherboard
  1466.         #   501-1408 (1MB 100ns), 501-1697 (SS1+ only) (1MB 80ns),
  1467.         #   501-1625 (4MB 100ns), 501-1739 (4MB 80ns)
  1468.         # Does not show memory with Open Boot PROM V1.X, but does with OBP V2.X
  1469.         if ($model eq "Sun 4/60") {
  1470.                 $devname="Campus";
  1471.                 $untested=0;
  1472.         } else {
  1473.                 $devname="CampusB";
  1474.                 $untested=1;
  1475.         }
  1476.         $simmrangex="00000010";
  1477.         $simmbanks=4;
  1478.         $simmsperbank=4;
  1479.         @simmsizes=(1,4);
  1480.         @socketstr=("U0588","U0587","U0586","U0585","U0584","U0591","U0590","U0589","U0678","U0676","U0683","U0677","U0682","U0681","U0680","U0679");
  1481.         @bankstr=(0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3);
  1482.         @bytestr=(0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3);
  1483. }
  1484. if ($model eq "Sun 4/75" | $model eq "SS-2") {
  1485.         # SS2 accepts 4MB SIMMs on motherboard and 32MB or 64MB SBus expansion
  1486.         # card (501-1823 Primary and 501-1824 Secondary)
  1487.         #   501-1739 (4MB 80ns)
  1488.         $devname="Calvin";
  1489.         $untested=0;
  1490.         $simmrangex="00000010";
  1491.         $simmbanks=4;
  1492.         $simmsperbank=4;
  1493.         @simmsizes=(4);
  1494.         @socketstr=("U0311","U0309","U0307","U0322","U0312","U0310","U0308","U0321","U0313","U0314","U0315","U0320","U0319","U0318","U0317","U0316");
  1495.         @bankstr=(0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3);
  1496.         @bytestr=(0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3);
  1497. }
  1498. if ($model =~ /SPARCclassic/ | $model =~ /SPARCstation-LX/) {
  1499.         # Classic-X (4/10) accepts 1MB, 2MB, 4MB and 16MB SIMMs on motherboard
  1500.         # Classic (4/15) and LX (4/30) accepts 4MB and 16MB SIMMs on motherboard
  1501.         # Can accept 32MB SIMMs in bank 1, allowing 128MB total (2x32, 4x16)
  1502.         # Possibly accepts 8MB SIMMs in bank 1
  1503.         #   501-2289 (1MB), 501-2433 (2MB) on Classic-X only
  1504.         #   501-1991 (4MB), 501-2059 (16MB)
  1505.         #   36-bit 72-pin 60ns Fast Page Mode
  1506.         $devname="Sunergy";
  1507.         if ($model =~ /SPARCclassic-X/) {
  1508.                 $untested=1;
  1509.                 @simmsizes=(1,2,4,8,16,32);
  1510.         } else {
  1511.                 $untested=0;
  1512.                 @simmsizes=(4,8,16,32);
  1513.         }
  1514.         $simmrangex="00000020";
  1515.         $simmbanks=3;
  1516.         $simmsperbank=2;
  1517.         @socketstr=("U0304","U0303","U0301","U0302","U0402","U0401");
  1518.         @bankstr=(1,1,2,2,3,3);
  1519. }
  1520. if ($model eq "S240") {
  1521.         # Voyager has 16MB on motherboard, plus accepts one or two 16MB or 32MB
  1522.         # Memory cards (501-2327 32MB, 501-2366 16MB)
  1523.         # Motherboard, address 0x00000000-0x007fffff, 0x01000000-0x017fffff
  1524.         # Lower slot=Mem 1, address 0x02000000-0x07ffffff
  1525.         # Upper slot=Mem 2, address 0x0a000000-0x0fffffff
  1526.         $devname="Gypsy";
  1527.         $untested=0;
  1528.         $memtype="memory card";
  1529.         $sockettype="slot";
  1530.         $simmrangex="00000020";
  1531.         $simmbanks=8;   # Count the skipped address range
  1532.         $simmsperbank=1;
  1533.         @simmsizes=(16,32);
  1534.         @socketstr=("motherboard","Mem 1","Mem 1","Mem 1","?","Mem 2","Mem 2","Mem 2");
  1535.         @orderstr=("","lower slot","lower slot","lower slot","?","upper slot","upper slot","upper slot");
  1536. }
  1537. if ($model eq "SPARCstation-4") {
  1538.         # Accepts 8MB and 32MB SIMMs on motherboard
  1539.         #   501-2470 (8MB), 501-2471 (32MB)
  1540.         #   168-pin 60ns Fast Page Mode
  1541.         $devname="Perigee";
  1542.         $untested=0;
  1543.         $simmrangex="00000020";
  1544.         $simmbanks=5;
  1545.         $simmsperbank=1;
  1546.         @simmsizes=(8,32);
  1547.         @socketstr=("J0301","J0302","J0303","J0304","J0305");
  1548.         @bankstr=(0,1,2,3,4);
  1549. }
  1550. if ($model eq "SPARCstation-5" | $model eq "micro COMPstation 5" | $model =~ /Axil-255/ | $banner =~ /TWINstation 5G\b/) {
  1551.         # Accepts 8MB and 32MB SIMMs on motherboard
  1552.         #   501-2470 (8MB), 501-2471 (32MB)
  1553.         #   168-pin 60ns Fast Page Mode
  1554.         $devname="Aurora" if ($model eq "SPARCstation-5");
  1555.         $untested=0;
  1556.         $simmrangex="00000020";
  1557.         $simmbanks=8;
  1558.         $simmsperbank=1;
  1559.         @simmsizes=(8,32);
  1560.         @socketstr=("J0300","J0301","J0302","J0303","J0400","J0401","J0402","J0403");
  1561.         @bankstr=(0,1,2,3,4,5,6,7);
  1562.         if ($banner =~ /TWINstation 5G\b/) {
  1563.                 $simmbanks=6;
  1564.                 @socketstr=(0,1,2,3,4,5);
  1565.         }
  1566.         if ($model ne "SPARCstation-5") {
  1567.                 $bannermore="SPARCstation 5 clone";
  1568.                 $modelmore="SPARCstation 5 clone";
  1569.         }
  1570. }
  1571. if ($model =~ /SPARCstation-10/ | $model eq "Premier-24" | $motherboard eq "SUNW,S10,501-2365") {
  1572.         # Accepts 16MB and 64MB SIMMs on motherboard
  1573.         #   501-1785 or 501-2273 (16MB 80ns), 501-2479 (16MB 60ns),
  1574.         #   501-2622 (32MB 60ns), 501-1930 (64MB 80ns), 501-2480 (64MB 60ns)
  1575.         #   200-pin 60ns or 80ns Fast Page Mode ECC
  1576.         # 32MB SIMMs not supported according to Sun, but appears to work fine
  1577.         # depending on the OBP revision. OBP 2.12 and older detects the 32MB
  1578.         # SIMM as 16MB, OBP 2.19 and later properly detects the 32MB SIMM.
  1579.         $devname="Campus2" if ($model =~ /SPARCstation-10/);
  1580.         $untested=0;
  1581.         $simmrangex="00000040";
  1582.         $simmbanks=8;
  1583.         $simmsperbank=1;
  1584.         $romvernum="2.X" if ($romvernum eq "");
  1585.         $romverminor=0 if ($romverminor eq "" | $romverminor eq "X");
  1586.         if ($romvermajor eq 2 & $romverminor >= 19) {
  1587.                 @simmsizes=(16,32,64);
  1588.         } else {
  1589.                 @simmsizes=(16,64);
  1590.         }
  1591.         @socketstr=("J0201","J0203","J0302","J0304","J0202","J0301","J0303","J0305");
  1592.         @orderstr=("1st","3rd","4th","2nd","8th","6th","5th","7th");
  1593.         @bankstr=(0,1,2,3,4,5,6,7);
  1594. }
  1595. if ($model =~ /SPARCstation-20/ | $model =~ /COMPstation-20S/ | $banner =~ /TWINstation 20G\b/) {
  1596.         # Accepts 16MB, 32MB and 64MB SIMMs on motherboard
  1597.         #   501-2479 (16MB), 501-2622 (32MB), 501-2480 (64MB)
  1598.         #   200-pin 60ns Fast Page Mode ECC
  1599.         $devname="Kodiak" if ($model eq "SPARCstation-20");
  1600.         $untested=0;
  1601.         $simmrangex="00000040";
  1602.         $simmbanks=8;
  1603.         $simmsperbank=1;
  1604.         @simmsizes=(16,32,64);
  1605.         @socketstr=("J0201","J0303","J0202","J0301","J0305","J0203","J0302","J0304");
  1606.         @orderstr=("1st","2nd","3rd","4th","5th","6th","7th","8th");
  1607.         @bankstr=(0,1,2,3,4,5,6,7);
  1608.         if ($model !~ /SPARCstation-20/) {
  1609.                 $bannermore="SPARCstation 20 clone";
  1610.                 $modelmore="SPARCstation 20 clone";
  1611.         }
  1612.         if ($model eq "SPARCstation-20I") {
  1613.                 $bannermore="(SPARCstation-20I) clone";
  1614.                 $modelmore="clone";
  1615.         }
  1616.         if ($banner =~ /TWINstation 20G\b/) {
  1617. #               @socketstr=("J0201","J0303","J0202","J0301","J0305","J0203","J0302","J0304");
  1618. #               @orderstr=("1st","6th","2nd","4th","8th","3rd","5th","7th");
  1619.                 @socketstr=(0,1,2,3,4,5,6,7);
  1620.                 @orderstr=("");
  1621.         }
  1622. }
  1623. if ($model eq "SPARCsystem-600" | $model =~ /Sun.4.600/) {
  1624.         # Accepts 4MB or 16MB SIMMs on motherboard
  1625.         # Accepts 1MB, 4MB or 16MB SIMMs on VME expansion cards
  1626.         # A memory bank is 16 SIMMs of the same size and speed
  1627.         # Minimum memory configuration is 16 SIMMs in Bank 0 on the motherboard
  1628.         # Motherboard Bank 1 must be populated before adding expansion cards
  1629.         # Up to two VME memory expansion cards can be added
  1630.         # Use 4MB SIMM 501-1739-01 or 501-2460-01
  1631.         # Use 16MB SIMM 501-2060-01
  1632.         $devname="Galaxy";
  1633.         $untested=0;
  1634.         $simmrangex="00000100";
  1635.         $simmbanks=2; # 2 banks on CPU board, 4 banks on each expansion cards
  1636.         $simmsperbank=16;
  1637.         @simmsizes=(4,16);
  1638.         # Sockets, banks and bytes on motherboard
  1639.         @socketstr=("U1107","U1307","U1105","U1305","U1103","U1303","U1101","U1301","U1207","U1407","U1205","U1405","U1203","U1403","U1201","U1401","U1108","U1308","U1106","U1306","U1104","U1304","U1102","U1302","U1208","U1408","U1206","U1406","U1204","U1404","U1202","U1402");
  1640.         @bankstr=(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
  1641.         @banksstr=("Motherboard bank 0","Motherboard bank 1");
  1642.         @bytestr=("0L0","0L1","1L0","1L1","2L0","2L1","3L0","3L1","4L0","4L1","5L0","5L1","6L0","6L1","7L0","7L1","0H0","0H1","1H0","1H1","2H0","2H1","3H0","3H1","4H0","4H1","5H0","5H1","6H0","6H1","7H0","7H1");
  1643.         # Sockets, banks and bytes on VME expansion cards
  1644.         @socketstr_exp=("U1501","U1503","U1505","U1507","U1601","U1603","U1605","U1607","U1701","U1703","U1705","U1707","U1801","U1803","U1805","U1807","U1502","U1504","U1506","U1508","U1602","U1604","U1606","U1608","U1702","U1704","U1706","U1708","U1802","U1804","U1806","U1808","U1901","U1903","U1905","U1907","U2001","U2003","U2005","U2007","U2101","U2103","U2105","U2107","U2201","U2203","U2205","U2207","U1902","U1904","U1906","U1908","U2002","U2004","U2006","U2008","U2102","U2104","U2106","U2108","U2202","U2204","U2206","U2208");
  1645.         @bankstr_exp=("B0","B0","B0","B0","B0","B0","B0","B0","B0","B0","B0","B0","B0","B0","B0","B0","B1","B1","B1","B1","B1","B1","B1","B1","B1","B1","B1","B1","B1","B1","B1","B1","B2","B2","B2","B2","B2","B2","B2","B2","B2","B2","B2","B2","B2","B2","B2","B2","B3","B3","B3","B3","B3","B3","B3","B3","B3","B3","B3","B3","B3","B3","B3","B3");
  1646.         @bytestr_exp=("0L0","0L1","1L0","1L1","2L0","2L1","3L0","3L1","4L0","4L1","5L0","5L1","6L0","6L1","7L0","7L1","0H0","0H1","1H0","1H1","2H0","2H1","3H0","3H1","4H0","4H1","5H0","5H1","6H0","6H1","7H0","7H1","8L0","8L1","9L0","9L1","aL0","aL1","bL0","bL1","cL0","cL1","dL0","dL1","eL0","eL1","fL0","fL1","8H0","8H1","9H0","9H1","aH0","aH1","bH0","bH1","cH0","cH1","dH0","dH1","eH0","eH1","fH0","fH1");
  1647. }
  1648. if ($model eq "Ultra-1" | $ultra eq 1) {
  1649.         # Accepts 16MB, 32MB, 64MB or 128MB DIMMs on motherboard
  1650.         #   501-2479 (16MB), 501-2622 (32MB), 501-2480 or 501-5691 (64MB),
  1651.         #   501-3136 (128MB)
  1652.         #   200-pin 60ns Fast Page Mode ECC
  1653.         $devname="Neutron (Ultra 1), Electron (Ultra 1E), Dublin (Ultra 150)";
  1654.         $untested=0;
  1655.         $simmrangex="00000100";
  1656.         $simmbanks=4;
  1657.         $simmsperbank=2;
  1658.         @simmsizes=(16,32,64,128);
  1659.         @socketstr=("U0701","U0601","U0702","U0602","U0703","U0603","U0704","U0604");
  1660.         @bankstr=("0L","0H","1L","1H","2L","2H","3L","3H");
  1661.         @bytestr=("00-15","16-31","00-15","16-31","00-15","16-31","00-15","16-31");
  1662. }
  1663. if ($model eq "Ultra-2" | $ultra eq 2) {
  1664.         # Accepts 16MB, 32MB, 64MB or 128MB DIMMs on motherboard
  1665.         $devname="Pulsar";
  1666.         $untested=0;
  1667.         $simmrangex="00000200";
  1668.         $simmbanks=4;
  1669.         $simmsperbank=4;
  1670.         @simmsizes=(16,32,64,128);
  1671.         @socketstr=("U0501","U0401","U0701","U0601","U0502","U0402","U0702","U0602","U0503","U0403","U0703","U0603","U0504","U0404","U0704","U0604");
  1672.         @groupstr=(0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3);
  1673.         @bankstr=("0L","0H","1L","1H","0L","0H","1L","1H","0L","0H","1L","1H","0L","0H","1L","1H");
  1674.         @bytestr=("00-15","16-31","32-47","48-63","00-15","16-31","32-47","48-63","00-15","16-31","32-47","48-63","00-15","16-31","32-47","48-63");
  1675. }
  1676. if ($model eq "Ultra-30" | $ultra eq 30) {
  1677.         # Accepts 16MB, 32MB, 64MB or 128MB DIMMs on motherboard
  1678.         #   501-2479 (16MB), 501-2622 (32MB), 501-2480 or 501-5691 (64MB),
  1679.         #   501-3136 (128MB)
  1680.         #   200-pin 60ns Fast Page Mode ECC
  1681.         # Two DIMMs form a pair, two pairs of DIMMs form a quad.
  1682.         # Minumum requirements is two DIMMs in any adjacent pair.
  1683.         # DIMMs can be installed in any order of pairs.
  1684.         # Interleaving requires a fully populated quad.
  1685.         # Each quad addresses 512MB of memory.
  1686.         $devname="Quark";
  1687.         $untested=0;
  1688.         # simmrangex, simmbanks, and simmsperbank set later after determining
  1689.         # if interleaving banks using quads rather than pairs
  1690.         @simmsizes=(16,32,64,128);
  1691.         @socketstr=("U0701","U0801","U0901","U1001","U0702","U0802","U0902","U1002","U0703","U0803","U0903","U1003","U0704","U0804","U0904","U1004");
  1692.         @bankstr=("Quad 0 Pair 0","Quad 0 Pair 0","Quad 0 Pair 1","Quad 0 Pair 1","Quad 1 Pair 0","Quad 1 Pair 0","Quad 1 Pair 1","Quad 1 Pair 1","Quad 2 Pair 0","Quad 2 Pair 0","Quad 2 Pair 1","Quad 2 Pair 1","Quad 3 Pair 0","Quad 3 Pair 0","Quad 3 Pair 1","Quad 3 Pair 1");
  1693. }
  1694. if ($model eq "Ultra-5_10" | $ultra eq "5_10" | $ultra eq 5 | $ultra eq 10) {
  1695.         # Accepts 16MB, 32MB, 64MB, 128MB or 256MB DIMMs on motherboard
  1696.         # 16MB DIMM uses 10-bit column addressing and was not sold
  1697.         # 32, 64, 128 and 256MB DIMMs use 11-bit column addressing
  1698.         # Do not mix 16MB DIMMs with other sizes
  1699.         # 256MB DIMM not supported in Ultra 5 according to Sun documentation,
  1700.         # but they do work as long as you use low-profile DIMMs or take out the
  1701.         # floppy drive.
  1702.         # Memory speed is 60ns if 50ns and 60ns DIMMs are mixed
  1703.         # 2-way interleaving supported with four identical sized DIMMs
  1704.         # 50ns DIMMs supported on 375-0066 & 375-0079 motherboards
  1705.         # Bank 0 DIMM1/DIMM2 0x00000000-0x0fffffff, 0x20000000-0x2fffffff
  1706.         # Bank 1 DIMM3/DIMM4 0x10000000-0x1fffffff, 0x30000000-0x3fffffff
  1707.         $devname="Darwin/Otter (Ultra 5), Darwin/SeaLion (Ultra 10)";
  1708.         $untested=0;
  1709.         $simmrangex="00000100";
  1710.         $simmbanks=2;
  1711.         $simmsperbank=2;
  1712.         @simmsizes=(16,32,64,128,256);
  1713.         @socketstr=("DIMM1","DIMM2","DIMM3","DIMM4");
  1714.         @bankstr=("0L","0H","1L","1H");
  1715.         $sortslots=0;
  1716. }
  1717. if ($model eq "Ultra-60" | $ultra eq 60 | $ultra eq "220R") {
  1718.         # Also Netra t1120/1125
  1719.         # Accepts 16MB, 32MB, 64MB or 128MB DIMMs on motherboard
  1720.         #   501-2479 (16MB), 501-2622 (32MB), 501-2480 or 501-5691 (64MB),
  1721.         #   501-3136 (128MB)
  1722.         #   200-pin 60ns Fast Page Mode ECC
  1723.         # U1001-U1004 bank 3 address 0xa0000000-0xbfffffff
  1724.         # U0901-U0904 bank 2 address 0x80000000-0x9fffffff
  1725.         # U0801-U0804 bank 1 address 0x20000000-0x3fffffff
  1726.         # U0701-U0704 bank 0 address 0x00000000-0x1fffffff
  1727.         $devname="Deuterium" if ($model eq "Ultra-60" | $ultra eq 60);
  1728.         $devname="Razor" if ($ultra eq "220R");
  1729.         $untested=0;
  1730.         $simmrangex="00000200";
  1731.         $simmbanks=6;   # Count the skipped address range
  1732.         $simmsperbank=4;
  1733.         @simmsizes=(16,32,64,128);
  1734.         @socketstr=("U0701","U0702","U0703","U0704","U0801","U0802","U0803","U0804","?","?","?","?","?","?","?","?","U0901","U0902","U0903","U0904","U1001","U1002","U1003","U1004");
  1735.         @bankstr=(0,0,0,0,1,1,1,1,"?","?","?","?","?","?","?","?",2,2,2,2,3,3,3,3);
  1736. }
  1737.  
  1738. #
  1739. # SPARCengine systems
  1740. #
  1741. if ($banner =~ /Netra t1\b/ | $ultra eq "Netra t1" | $banner =~ /Ultra CP 1500\b/ | $ultra eq "cp1500" | $ultra eq "Netra ct400" | $ultra eq "Netra ct800") {
  1742.         # Netra t1 100/105, Netra ct400/800, SPARCengine CP1500
  1743.         #  Accepts 1 or 2 64MB, 128MB, 256MB or 512MB mezzanine memory cards
  1744.         # Also used in Sun Fire 12K & Sun Fire 15K
  1745.         # Install the highest capacity memory board first
  1746.         # The 370-4155 was sold for use in the Netra t1 100/105
  1747.         # Up to four 370-4155 256MB memory boards can be installed
  1748.         # Only one 370-4155 can be mixed with any other memory boards
  1749.         # Cannot distinguish between 4 370-4155 256MB and 2 512MB memory boards
  1750.         # Maximum memory: 768MB for 270MHz/33MHz, 1GB for 360MHz/440MHz systems
  1751.         #
  1752.         #   Top slot ->  64MB    64MB   128MB   128MB   256MB   256MB   512MB
  1753.         # Bottom slot   SSF SS  DSF SS  SSF SS  DSF SS  DSF DS  DSF SS  DSF DS
  1754.         #       |
  1755.         #       v       ------  ------  ------  ------  ------  ------  ------
  1756.         #  64MB SSF SS  Y       N       Y       N       N       Y       N
  1757.         #  64MB DSF SS  Y       Y       Y       Y       Y       Y       Y
  1758.         # 128MB SSF SS  Y       N       Y       N       N       Y       N
  1759.         # 128MB DSF SS  Y       Y       Y       Y       Y       Y       Y
  1760.         # 256MB DSF SS  Y       Y       Y       Y       Y       Y       Y
  1761.         # 512MB DSF DS  Y/N *   Y/N *   Y/N *   Y/N *   Y/N *   Y/N *   Y/N *
  1762.         #
  1763.         # SSF=single-sided fab, DSF=double-sided fab
  1764.         # SS=stuffed on one side, DS=stuffed on both sides
  1765.         # * 512MB DSF DS board is supported on 360MHz and 440MHz systems,
  1766.         #   512MB DSF DS board is not supported on 270MHz and 333MHz systems
  1767.         # Lower board, address 0x00000000-0x0fffffff, 0x20000000-0x2fffffff
  1768.         # upper board, address 0x10000000-0x1fffffff, 0x30000000-0x3fffffff
  1769.         $devname="Flyweight (Model 100), Flapjack (Model 105)" if ($banner =~ /Netra t1\b/ | $ultra eq "Netra t1");
  1770.         $devname="Tonga, Monte Carlo" if ($ultra =~ /Netra ct[48]00\b/);
  1771.         $untested=0;
  1772.         $untested=1 if ($ultra eq "Netra ct400");
  1773.         $memtype="memory card";
  1774.         $sockettype="";
  1775.         $simmrangex="00000100";
  1776.         $simmbanks=2;
  1777.         $simmsperbank=1;
  1778.         @simmsizes=(64,128,256,512);
  1779.         @socketstr=("base mezzanine board","additional mezzanine board");
  1780.         @orderstr=("lower board","upper board");
  1781.         $sortslots=0;
  1782. }
  1783. if ($banner =~ /Ultra CP 1400\b/ | $ultra eq "cp1400") {
  1784.         # Accepts 1 or 2 64MB, 128MB, 256MB or 512MB mezzanine memory cards
  1785.         # Has 64MB on-board memory on motherboard
  1786.         # Maximum memory: 832MB (64MB motherboard, 512MB bottom, 256MB top)
  1787.         #
  1788.         #   Top slot ->  64MB    64MB   128MB   128MB   256MB   512MB
  1789.         # Bottom slot   SSF SS  DSF SS  SSF SS  DSF SS  DSF SS  DSF DS
  1790.         #       |
  1791.         #       v       ------  ------  ------  ------  ------  ------
  1792.         #  64MB SSF SS  Y       N       Y       N       Y       N
  1793.         #  64MB DSF SS  Y       Y       Y       Y       Y       N
  1794.         # 128MB SSF SS  Y       N       Y       N       Y       N
  1795.         # 128MB DSF SS  Y       Y       Y       Y       Y       N
  1796.         # 256MB DSF SS  Y       Y       Y       Y       Y       N
  1797.         # 512MB DSF DS  Y       Y       Y       Y       Y       N
  1798.         #
  1799.         # SSF=single-sided fab, DSF=double-sided fab
  1800.         # SS=stuffed on one side, DS=stuffed on both sides
  1801.         # 512MB DSF DS board is only supported in bottom slot
  1802.         #
  1803.         # Motherboard, address 0x00000000-0x03ffffff
  1804.         # Upper board, address 0x08000000-0xffffffff, 0x28000000-0x2fffffff
  1805.         # Lower board, address 0x10000000-0x17ffffff, 0x30000000-0x37ffffff
  1806.         $untested=0;
  1807.         $memtype="memory card";
  1808.         $sockettype="";
  1809.         $simmrangex="00000080";
  1810.         $simmbanks=3;
  1811.         $simmsperbank=1;
  1812.         @simmsizes=(64,128,256,512);
  1813.         @socketstr=("motherboard","additional mezzanine board","base mezzanine board");
  1814.         @orderstr=("","upper board","lower board");
  1815.         $sortslots=0;
  1816. }
  1817. if ($ultra eq "AX" | $ultra eq "AX-300") {
  1818.         # SPARCengine Ultra AX and AX-300
  1819.         # Accepts 8MB, 16MB, 32MB or 64MB DIMMs on motherboard
  1820.         # AX-300 also accepts 128MB DIMMs on motherboard
  1821.         $untested=0;            # unsure if socket order is correct
  1822.         $simmrangex="00000200";
  1823.         $simmbanks=2;
  1824.         $simmsperbank=4;
  1825.         @simmsizes=(8,16,32,64,128);
  1826.         @socketstr=("U0301","U0302","U0303","U0304","U0401","U0402","U0403","U0404");
  1827.         @bankstr=(0,0,0,0,1,1,1,1);
  1828. }
  1829. if ($ultra eq "AXi") {
  1830.         # SPARCengine Ultra AXi
  1831.         # Accepts 8MB, 16MB, 32MB, 64MB or 128MB single or dual bank 10-bit
  1832.         #  column address type DIMMs on motherboard in all socket pairs
  1833.         # Accepts 8MB, 16MB, 32MB, 64MB, 128MB or 256MB dual bank 11-bit
  1834.         #  column address type DIMMs on motherboard in Pairs 0 & 2
  1835.         #  (leave Pairs 1 & 3 empty)
  1836.         # DIMMs should be chosen as all 10-bit or all 11-bit column address type
  1837.         # Use 60ns DIMMs only
  1838.         $untested=0;
  1839.         $simmrangex="00000100";
  1840.         $simmbanks=4;
  1841.         $simmsperbank=2;
  1842.         @simmsizes=(8,16,32,64,128,256);
  1843.         @socketstr=("U0404","U0403","U0304","U0303","U0402","U0401","U0302","U0301");
  1844.         @bankstr=(0,0,2,2,1,1,3,3);
  1845.         $sortslots=0;
  1846. }
  1847. if ($ultra eq "AXmp" | $ultra eq "AXmp+") {
  1848.         # SPARCengine Ultra AXmp
  1849.         #  Accepts 8MB, 16MB, 32MB, 64MB or 128MB DIMMs on motherboard
  1850.         #  Accepts 256MB dual-bank DIMMs in bank 0 or 1 (not both)
  1851.         #  Can't distinguish dual-bank DIMMs from two banks of single bank DIMMs
  1852.         # SPARCengine Ultra AXmp+
  1853.         #  Accepts 8MB, 16MB, 32MB, 64MB, 128MB or 256MB DIMMs on motherboard
  1854.         #  Accepts dual-bank DIMMs in both bank 0 and 1
  1855.         #  Can't distinguish dual-bank DIMMs from two banks of single bank DIMMs
  1856.         $untested=0;
  1857.         $simmbanks=2;
  1858.         $simmsperbank=8;
  1859.         if ($ultra eq "AXmp+") {
  1860.                 $simmrangex="00000400";
  1861.                 @simmsizes=(8,16,32,64,128,256);
  1862.         } else {
  1863.                 $simmrangex="00000800";
  1864.                 @simmsizes=(8,16,32,64,128);
  1865.         }
  1866.         @socketstr=("U0701","U0702","U0703","U0704","U0801","U0802","U0803","U0804","U0901","U0902","U0903","U0904","U1001","U1002","U1003","U1004");
  1867.         @bankstr=(0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1);
  1868.         $sortslots=0;
  1869. }
  1870. if ($ultra eq "AXe") {
  1871.         # SPARCengine Ultra AXe
  1872.         # Accepts 32MB, 64MB, 128MB or 256MB single or dual bank DIMMs
  1873.         # DIMMs should be chosen as all 10-bit or all 11-bit column address type
  1874.         $untested=0;
  1875.         $simmrangex="00000100";
  1876.         $simmbanks=2;
  1877.         $simmsperbank=2;
  1878.         @simmsizes=(32,64,128,256);
  1879.         @socketstr=("DIMM3","DIMM4","DIMM1","DIMM2");
  1880.         @bankstr=(0,0,1,1);
  1881.         # Assume stacked DIMMs like AXi since only 128MB DIMMs have been tested
  1882.         $sortslots=0;
  1883. }
  1884. if ($ultra eq "AX-e2") {
  1885.         # Netra AX1105-500
  1886.         # Accepts up to 4 64MB, 128MB, 256MB or 512MB registered SDRAM PC133
  1887.         # DIMMs; 128MB Minimum, 2GB Maximum
  1888.         # DIMM0 & DIMM1 form Bank 0, DIMM2 & DIMM3 form Bank 1
  1889.         # DIMMs don't have to be installed as pairs
  1890.         $untested=0;
  1891.         $simmrangex="00000200";
  1892.         $simmbanks=4;
  1893.         $simmsperbank=1;
  1894.         @simmsizes=(64,128,256,512);
  1895.         @socketstr=("DIMM0","DIMM1","DIMM2","DIMM3");
  1896.         @bankstr=(0,0,1,1);
  1897. }
  1898. if ($ultra eq "Netra X1" | $ultra eq "Sun Fire V100") {
  1899.         # Netra X1, Sun Fire V100, UltraAX-i2
  1900.         # Accepts up to 4 128MB or 256MB PC133 DIMMs for 1GB maximum
  1901.         # 500MHz model also accepts up to 4 512MB PC133 DIMMs for 2GB maximum
  1902.         # Have seen slower models also work with 512MB DIMMs for 2GB maximum
  1903.         # Sun Fire V100 is 500MHz only
  1904.         # The memory installation sequence is Slot 3, 2, 1, and 0.
  1905.         # Each DIMM slot addresses 512MB with 400MHz UltraSPARC IIe
  1906.         # Each DIMM slot addresses 1GB with >= 550MHz UltraSPARC IIe
  1907.         # Memory is SDRAM PC133 CL=3 ECC registered
  1908.         # When equal size DIMMs are installed, the lowest slot number is
  1909.         #  mapped to the lowest address range.
  1910.         # When mixed size DIMMs are installed, the slot number with the largest
  1911.         #  size DIMM is mapped to the lowest address range.
  1912.         $devname="Flapjack-lite" if ($ultra eq "Netra X1");
  1913.         $devname="Flapjack-liteCD500" if ($ultra eq "Sun Fire V100");
  1914.         $untested=0;
  1915.         $simmrangex=($cpufreq > 520) ? "00000400" : "00000200";
  1916.         $simmbanks=4;
  1917.         $simmsperbank=1;
  1918.         #@simmsizes=($cpufreq < 420) ? (128,256) : (128,256,512);
  1919.         @simmsizes=(128,256,512);
  1920.         @socketstr=("DIMM0","DIMM1","DIMM2","DIMM3");
  1921. }
  1922. if ($ultra eq "Netra T1 200" | $ultra eq "Sun Fire V120" | $ultra eq "Netra 120") {
  1923.         # Netra T1 200, Sun Fire V120, Netra 120, UltraAX-i2
  1924.         # Accepts up to 4 256MB, 512MB or 1GB PC133 DIMMs for 4GB maximum
  1925.         # Sun Fire V120 is 550MHz or 650MHz
  1926.         # Netra 120 is same platform as Sun Fire V120, but is 650MHz only
  1927.         # Memory is SDRAM PC133 CL=3 ECC registered
  1928.         # The minimum memory requirement is one DIMM in Slot 0
  1929.         # The memory installation sequence is Slot 0, 1, 2, 3
  1930.         # Each DIMM slot addresses 512MB of memory with 500MHz UltraSPARC IIe
  1931.         # Each DIMM slot addresses 1GB of memory with >= 550MHz UltraSPARC IIe
  1932.         # When equal size DIMMs are installed, the lowest slot number is
  1933.         #  mapped to the lowest address range.
  1934.         # When mixed size DIMMs are installed, the slot number with the largest
  1935.         #  size DIMM is mapped to the lowest address range.
  1936.         $devname="Flapjack2" if ($ultra eq "Netra T1 200");
  1937.         $devname="Flapjack2 plus" if ($ultra eq "Sun Fire V120" | $ultra eq "Netra 120");
  1938.         $untested=0;
  1939.         $simmrangex=($cpufreq > 520) ? "00000400" : "00000200";
  1940.         $simmbanks=4;
  1941.         $simmsperbank=1;
  1942.         @simmsizes=(256,512,1024);
  1943.         @socketstr=("DIMM0","DIMM1","DIMM2","DIMM3");
  1944. }
  1945.  
  1946. #
  1947. # Clones: most do not have verbose output since I don't have any socket data
  1948. # on them
  1949. #
  1950. if ($ultra eq "axus250" | $modelmore =~ /Ultra-250/) {
  1951.         # AXUS Microsystems, Inc. http://www.axus.com.tw
  1952.         # AXUS 250 clone
  1953.         # accepts up to 128MB DIMMs on motherboard
  1954.         $untested=0;
  1955.         $simmrangex="00000200";
  1956.         $simmbanks=4;
  1957.         $simmsperbank=4;
  1958.         @simmsizes=(8,16,32,64,128);
  1959.         @socketstr=("U0501","U0601","U0701","U0801","U0502","U0602","U0702","U0802","U0503","U0603","U0703","U0803","U0504","U0604","U0704","U0804");
  1960.         @bankstr=(0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3);
  1961. }
  1962. if ($model =~ /SPARC CPU-/) {
  1963.         # Force Computers, http://www.forcecomputers.com
  1964.         $untested=0;
  1965. }
  1966. if ($model =~ /SPARC CPCI-/) {
  1967.         # Force Computers, http://www.forcecomputers.com
  1968.         $untested=1;
  1969. }
  1970. if ($model =~ /Axil/) {
  1971.         # RAVE Computer Association, http://rave.com
  1972.         $untested=1;
  1973.         $untested=0 if ($model =~ /Axil-245/);
  1974.         $untested=0 if ($model =~ /Axil-255/);
  1975.         $untested=0 if ($model =~ /Axil-311/);
  1976.         $untested=0 if ($model =~ /Axil-320/);
  1977. }
  1978. if ($manufacturer eq "Tadpole") {
  1979.         # Tadpole RDI, http://www.tadpole.com
  1980.         $untested=1;
  1981.         $untested=0 if ($banner =~ /Tadpole S3/);
  1982.         $untested=0 if ($model =~ /PowerLite-170/);
  1983.         $untested=0 if ($banner =~ /\bVoyagerIIi\b/);
  1984. }
  1985. if ($manufacturer eq "Auspex") {
  1986.         # Auspex Netserver, http://www.auspex.com
  1987.         $memtype="Memory Module";
  1988.         $untested=1;
  1989.         $untested=0 if ($model eq "SPARC Processor");
  1990.         if ($sunos =~ /^5./) {
  1991.                 $untested=1;    # Untested with Solaris 2.X
  1992.                 $untested_type="OS";
  1993.         }
  1994. }
  1995. if ($manufacturer =~ /Fujitsu/) {
  1996.         # Hal Computer Systems, a Fujitsu Company, http://www.hal.com
  1997.         # Fujitsu Siemens, http://www.fujitsu-siemens.com
  1998.         $untested=1;
  1999.         $untested=0 if ($model =~ /S-4\/10H/ | $model =~ /S-4\/20[ABLH]/);
  2000.         if ($banner =~ /GP7000\b/ | $banner =~ /GP7000F\b/) {
  2001.                 $untested=0;
  2002.                 if ($slotname0 =~ /SLOT[0-9]/) {
  2003.                         # M200
  2004.                         # Up to 4GB of memory
  2005.                         # System board has 16 DIMM slots, #00 - #15
  2006.                         # Banks - 0,0,1,1,2,2,2,2,3,3,3,3,4,4,4,4
  2007.                         # First Modules installed in Bank 0, slots 0-1
  2008.                         # Second Modules Installed in Bank 1, slots 2-3
  2009.                         # Modules in Bank 0 and 1 must be same size
  2010.                         # Subsequent memory expansion installed in sets of four
  2011.                         #   modules in Bank 2 - 4 (Slots 4-7, 8-11, 12-15)
  2012.                         @socketstr=("SLOT0","SLOT1","SLOT2","SLOT3","SLOT4","SLOT5","SLOT6","SLOT7","SLOT8","SLOT9","SLOT10","SLOT11","SLOT12","SLOT13","SLOT14","SLOT15");
  2013.                 }
  2014.                 if ($slotname0 =~ /SLOT[AB][0-9]/) {
  2015.                         # M400 and M600
  2016.                         # Up to 4GB of memory
  2017.                         # System board has 32 DIMM slots, #00 - #15 Group A & B
  2018.                         # Banks - 0,0,1,1,2,2,2,2,3,3,3,3,4,4,4,4
  2019.                         # First Modules installed in Bank 0 Group A, slots 0-1
  2020.                         # Second Modules installed in Bank 0 Group B, slots 0-1
  2021.                         # Modules in Group A and B must be same size
  2022.                         # Next memory expansion installs in Bank 1 Group A & B,
  2023.                         #   slots 2-3 using modules of same size as Bank 0
  2024.                         # Subsequent memory expansion installed in sets of eight
  2025.                         #   modules in Bank 2 - 4 (Slots 4-7, 8-11, 12-15) in
  2026.                         #   both Group A and B
  2027.                         @socketstr=("SLOTA0","SLOTA1","SLOTA2","SLOTA3","SLOTA4","SLOTA5","SLOTA6","SLOTA7","SLOTA8","SLOTA9","SLOTA10","SLOTA11","SLOTA12","SLOTA13","SLOTA14","SLOTA15","SLOTB0","SLOTB1","SLOTB2","SLOTB3","SLOTB4","SLOTB5","SLOTB6","SLOTB7","SLOTB8","SLOTB9","SLOTB10","SLOTB11","SLOTB12","SLOTB13","SLOTB14","SLOTB15");
  2028.                 }
  2029.         }
  2030.         if ($banner =~ /PRIMEPOWER [246]00\b/ | $banner =~ /PRIMEPOWER[246]00\b/) {
  2031.                 # Up to 8GB of memory
  2032.                 # Each system board has 16 DIMM slots, #00 - #15
  2033.                 # Four banks of 4 (0-3,4-7,8-11,12-15)
  2034.                 # PrimePower 200 and 400 use 1 system board
  2035.                 # PrimePower 600 uses 2 system boards (00, 01)
  2036.                 $untested=0;
  2037.                 if ($slotname0 =~ /00-SLOT[0-9]/) {
  2038.                         @socketstr=("00-SLOT0","00-SLOT1","00-SLOT2","00-SLOT3","00-SLOT4","00-SLOT5","00-SLOT6","00-SLOT7","00-SLOT8","00-SLOT9","00-SLOT10","00-SLOT11","00-SLOT12","00-SLOT13","00-SLOT14","00-SLOT15");
  2039.                 }
  2040.                 if ($gotmodulenames =~ /01-SLOT[0-9]/) {
  2041.                         push (@socketstr, ("01-SLOT0","01-SLOT1","01-SLOT2","01-SLOT3","01-SLOT4","01-SLOT5","01-SLOT6","01-SLOT7","01-SLOT8","01-SLOT9","01-SLOT10","01-SLOT11","01-SLOT12","01-SLOT13","01-SLOT14","01-SLOT15"));
  2042.                 }
  2043.         }
  2044.         if ($banner =~ /PRIMEPOWER 800\b/ | $banner =~ /PRIMEPOWER800\b/) {
  2045.                 # Minimum Memory: 1GB / system board, 2GB / system
  2046.                 # Maximum Memory: 8GB / system board, 32GB / system
  2047.                 $untested=0;
  2048.                 if ($slotname0 =~ /00-SLOT#[AB][0-9]/) {
  2049.                         @socketstr=("00-SLOT#A00","00-SLOT#A01","00-SLOT#A02","00-SLOT#A03","00-SLOT#A10","00-SLOT#A11","00-SLOT#A12","00-SLOT#A13","00-SLOT#A20","00-SLOT#A21","00-SLOT#A22","00-SLOT#A23","00-SLOT#A30","00-SLOT#A31","00-SLOT#A32","00-SLOT#A33","00-SLOT#B00","00-SLOT#B01","00-SLOT#B02","00-SLOT#B03","00-SLOT#B10","00-SLOT#B11","00-SLOT#B12","00-SLOT#B13","00-SLOT#B20","00-SLOT#B21","00-SLOT#B22","00-SLOT#B23","00-SLOT#B30","00-SLOT#B31","00-SLOT#B32","00-SLOT#B33");
  2050.                 }
  2051.                 if ($gotmodulenames =~ /01-SLOT#[AB][0-9]/) {
  2052.                         push (@socketstr, ("01-SLOT#A00","01-SLOT#A01","01-SLOT#A02","01-SLOT#A03","01-SLOT#A10","01-SLOT#A11","01-SLOT#A12","01-SLOT#A13","01-SLOT#A20","01-SLOT#A21","01-SLOT#A22","01-SLOT#A23","01-SLOT#A30","01-SLOT#A31","01-SLOT#A32","01-SLOT#A33","01-SLOT#B00","01-SLOT#B01","01-SLOT#B02","01-SLOT#B03","01-SLOT#B10","01-SLOT#B11","01-SLOT#B12","01-SLOT#B13","01-SLOT#B20","01-SLOT#B21","01-SLOT#B22","01-SLOT#B23","01-SLOT#B30","01-SLOT#B31","01-SLOT#B32","01-SLOT#B33"));
  2053.                 }
  2054.                 if ($gotmodulenames =~ /02-SLOT#[AB][0-9]/) {
  2055.                         push (@socketstr, ("02-SLOT#A00","02-SLOT#A01","02-SLOT#A02","02-SLOT#A03","02-SLOT#A10","02-SLOT#A11","02-SLOT#A12","02-SLOT#A13","02-SLOT#A20","02-SLOT#A21","02-SLOT#A22","02-SLOT#A23","02-SLOT#A30","02-SLOT#A31","02-SLOT#A32","02-SLOT#A33","02-SLOT#B00","02-SLOT#B01","02-SLOT#B02","02-SLOT#B03","02-SLOT#B10","02-SLOT#B11","02-SLOT#B12","02-SLOT#B13","02-SLOT#B20","02-SLOT#B21","02-SLOT#B22","02-SLOT#B23","02-SLOT#B30","02-SLOT#B31","02-SLOT#B32","02-SLOT#B33"));
  2056.                 }
  2057.                 if ($gotmodulenames =~ /03-SLOT#[AB][0-9]/) {
  2058.                         push (@socketstr, ("03-SLOT#A00","03-SLOT#A01","03-SLOT#A02","03-SLOT#A03","03-SLOT#A10","03-SLOT#A11","03-SLOT#A12","03-SLOT#A13","03-SLOT#A20","03-SLOT#A21","03-SLOT#A22","03-SLOT#A23","03-SLOT#A30","03-SLOT#A31","03-SLOT#A32","03-SLOT#A33","03-SLOT#B00","03-SLOT#B01","03-SLOT#B02","03-SLOT#B03","03-SLOT#B10","03-SLOT#B11","03-SLOT#B12","03-SLOT#B13","03-SLOT#B20","03-SLOT#B21","03-SLOT#B22","03-SLOT#B23","03-SLOT#B30","03-SLOT#B31","03-SLOT#B32","03-SLOT#B33"));
  2059.                 }
  2060.         }
  2061. }
  2062. if ($model =~ /COMPstation.10/) {
  2063.         # Tatung Science and Technology, http://www.tsti.com
  2064.         # Accepts 16MB and 64MB SIMMs on motherboard
  2065.         # Bank 0 must be filled first
  2066.         # Layout is like SPARCstation-10, but I don't know if it can accept
  2067.         # 32MB SIMMs or NVSIMMs
  2068.         $untested=0;
  2069.         $simmrangex="00000040";
  2070.         $simmbanks=8;
  2071.         $simmsperbank=1;
  2072.         @simmsizes=(16,64);
  2073.         @socketstr=("J0201","J0203","J0302","J0304","J0202","J0301","J0303","J0305");
  2074.         @bankstr=(0,2,4,6,1,3,5,7);
  2075. }
  2076. if ($model =~ /COMPstation-20A\b/) {
  2077.         # Tatung Science and Technology, http://www.tsti.com
  2078.         # Accepts 16MB, 32MB and 64MB SIMMs on motherboard
  2079.         $untested=1;
  2080.         $simmrangex="00000040";
  2081.         $simmbanks=8;
  2082.         $simmsperbank=1;
  2083.         @simmsizes=(16,32,64);
  2084.         @socketstr=("J0201","J0304","J0203","J0302","J0303","J0301","J0305","J0202");
  2085.         @orderstr=("1st","2nd","3rd","4th","5th","6th","7th","8th");
  2086.         @bankstr=(1,2,3,4,5,6,7,8);
  2087. }
  2088. if ($model =~ /COMPstation-20AL/) {
  2089.         # Tatung Science and Technology, http://www.tsti.com
  2090.         # Accepts 16MB, 32MB and 64MB SIMMs on motherboard
  2091.         $untested=0;
  2092.         $simmrangex="00000040";
  2093.         $simmbanks=8;
  2094.         $simmsperbank=1;
  2095.         @simmsizes=(16,32,64);
  2096.         @socketstr=("J0201","J0203","J0302","J0304","J0202","J0301","J0303","J0305");
  2097.         @orderstr=("1st","2nd","3rd","4th","5th","6th","7th","8th");
  2098.         @bankstr=(0,1,2,3,4,5,6,7);
  2099. }
  2100. if ($banner =~ /COMPstation_U60_Series/ | $banner =~ /COMPstation_U80D_Series/) {
  2101.         # Tatung Science and Technology, http://www.tsti.com
  2102.         # Accepts 16MB, 32MB, 64MB, 128MB or 256MB DIMMs on motherboard
  2103.         # 4 banks with 4 DIMMs per bank
  2104.         $untested=0;
  2105.         $simmrangex="00000200"; # use "00000400" with 256MB DIMMs
  2106.         $simmbanks=6;   # Count the skipped address range
  2107.         $simmsperbank=4;
  2108.         @simmsizes=(16,32,64,128,256);
  2109. }
  2110. if ($model =~ /\bVoyagerIIi\b/) {
  2111.         # Tadpole Voyager IIi has 8 DIMM slots, but otherwise appears
  2112.         # to look like an Ultra 5. It allows 256MB to 1GB of memory.
  2113.         $untested=0;
  2114.         $simmrangex="00000100";
  2115.         $simmbanks=4;
  2116.         $simmsperbank=2;
  2117.         @simmsizes=(16,32,64,128);
  2118.         @socketstr=("DIMM1","DIMM2","DIMM5","DIMM6","DIMM3","DIMM4","DIMM7","DIMM8");
  2119.         $sortslots=1;
  2120. }
  2121.  
  2122. #
  2123. # systems below may have memory information available in prtdiag output
  2124. #
  2125. if ($model eq "SPARCserver-1000" | $model eq "SPARCcenter-2000") {
  2126.         $devname="Scorpion" if ($model eq "SPARCserver-1000");
  2127.         $devname="Dragon" if ($model eq "SPARCcenter-2000");
  2128.         # Accepts 8MB and 32MB SIMMs on motherboard
  2129.         $untested=0;
  2130.         @simmsizes=(8,32);
  2131.         $prtdiag_has_mem=1;
  2132.         &check_prtdiag;
  2133.         if ($boardfound_mem) {
  2134.                 foreach $line (@boards_mem) {
  2135.                         if ($line =~ /Board/) {
  2136.                                 $boardslot_mem=substr($line,5,1);
  2137.                                 $simmsize=int substr($line,46,3) / 4;
  2138.                                 if ($simmsize == 0) {
  2139.                                         &found_empty_bank("Group 0");
  2140.                                 } elsif ($simmsize == 1) {
  2141.                                         &found_nvsimm_bank("Group 0");
  2142.                                 } else {
  2143.                                         push(@simmsizesfound, "$simmsize");
  2144.                                 }
  2145.                                 $simmsize=int substr($line,54,3) / 4;
  2146.                                 if ($simmsize == 0) {
  2147.                                         &found_empty_bank("Group 1");
  2148.                                 } elsif ($simmsize == 1) {
  2149.                                         &found_nvsimm_bank("Group 1");
  2150.                                 } else {
  2151.                                         push(@simmsizesfound, "$simmsize");
  2152.                                 }
  2153.                                 $simmsize=int substr($line,62,3) / 4;
  2154.                                 if ($simmsize == 0) {
  2155.                                         &found_empty_bank("Group 2");
  2156.                                 } elsif ($simmsize == 1) {
  2157.                                         &found_nvsimm_bank("Group 2");
  2158.                                 } else {
  2159.                                         push(@simmsizesfound, "$simmsize");
  2160.                                 }
  2161.                                 $simmsize=int substr($line,70,3) / 4;
  2162.                                 if ($simmsize == 0) {
  2163.                                         &found_empty_bank("Group 3");
  2164.                                 } elsif ($simmsize == 1) {
  2165.                                         &found_nvsimm_bank("Group 3");
  2166.                                 } else {
  2167.                                         push(@simmsizesfound, "$simmsize");
  2168.                                 }
  2169.                         }
  2170.                 }
  2171.                 &show_header;
  2172.                 print @boards_mem;
  2173.                 print "Each memory unit group is comprised of 4 SIMMs\n";
  2174.                 $empty_banks=" None" if ($empty_banks eq "");
  2175.                 print "empty memory groups:$empty_banks\n";
  2176.         } else {
  2177.                 &show_header;
  2178.                 $recognized=0;
  2179.         }
  2180.         $totmem=$installed_memory;
  2181.         &finish;
  2182.         exit;
  2183. }
  2184. if ($model eq "Ultra-4" | $ultra eq 450 | $model eq "Ultra-4FT" | $ultra eq "Netra ft1800") {
  2185.         # Accepts 32MB, 64MB, 128MB or 256MB DIMMs on motherboard
  2186.         #   501-2622 (32MB), 501-2480 or 501-5691 (64MB), 501-3136 (128MB),
  2187.         #   501-4743 or 501-5896 (256MB)
  2188.         #   200-pin 60ns Fast Page Mode ECC
  2189.         # Netra ft1800 is based on Ultra 450
  2190.         $devname="Tazmo (Tazmax/Tazmin)";
  2191.         $untested=0;
  2192.         $simmrangex="00000400";
  2193.         $simmbanks=4;
  2194.         $simmsperbank=4;
  2195.         @simmsizes=(32,64,128,256);
  2196.         @socketstr=("U1901","U1902","U1903","U1904","U1801","U1802","U1803","U1804","U1701","U1702","U1703","U1704","U1601","U1602","U1603","U1604");
  2197.         @groupstr=("A","A","A","A","B","B","B","B","C","C","C","C","D","D","D","D");
  2198.         @bankstr=(2,2,2,2,3,3,3,3,0,0,0,0,1,1,1,1);
  2199. }
  2200. if ($model eq "Ultra-250" | $ultra eq 250) {
  2201.         # Accepts 16MB, 32MB, 64MB, or 128MB DIMMs on motherboard
  2202.         #   501-2479 (16MB), 501-2622 (32MB), 501-2480 or 501-5691 (64MB),
  2203.         #   501-3136 (128MB)
  2204.         #   200-pin 60ns Fast Page Mode ECC
  2205.         $devname="Javelin";
  2206.         $untested=0;
  2207.         $simmrangex="00000200";
  2208.         $simmbanks=4;
  2209.         $simmsperbank=4;
  2210.         @simmsizes=(16,32,64,128);
  2211.         @socketstr=("U0701","U0801","U0901","U1001","U0702","U0802","U0902","U1002","U0703","U0803","U0903","U1003","U0704","U0804","U0904","U1004");
  2212.         @bankstr=("A","A","A","A","B","B","B","B","C","C","C","C","D","D","D","D");
  2213. }
  2214. if ($model eq "Ultra-80" | $ultra eq 80 | $ultra eq "420R") {
  2215.         # Also Netra t1400/1405
  2216.         # Accepts 32MB, 64MB, 128MB or 256MB DIMMs on motherboard, but Sun
  2217.         # only supports 64MB or 256MB DIMMs on motherboard
  2218.         #   501-5691 (64MB), 501-4743 (256MB)
  2219.         #   200-pin 60ns 5V Fast Page Mode ECC, 576 bits data width
  2220.         # 64MB DIMMs same as in Ultra-60, 256MB DIMMs same as in Enterprise-450
  2221.         # U0403,U0404,U1403,U1404 bank 3 address 0xc0000000-0xffffffff
  2222.         # U0303,U0304,U1303,U1304 bank 2 address 0x80000000-0xbfffffff
  2223.         # U0401,U0402,U1401,U1402 bank 1 address 0x40000000-0x7fffffff
  2224.         # U0301,U0302,U1301,U1302 bank 0 address 0x00000000-0x3fffffff
  2225.         # The minimum requirement is four DIMMs in any bank. DIMMs can be
  2226.         # installed in any bank order. DIMMs are required on both the Riser
  2227.         # Board (U0[34]0?) and the System Board (U1[34]0?). Two-way and
  2228.         # four-way memory bank interleaving is supported.
  2229.         #
  2230.         # prtconf does not reliably show the size of DIMMs in each slot.
  2231.         # It shows this:
  2232.         #  4096MB system: 00000000.00000000.00000001.00000000
  2233.         #  1536MB system: 00000000.00000000.00000000.60000000
  2234.         #  1024MB system: 00000000.00000000.00000000.40000000
  2235.         #   512MB system: 00000000.00000000.00000000.20000000
  2236.         #   256MB system: 00000000.00000000.00000000.10000000
  2237.         # which is useless! A system with 4GB is reported as having
  2238.         # 4 1GB DIMMs instead of 16 256MB DIMMs.
  2239.         # This is apparently an issue that Sun may fix in the OBP.
  2240.         # It is broken with OBP 3.27.0 2000/08/23 (patch 109082-02) and older.
  2241.         # Sun ships U80 1GB configurations w/ 4x256MB DIMMs
  2242.         # Sun ships U80 256MB configurations w/ 4x64MB DIMMs
  2243.         # 64MB DIMM 501-2480 and 128MB DIMM 501-3136 are not supported.
  2244.         # 16MB and 32MB DIMMs are not sold for the Ultra 80.
  2245.         $devname="Quasar (U80), Quahog (420R), Lightweight 3 (Netra t140x)";
  2246.         $devname="Quasar" if ($ultra eq 80);
  2247.         $devname="Quahog" if ($ultra eq "420R");
  2248.         $untested=0;
  2249.         $recognized=-1;
  2250.         $simmrangex="00000400";
  2251.         $simmbanks=4;
  2252.         $simmsperbank=4;
  2253.         @simmsizes=(32,64,128,256); # Sun only supports 64MB and 256MB DIMMs
  2254.         @socketstr=("U0301","U0302","U1301","U1302","U0401","U0402","U1401","U1402","U0303","U0304","U1303","U1304","U0403","U0404","U1403","U1404");
  2255.         @bankstr=(0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3);
  2256. }
  2257. if ($ultra eq "Sun Blade 1000" | $ultra eq "Sun Blade 2000" | $ultra eq "Sun Fire 280R" | $ultra eq "Netra 20") {
  2258.         # Accepts up to 8 128MB, 256MB, 512MB, 1GB or 2GB DIMMs installed in
  2259.         #  groups of four DIMMs per bank on motherboard
  2260.         # Uses 232-pin 3.3V ECC 7ns SDRAM
  2261.         # J0407 Group 1 Bank 1/3 address 0x0fa000000 - 0x1f3ffffff
  2262.         # J0406 Group 0 Bank 0/2 address 0x000000000 - 0x0f9ffffff
  2263.         # J0305 Group 1 Bank 1/3 address 0x0fa000000 - 0x1f3ffffff
  2264.         # J0304 Group 0 Bank 0/2 address 0x000000000 - 0x0f9ffffff
  2265.         # J0203 Group 1 Bank 1/3 address 0x0fa000000 - 0x1f3ffffff
  2266.         # J0202 Group 0 Bank 0/2 address 0x000000000 - 0x0f9ffffff
  2267.         # J0101 Group 1 Bank 1/3 address 0x0fa000000 - 0x1f3ffffff
  2268.         # J0100 Group 0 Bank 0/2 address 0x000000000 - 0x0f9ffffff
  2269.         # The minimum memory requirement is four DIMMs in any Group
  2270.         # DIMMs can be installed in any group order
  2271.         # Each group addresses 4GB of memory
  2272.         # Memory slots (Jxxxx) map to same-numbered DIMMs (Uxxxx)
  2273.         # For maximum 4-way interleaving, install 8 DIMMs of identical sizes
  2274.         $devname="Excalibur (Sun Blade 1000), Littleneck (Sun Fire 280R), Lightweight 2+ (Netra 20/Netra T4), Sun Blade 2000 (Sun Blade 2000)";
  2275.         $devname="Excalibur" if ($ultra eq "Sun Blade 1000");
  2276.         $devname="Littleneck" if ($ultra eq "Sun Fire 280R");
  2277.         $devname="Lightweight 2+" if ($ultra eq "Netra 20");
  2278.         $devname="Sun Blade 2000" if ($ultra eq "Sun Blade 2000");
  2279.         $untested=0;
  2280.         # SB1000 uses 501-4143, 501-5938, or 501-6230 motherboards
  2281.         # SB1000 can use 600, 750 and 900MHz UltraSPARC-III CPUs
  2282.         # SB1000 can use 900MHz and 1.05GHz UltraSPARC-III+ Cu CPUs
  2283.         # SB2000 uses 501-6230 motherboards
  2284.         # SB2000 only uses 900MHz and 1.05GHz UltraSPARC-III+ Cu CPUs
  2285.         # assume all SB2000 use 501-6230 motherboard with UltraSPARC-III+ CPU
  2286.         if ($motherboard =~ /501-6230/ & $ultra eq "Sun Blade 1000" & $banner =~ /UltraSPARC-III+/) {
  2287.                 $ultra="Sun Blade 2000";
  2288.                 $realmodel="(Sun Blade 2000)";
  2289.         }
  2290.         $prtdiag_has_mem=1;
  2291.         $simmrangex="00001000";
  2292.         $simmbanks=2;
  2293.         $simmsperbank=4;
  2294.         @simmsizes=(128,256,512,1024,2048);
  2295.         @socketstr=("J0100","J0202","J0304","J0406","J0101","J0203","J0305","J0407");
  2296.         @bankstr=(0,0,0,0,1,1,1,1);
  2297. }
  2298. if ($model eq "Sun-Blade-100" | $ultra eq "Sun Blade 100" | $ultra eq "Sun Blade 150") {
  2299.         # Accepts 128MB, 256MB or 512MB DIMMs on motherboard
  2300.         # Uses 168-pin 3.3V ECC PC133 CL=3 SDRAM
  2301.         # U5 DIMM3 address 0x60000000 - 0x7fffffff or 0xc0000000 - 0xffffffff
  2302.         # U4 DIMM2 address 0x40000000 - 0x5fffffff or 0x80000000 - 0xbfffffff
  2303.         # U3 DIMM1 address 0x20000000 - 0x3fffffff or 0x40000000 - 0x7fffffff
  2304.         # U2 DIMM0 address 0x00000000 - 0x1fffffff or 0x00000000 - 0x3fffffff
  2305.         # The minimum memory requirement is one DIMM in U2
  2306.         # The memory installation sequence is U2, U3, U4, U5
  2307.         # Each bank addresses 512MB of memory with 500MHz UltraSPARC
  2308.         # Each bank addresses 1GB of memory with >= 550MHz UltraSPARC
  2309.         $devname="Grover" if ($model eq "Sun-Blade-100" | $ultra eq "Sun Blade 100");
  2310.         $devname="Grover Plus" if ($ultra eq "Sun Blade 150");
  2311.         $untested=0;
  2312.         $untested=1 if ($cpufreq > 520);
  2313.         $untested=0 if ($ultra eq "Sun Blade 150");
  2314.         $prtdiag_has_mem=1;
  2315.         $simmrangex=($cpufreq > 520) ? "00000400" : "00000200";
  2316.         $simmbanks=4;
  2317.         $simmsperbank=1;
  2318.         @simmsizes=(128,256,512);
  2319.         @socketstr=("DIMM0","DIMM1","DIMM2","DIMM3");
  2320.         @bankstr=(0,1,2,3);
  2321. }
  2322. if ($ultra eq "Sun Fire" || $ultra eq "Sun Fire 15K" || $ultra eq "Sun Fire 12K") {
  2323.         # Sun Fire 3800 system
  2324.         #   2-8 UltraSPARC-III processors
  2325.         #   Up to 2 CPU/Memory boards
  2326.         # Sun Fire 4800, 4810 and 6800 system
  2327.         #   2-12 UltraSPARC-III processors
  2328.         #   Up to 3 CPU/Memory boards
  2329.         # Sun Fire 6800 system
  2330.         #   2-24 UltraSPARC-III processors
  2331.         #   Up to 6 CPU/Memory boards
  2332.         # Sun Fire 15K system - untested
  2333.         #   16-106 UltraSPARC-III processors
  2334.         #   Up to 18 CPU/Memory boards
  2335.         # Sun Fire 12K system - untested
  2336.         #   up to 56 UltraSPARC-III processors and 288GB memory
  2337.         # Each CPU/Memory board holds up to 4 processors and up to 32GB memory
  2338.         #  (32 DIMMs per board, 8 banks of 4 DIMMs)
  2339.         # Accepts 256MB, 512MB or 1GB DIMMs
  2340.         # System Board slots are labeled SB0 and higher
  2341.         # A populated DIMM bank requires an UltraSPARC III CPU.
  2342.         # DIMMs are 232-pin 3.3V ECC 7ns SDRAM
  2343.         # prtdiag output shows the memory installed.
  2344.         #
  2345.         # CPU1 and CPU0 Memory  CPU3 and CPU2 Memory
  2346.         # --------------------  --------------------
  2347.         # Socket CPU Bank DIMM  Socket CPU Bank DIMM
  2348.         # ------ --- ---- ----  ------ --- ---- ----
  2349.         # J14600  P1  B0   D3   J16600  P3  B0   D3
  2350.         # J14601  P1  B1   D3   J16601  P3  B1   D3
  2351.         # J14500  P1  B0   D2   J16500  P3  B0   D2
  2352.         # J14501  P1  B1   D2   J16501  P3  B1   D2
  2353.         # J14400  P1  B0   D1   J16400  P3  B0   D1
  2354.         # J14401  P1  B1   D1   J16401  P3  B1   D1
  2355.         # J14300  P1  B0   D0   J16300  P3  B0   D0
  2356.         # J14301  P1  B1   D0   J16301  P3  B1   D0
  2357.         # J13600  P0  B0   D3   J15600  P2  B0   D3
  2358.         # J13601  P0  B1   D3   J15601  P2  B1   D3
  2359.         # J13500  P0  B0   D2   J15500  P2  B0   D2
  2360.         # J13501  P0  B1   D2   J15501  P2  B1   D2
  2361.         # J13400  P0  B0   D1   J15400  P2  B0   D1
  2362.         # J13401  P0  B1   D1   J15401  P2  B1   D1
  2363.         # J13300  P0  B0   D0   J15300  P2  B0   D0
  2364.         # J13301  P0  B1   D0   J15301  P2  B1   D0
  2365.         #
  2366.         $devname="Serengeti" if ($ultra eq "Sun Fire");
  2367.         $devname="Serengeti8, SF3800 or SP" if ($banner =~ /Sun Fire 3800\b/);
  2368.         $devname="Serengeti12, SF4800 or MD" if ($banner =~ /Sun Fire 4800\b/);
  2369.         $devname="Serengeti12i, SF4810 or ME" if ($banner =~ /Sun Fire 4810\b/);
  2370.         $devname="Serengeti24, SF6800 or DC" if ($banner =~ /Sun Fire 6800\b/);
  2371.         $devname="Starcat, Serengeti72" if ($ultra eq "Sun Fire 15K");
  2372.         $devname="Starkitty" if ($ultra eq "Sun Fire 12K");
  2373.         $untested=0;
  2374.         $untested=1 if ($ultra eq "Sun Fire 12K");
  2375.         $prtdiag_has_mem=1;
  2376.         @simmsizes=(256,512,1024);
  2377. }
  2378. if ($ultra eq "Sun Fire V880") {
  2379.         # Accepts 128MB, 256MB, 512MB or 1GB DIMMs in groups of four per CPU
  2380.         # 1GB DIMMs only supported on 900MHz or faster CPU/memory boards
  2381.         # 2-8 UltraSPARC-III processors, 750MHz or 900MHz
  2382.         # Up to 64GB memory, 8GB max per CPU, 4 DIMMs per CPU, 2 CPUs per board
  2383.         # DIMMs must be added four-at-a-time within the same group of DIMM
  2384.         #  slots; every fourth slot belongs to the same DIMM group.
  2385.         # Each CPU/Memory board must be populated with a minimum of eight DIMMs,
  2386.         #  installed in groups A0 and B0.
  2387.         # Each group used must have four identical DIMMs installe (all four
  2388.         #  DIMMs must be from the same manufacturing vendor and must have the
  2389.         #  same capacity).
  2390.         # DIMMs are 232-pin 3.3V ECC 7ns SDRAM
  2391.         # Uses 128-bit-wide path to memory, 150MHz DIMM modules, 2.4GB/sec
  2392.         #   bandwidth to processor and an aggregate memory bw of 9.6GB/sec
  2393.         # prtdiag output shows the memory installed.
  2394.         #
  2395.         # CPU CPU/Memory Slot Associated DIMM Group
  2396.         # --- --------------- ---------------------
  2397.         #  0      Slot A             A0,A1
  2398.         #  2      Slot A             B0,B1
  2399.         #  1      Slot B             A0,A1
  2400.         #  3      Slot B             B0,B1
  2401.         #  4      Slot C             A0,A1
  2402.         #  6      Slot C             B0,B1
  2403.         #  5      Slot D             A0,A1
  2404.         #  7      Slot D             B0,B1
  2405.         #
  2406.         $devname="Daktari";
  2407.         $untested=0;
  2408.         @simmsizes=($cpufreq < 800) ? (128,256,512) : (128,256,512,1024);
  2409.         @socketstr=("A0","A1","B0","B1");
  2410.         # System should not have any empty DIMM slots
  2411.         $sockets_used="A0 A1 B0 B1";
  2412.         $prtdiag_has_mem=1;
  2413. }
  2414. if ($ultra eq "Sun Fire V480") {
  2415.         # Accepts 128MB, 256MB, 512MB or 1GB DIMMs in groups of four per CPU
  2416.         # 2 or 4 UltraSPARC-III processors, 900MHz
  2417.         # Up to 32GB memory, 8GB max per CPU, 4 DIMMs per CPU, 2 CPUs per board
  2418.         # Smaller version of Sun Fire V880 above
  2419.         $devname="Cherrystone, cstone";
  2420.         $untested=0;
  2421.         @simmsizes=(128,256,512,1024);
  2422.         @socketstr=("A0","A1","B0","B1");
  2423.         # System should not have any empty DIMM slots
  2424.         $sockets_used="A0 A1 B0 B1";
  2425.         $prtdiag_has_mem=1;
  2426. }
  2427.  
  2428. if ($model =~ /Ultra-Enterprise/ | $ultra eq "e") {
  2429.         # E3x00/E4x00/E5x00/E6x00 accepts 8MB, 32MB, 128MB or 256MB DIMMs on
  2430.         #  motherboard, 2 banks of 8 DIMMs per board.
  2431.         #  256MB DIMMs (2GB kit X7026A) can be used with OBP 3.2.24 or later and
  2432.         #  Solaris 2.5.1 11/97, Solaris 2.6 3/98 or later
  2433.         #   501-2652 (8MB), 501-2653 (32MB), 501-2654 (128MB), 501-5658 (256MB)
  2434.         #   168-pin 60ns 3.3V ECC
  2435.         # E10000 accepts 32MB or 128MB DIMMs on motherboard,
  2436.         #  using 2 or 4 banks of 8 DIMMs per board.
  2437.         #   501-2653 (32MB), 501-2654 (128MB)
  2438.         #   168-pin 60ns 3.3V ECC
  2439.         $devname="Duraflame" if ($banner =~ /\bE?3[05]00\b/);
  2440.         $devname="Campfire Rack" if ($banner =~ /\bE?5[05]00\b/);
  2441.         $devname="Campfire" if ($banner =~ /\bE?4[05]00\b/);
  2442.         $devname="Sunfire" if ($banner =~ /\bE?6[05]00\b/);
  2443.         $devname .= "+" if ($banner =~ /\bE?[3-6]500\b/);
  2444.         $devname="Starfire" if ($model =~ /-10000\b/);
  2445.         $untested=1;
  2446.         if ($banner =~ /\bE?[3-6][05]00\b/) {
  2447.                 $untested=0;
  2448.                 @simmsizes=(8,32,128,256);
  2449.         }
  2450.         if ($model =~ /-10000\b/) {
  2451.                 $untested=0;
  2452.                 @simmsizes=(32,128);
  2453.         }
  2454.         $prtdiag_has_mem=1;
  2455.         @prtdiag=`$prtdiag_exec` if ($filename eq "");
  2456.         $i=0;
  2457.         foreach $line (@prtdiag) {
  2458.                 if ($line =~ /Memory Units:/) {
  2459.                         # Start of memory section, Solaris 2.5.1 format
  2460.                         $flag_mem=1;
  2461.                         $format_mem=1;
  2462.                         $flag_cpu=0;    # End of CPU section
  2463.                 }
  2464.                 if ($line =~ /===== Memory /) {
  2465.                         # Start of memory section, Solaris 2.6 and later format
  2466.                         $flag_mem=1;
  2467.                         $format_mem=2;
  2468.                         $flag_cpu=0;    # End of CPU section
  2469.                 }
  2470.                 if ($line =~ /Factor/) {
  2471.                         # No interleave factor on E10000
  2472.                         $format_mem += 2 if ($format_mem == 1 | $format_mem == 2);
  2473.                 }
  2474.                 if ($line =~ /IO Cards/) {
  2475.                         $flag_cpu=0;    # End of CPU section
  2476.                         $flag_mem=0;    # End of memory section
  2477.                 }
  2478.                 if ($flag_cpu >= 1 & $line ne "\n") {
  2479.                         push(@boards_cpu, "$line");
  2480.                         $boardfound_cpu=1;
  2481.                         if ($line =~ /Board/) {
  2482.                                 $boardslot_cpu=substr($line,6,2);
  2483.                         } else {
  2484.                                 $boardslot_cpu=substr($line,0,2);
  2485.                         }
  2486.                         $boardslot_cpu =~ s/[: ]//g;
  2487.                         if ($flag_cpu == 2 & $boardslot_cpus !~ /\s$boardslot_cpu\s/ & $boardslot_cpu ne "") {
  2488.                                 push(@boardslot_cpus, "$boardslot_cpu");
  2489.                                 $boardslot_cpus .= $boardslot_cpu . " ";
  2490.                         }
  2491.                 }
  2492.                 if ($line =~ /CPU Units:/) {
  2493.                         $flag_cpu=1;    # Start of CPU section
  2494.                         $flag_mem=0;    # End of memory section
  2495.                         $format_cpu=1;
  2496.                 }
  2497.                 if ($line =~ /===== CPUs =====/) {
  2498.                         $flag_cpu=1;    # Start of CPU section
  2499.                         $flag_mem=0;    # End of memory section
  2500.                         $format_cpu=2;
  2501.                 }
  2502.                 if ($flag_mem == 2 & $line ne "\n") {
  2503.                         if ($line =~ /Board/) {
  2504.                                 $boardslot_mem=substr($line,5,2);
  2505.                         } else {
  2506.                                 $boardslot_mem=substr($line,0,2);
  2507.                         }
  2508.                         $boardslot_mem =~ s/[: ]//g;
  2509.                         if ($boardslot_mems !~ /\s$boardslot_mem\s/) {
  2510.                                 push(@boardslot_mems, "$boardslot_mem");
  2511.                                 $boardslot_mems .= $boardslot_mem . " ";
  2512.                         }
  2513.                         if ($format_mem == 1) {
  2514.                                 # Memory on each system board, E10000
  2515.                                 $mem0=substr($line,12,4);
  2516.                                 $mem0=0 if ($mem0 !~ /\d+/);
  2517.                                 $dimm0=$mem0 / 8;
  2518.                                 if ($dimm0 > 0) {
  2519.                                         $dimms0=sprintf("8x%3d", $dimm0);
  2520.                                         push(@simmsizesfound, "$dimm0");
  2521.                                 } else {
  2522.                                         $dimms0="     ";
  2523.                                         &found_empty_bank("Bank 0");
  2524.                                 }
  2525.                                 $mem1=substr($line,20,4);
  2526.                                 $mem1=0 if ($mem1 !~ /\d+/);
  2527.                                 $dimm1=$mem1 / 8;
  2528.                                 if ($dimm1 > 0) {
  2529.                                         $dimms1=sprintf("8x%3d", $dimm1);
  2530.                                         push(@simmsizesfound, "$dimm1");
  2531.                                 } else {
  2532.                                         $dimms1="     ";
  2533.                                         &found_empty_bank("Bank 1");
  2534.                                 }
  2535.                                 $mem2=substr($line,28,4);
  2536.                                 $mem2=0 if ($mem2 !~ /\d+/);
  2537.                                 $dimm2=$mem2 / 8;
  2538.                                 if ($dimm2 > 0) {
  2539.                                         $dimms2=sprintf("8x%3d", $dimm2);
  2540.                                         push(@simmsizesfound, "$dimm2");
  2541.                                 } else {
  2542.                                         $dimms2="     ";
  2543.                                         &found_empty_bank("Bank 2");
  2544.                                 }
  2545.                                 $mem3=substr($line,36,4);
  2546.                                 $mem3=0 if ($mem3 !~ /\d+/);
  2547.                                 $dimm3=$mem3 / 8;
  2548.                                 if ($dimm3 > 0) {
  2549.                                         $dimms3=sprintf("8x%3d", $dimm3);
  2550.                                         push(@simmsizesfound, "$dimm3");
  2551.                                 } else {
  2552.                                         $dimms3="     ";
  2553.                                         &found_empty_bank("Bank 3");
  2554.                                 }
  2555.                                 $newline=substr($line,0,10);
  2556.                                 $newline .= "  " . $mem0 . "  " . $dimms0;
  2557.                                 $newline .= "  " . $mem1 . "  " . $dimms1;
  2558.                                 $newline .= "  " . $mem2 . "  " . $dimms2;
  2559.                                 $newline .= "  " . $mem3 . "  " . $dimms3;
  2560.                                 $newline .= "\n";
  2561.                                 push(@boards_mem, "$newline");
  2562.                                 $boardfound_mem=1;
  2563.                         }
  2564.                         if ($format_mem == 2) {
  2565.                                 # Memory on each system board, E10000
  2566.                                 # untested reporting of empty banks
  2567.                                 $untested=1;
  2568.                                 $bank_slot=substr($line,6,2);
  2569.                                 $mem=substr($line,12,4);
  2570.                                 $mem=0 if ($mem !~ /\d+/);
  2571.                                 $dimm=$mem / 8;
  2572.                                 if ($dimm > 0) {
  2573.                                         $dimms=sprintf("8x%3d", $dimm);
  2574.                                         push(@simmsizesfound, "$dimm");
  2575.                                         $newline=substr($line,0,18) . $dimms;
  2576.                                         $newline .= substr($line,16,47);
  2577.                                         push(@boards_mem, "$newline");
  2578.                                         $boardfound_mem=1;
  2579.                                 } else {
  2580.                                         $flag_mem=0;
  2581.                                         &found_empty_bank("Bank $bank_slot");
  2582.                                 }
  2583.                                 if ($bank_slot == 0) {
  2584.                                         $next_boardslot_mem=substr($prtdiag[$i + 1],0,2);
  2585.                                         $next_boardslot_mem =~ s/[: ]//g;
  2586.                                         if ($next_boardslot_mem ne $boardslot_mem) {
  2587.                                                 &found_empty_bank("Bank 1");
  2588.                                         }
  2589.                                 }
  2590.                                 if ($bank_slot == 1) {
  2591.                                         $prev_boardslot_mem=substr($prtdiag[$i - 1],0,2);
  2592.                                         $prev_boardslot_mem =~ s/[: ]//g;
  2593.                                         if ($prev_boardslot_mem ne $boardslot_mem) {
  2594.                                                 &found_empty_bank("Bank 0");
  2595.                                         }
  2596.                                 }
  2597.                         }
  2598.                         if ($format_mem == 3) {
  2599.                                 # Memory on each system board, E[3456]x00
  2600.                                 $mem0=substr($line,10,4);
  2601.                                 $mem0=0 if ($mem0 !~ /\d+/);
  2602.                                 $dimm0=$mem0 / 8;
  2603.                                 if ($dimm0 > 0) {
  2604.                                         $dimms0=sprintf("8x%3d", $dimm0);
  2605.                                         push(@simmsizesfound, "$dimm0");
  2606.                                 } else {
  2607.                                         $dimms0="     ";
  2608.                                         &found_empty_bank("Bank 0");
  2609.                                 }
  2610.                                 $memlength=length $line;
  2611.                                 if ($memlength > 34) {
  2612.                                         $mem1=substr($line,34,4);
  2613.                                 } else {
  2614.                                         $mem1=0;
  2615.                                 }
  2616.                                 $mem1=0 if ($mem1 !~ /\d+/);
  2617.                                 $dimm1=$mem1 / 8;
  2618.                                 if ($dimm1 > 0) {
  2619.                                         $dimms1=sprintf("8x%3d", $dimm1);
  2620.                                         push(@simmsizesfound, "$dimm1");
  2621.                                 } else {
  2622.                                         $dimms1="     ";
  2623.                                         &found_empty_bank("Bank 1");
  2624.                                 }
  2625.                                 $newline=substr($line,0,16) . $dimms0;
  2626.                                 $newline .= substr($line,16,24);
  2627.                                 if ($dimm1 > 0) {
  2628.                                         $newline .= $dimms1;
  2629.                                         $newline .= substr($line,39,16);
  2630.                                 }
  2631.                                 push(@boards_mem, "$newline");
  2632.                                 $boardfound_mem=1;
  2633.                         }
  2634.                         if ($format_mem == 4) {
  2635.                                 # Memory on each system board, E[3456]x00
  2636.                                 $bank_slot=substr($line,7,1);
  2637.                                 $mem=substr($line,12,4);
  2638.                                 $mem=0 if ($mem !~ /\d+/);
  2639.                                 $dimm=$mem / 8;
  2640.                                 if ($dimm > 0) {
  2641.                                         $dimms=sprintf("8x%3d", $dimm);
  2642.                                         push(@simmsizesfound, "$dimm");
  2643.                                         $newline=substr($line,0,18) . $dimms;
  2644.                                         $newline .= substr($line,16,47);
  2645.                                         push(@boards_mem, "$newline");
  2646.                                         $boardfound_mem=1;
  2647.                                 } else {
  2648.                                         $flag_mem=0;
  2649.                                         &found_empty_bank("Bank $bank_slot");
  2650.                                 }
  2651.                                 if ($bank_slot == 0) {
  2652.                                         $next_boardslot_mem=substr($prtdiag[$i + 1],0,2);
  2653.                                         $next_boardslot_mem =~ s/[: ]//g;
  2654.                                         if ($next_boardslot_mem ne $boardslot_mem) {
  2655.                                                 &found_empty_bank("Bank 1");
  2656.                                         }
  2657.                                 }
  2658.                                 if ($bank_slot == 1) {
  2659.                                         $prev_boardslot_mem=substr($prtdiag[$i - 1],0,2);
  2660.                                         $prev_boardslot_mem =~ s/[: ]//g;
  2661.                                         if ($prev_boardslot_mem ne $boardslot_mem) {
  2662.                                                 &found_empty_bank("Bank 0");
  2663.                                         }
  2664.                                 }
  2665.                         }
  2666.                 }
  2667.                 if ($flag_cpu == 1 & $line =~ /-----/) {
  2668.                         # Next lines are the CPUs on each system board
  2669.                         $flag_cpu=2;
  2670.                 }
  2671.                 if ($flag_mem == 1 & $line =~ /-----/) {
  2672.                         # Next lines are the memory on each system board
  2673.                         $flag_mem=2;
  2674.                 }
  2675.                 $i++;
  2676.         }
  2677.         &show_header;
  2678.         if ($boardfound_mem) {
  2679.                 if ($boardfound_cpu) {
  2680.                         foreach $board (@boardslot_cpus) {
  2681.                                 if ($boardslot_mems !~ /\s$board\s/) {
  2682.                                         $boardslot_mem=$board;
  2683.                                         if ($format_mem <= 2) {
  2684.                                                 # E10000
  2685.                                                 &found_empty_bank("Bank 0");
  2686.                                                 &found_empty_bank("Bank 1");
  2687.                                                 &found_empty_bank("Bank 2");
  2688.                                                 &found_empty_bank("Bank 3");
  2689.                                         } else {
  2690.                                                 # E3x00/E4x00/E5x00/E6x00
  2691.                                                 &found_empty_bank("Bank 0");
  2692.                                                 &found_empty_bank("Bank 1");
  2693.                                         }
  2694.                                 }
  2695.                         }
  2696.                 }
  2697.                 if ($format_mem == 1) {
  2698.                         # E10000 running Solaris 2.5.1
  2699.                         print "               Bank 0       Bank 1       Bank 2       Bank 3\n";
  2700.                         print "             MB   DIMMs   MB   DIMMs   MB   DIMMs   MB   DIMMs\n";
  2701.                         print "            ----  -----  ----  -----  ----  -----  ----  -----\n";
  2702.                         print @boards_mem;
  2703.                 }
  2704.                 if ($format_mem == 2) {
  2705.                         # E10000 running Solaris 2.6 or later
  2706.                         print "Brd   Bank   MB   DIMMs   Status   Condition  Speed\n";
  2707.                         print "---  -----  ----  -----  -------  ----------  -----\n";
  2708.                         print @boards_mem;
  2709.                 }
  2710.                 if ($format_mem == 3) {
  2711.                         # E3x00/E4x00/E5x00/E6x00 running Solaris 2.5.1
  2712.                         print "                   Bank 0                       Bank 1\n";
  2713.                         print "          J3100-J3800   Interleave     J3101-J3801   Interleave\n";
  2714.                         print "           MB   DIMMs  Factor  With     MB   DIMMs  Factor  With\n";
  2715.                         print "          ----  -----  ------  ----    ----  -----  ------  ----\n";
  2716.                         print @boards_mem;
  2717.                 }
  2718.                 if ($format_mem == 4) {
  2719.                         # E3x00/E4x00/E5x00/E6x00 running Solaris 2.6 or later
  2720.                         print "                                                     Intrlv.  Intrlv.\n";
  2721.                         print "Brd   Bank   MB   DIMMs   Status   Condition  Speed   Factor   With\n";
  2722.                         print "---  -----  ----  -----  -------  ----------  -----  -------  -------\n";
  2723.                         print @boards_mem;
  2724.                         print "Bank 0 uses sockets J3100-J3800, Bank 1 uses sockets J3101-J3801\n";
  2725.                 }
  2726.                 $empty_banks=" None" if ($empty_banks eq "");
  2727.                 print "empty memory banks:$empty_banks\n";
  2728.         }
  2729.         $totmem=$installed_memory;
  2730.         &finish;
  2731.         exit;
  2732. }
  2733.  
  2734. #
  2735. # Check to see if this system has memory defined in the prtdiag output
  2736. #
  2737. &check_prtdiag;
  2738.  
  2739. #
  2740. # Check to see if this system has module information in prtconf output
  2741. # (Seen on Fujitsu GP7000, GP7000F, PrimePower 200 & 400)
  2742. #
  2743. if ($gotmodule | $gotmodulenames) {
  2744.         if ($gotmodulenames) {
  2745.                 @simmslots=split(/\./, $gotmodulenames);
  2746.         } else {
  2747.                 @simmslots=split(/\./, $gotmodule);
  2748.         }
  2749.         for($val=0; $val < scalar(@simmslots); $val += 2) {
  2750.                 if ($gotmodulenames) {
  2751.                         $socket=$simmslots[$val];
  2752.                 } else {
  2753.                         $socket="SLOT" . $val / 2;
  2754.                 }
  2755.                 $simmsz=$simmslots[$val + 1];
  2756.                 $simmsize=hex("0x$simmsz") / $meg;
  2757.                 $perlhexbug=1 if ($simmsize < 0);
  2758.                 $totmem += $simmsize;
  2759.                 if ($simmsize > 0) {
  2760.                         push(@simmsizesfound, "$simmsize");
  2761.                         if (! $boardfound_mem) {
  2762.                                 push(@memorylines, "$socket has a ${simmsize}MB");
  2763.                                 if ($simmsize > 1023) {
  2764.                                         push(@memorylines, " (");
  2765.                                         push(@memorylines, $simmsize/1024);
  2766.                                         push(@memorylines, "GB)");
  2767.                                 }
  2768.                                 push(@memorylines, " $memtype\n");
  2769.                         }
  2770.                         $sockets_used .= " $socket";
  2771.                 }
  2772.         }
  2773.         &show_header;
  2774.         if ($boardfound_mem) {
  2775.                 print @boards_mem;
  2776.         } else {
  2777.                 print @memorylines;
  2778.         }
  2779.         $totmem=$installed_memory;
  2780.         &finish;
  2781.         exit;
  2782. }
  2783.  
  2784. #
  2785. # Display memory if found in prtdiag output
  2786. #
  2787. if ($boardfound_mem) {
  2788.         &show_header;
  2789.         print @boards_mem;
  2790.         $totmem=$installed_memory;
  2791. }
  2792. #
  2793. # Look for empty memory banks on Sun Fire 3800, 4800, 4810, 6800, 12K and 15K
  2794. # systems.
  2795. #
  2796. if ($ultra eq "Sun Fire" || $ultra eq "Sun Fire 15K" || $ultra eq "Sun Fire 12K") {
  2797.         foreach $cpu (@boardslot_cpus) {
  2798.                 if ($boardslot_mems !~ /\s$cpu\/B0\s/) {
  2799.                         $empty_banks .= " $cpu/B0";
  2800.                 }
  2801.                 if ($boardslot_mems !~ /\s$cpu\/B1\s/) {
  2802.                         $empty_banks .= " $cpu/B1";
  2803.                 }
  2804.         }
  2805.         $empty_banks=" None" if ($empty_banks eq "");
  2806.         if ($boardslot_mems eq " ") {
  2807.                 $empty_banks=" Unknown";
  2808.                 $exitstatus=1;
  2809.         }
  2810.         print "empty memory banks:$empty_banks\n";
  2811. }
  2812. if ($boardfound_mem) {
  2813.         &finish;
  2814.         exit;
  2815. }
  2816.  
  2817. #
  2818. # OK, get ready to print out results
  2819. #
  2820. for($val=$val0; $val < scalar(@slots); $val += $valinc) {
  2821.         $newaddrmsb=substr($slots[$val - $valaddr - 1],3,5);
  2822.         $newaddrlsb=substr($slots[$val - $valaddr],0,3);
  2823.         if ($valinc == 4) {
  2824.                 $newsizemsb=substr($slots[$val - 1],3,5);
  2825.         } else {
  2826.                 $newsizemsb="";
  2827.         }
  2828.         $newsizelsb=substr($slots[$val],0,3);
  2829.         if ($sortslots) {
  2830.                 $mods{"$newaddrmsb$newaddrlsb"}="$newsizemsb$newsizelsb";
  2831.         } else {
  2832.                 push(@newslots, "$newaddrmsb$newaddrlsb");
  2833.                 push(@newslots, "$newsizemsb$newsizelsb");
  2834.         }
  2835. }
  2836. if ($sortslots) {
  2837.         for(sort keys %mods) {
  2838.                 push(@newslots, $_);
  2839.                 push(@newslots, $mods{$_});
  2840.         }
  2841. }
  2842.  
  2843. # For Ultra-30, determine if interleaving of banks using four DIMMs
  2844. if ($model eq "Ultra-30" | $ultra eq 30) {
  2845.         $interleave=2;
  2846.         # pairs show up in odd numbered address ranges
  2847.         for($val=0; $val < scalar(@newslots); $val += 2) {
  2848.                 $interleave=1 if ($newslots[$val] =~ /00000[1357]00/);
  2849.         }
  2850.         if ($interleave eq 2) {
  2851.                 $simmrangex="00000200";
  2852.                 $simmbanks=4;
  2853.                 $simmsperbank=4;
  2854.         } else {
  2855.                 $simmrangex="00000100";
  2856.                 $simmbanks=8;
  2857.                 $simmsperbank=2;
  2858.         }
  2859. }
  2860.  
  2861. # Check if SPARCsystem-600 has VME memory expansion boards
  2862. if ($model eq "SPARCsystem-600" | $model =~ /Sun.4.600/) {
  2863.         for($val=0; $val < scalar(@newslots); $val += 2) {
  2864.                 if ($newslots[$val] =~ /00000[4-9ab]00/) {
  2865.                         @simmsizes=(1,4,16);
  2866.                         push (@socketstr, @socketstr_exp);
  2867.                         push (@bankstr, @bankstr_exp);
  2868.                         push (@bytestr, @bytestr_exp);
  2869.                         if ($newslots[$val] =~ /00000[4-7]00/) {
  2870.                                 $exp="Expansion board 0 bank";
  2871.                         } else {
  2872.                                 $exp="Expansion board 1 bank";
  2873.                         }
  2874.                         push (@banksstr, ("$exp B0","$exp B1", "$exp B2","$exp B3"));
  2875.                 }
  2876.         }
  2877. }
  2878.  
  2879. # Hack: Try to rewrite memory line for Ultra-80 or Enterprise 420R
  2880. if ($model eq "Ultra-80" | $ultra eq 80 | $ultra eq "420R") {
  2881.         # 4GB of memory (maximum allowed)
  2882.         if ($newslots[1] eq "00001000") {
  2883.                 $newslots[1]="00000400";
  2884.                 $newslots[2]="00000400";
  2885.                 $newslots[3]="00000400";
  2886.                 $newslots[4]="00000800";
  2887.                 $newslots[5]="00000400";
  2888.                 $newslots[6]="00000c00";
  2889.                 $newslots[7]="00000400";
  2890.                 $recognized=-2;
  2891.         }
  2892.         # 2GB of memory (eliminate unsupported 512MB DIMM error)
  2893.         if ($newslots[1] eq "00000800") {
  2894.                 $newslots[1]="00000400";
  2895.                 $newslots[2]="00000400";
  2896.                 $newslots[3]="00000400";
  2897.         }
  2898. }
  2899.  
  2900. # Hack: Fix address ranges for Tatung COMPstation U60 and U80D
  2901. if ($banner =~ /COMPstation_U60_Series/ | $banner =~ /COMPstation_U80D_Series/) {
  2902.         # Tatung Science and Technology, http://www.tsti.com
  2903.         for($val=0; $val < scalar(@newslots); $val += 2) {
  2904.                 if ($newslots[$val] =~ /00000[46]00/) {
  2905.                         $simmbanks=4;
  2906.                 }
  2907.                 # Check for 256MB DIMMs or 256MB address range per bank
  2908.                 if ($newslots[$val+1] =~ /00000400/ | $newslots[$val] =~ /00000c00/) {
  2909.                         $simmrangex="00000400";
  2910.                         $simmbanks=4;
  2911.                 }
  2912.         }
  2913.         if ($simmbanks eq 6) {
  2914.                 # Skipped address range similar to Sun Ultra 60
  2915.                 @socketstr=("J17","J32","J36","J40","J18","J33","J37","J41","?","?","?","?","?","?","?","?","J19","J34","J38","J42","J20","J35","J39","J43");
  2916.                 @slotstr=(1,2,3,4,5,6,7,8,"?","?","?","?","?","?","?","?",9,10,11,12,13,14,15,16);
  2917.                 @bankstr=(0,0,0,0,1,1,1,1,"?","?","?","?","?","?","?","?",2,2,2,2,3,3,3,3);
  2918.         } else {
  2919.                 @socketstr=("J17","J32","J36","J40","J18","J33","J37","J41","J19","J34","J38","J42","J20","J35","J39","J43");
  2920.                 @slotstr=(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
  2921.                 @bankstr=(0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3);
  2922.         }
  2923. }
  2924.  
  2925. # Hack: Try to rewrite memory line for Sun Blade 1000 & 2000 if prtdiag output
  2926. #       did not show the memory. This does not expect 2GB DIMMs to be used.
  2927. if (($ultra eq "Sun Blade 1000" | $ultra eq "Sun Blade 2000" | $ultra eq "Sun Fire 280R") & ! $boardfound_mem) {
  2928.         # Assume 8GB is 8x1GB instead of 4x2GB
  2929.         if ($newslots[1] eq "00002000") {
  2930.                 $newslots[1]="00001000";
  2931.                 $newslots[2]="00001000";
  2932.                 $newslots[3]="00001000";
  2933.                 $recognized=-2;
  2934.         }
  2935.         # Assume 6GB is 4x1GB + 4x512MB instead of 4x1.5GB
  2936.         if ($newslots[1] eq "00001800") {
  2937.                 $newslots[1]="00001000";
  2938.                 $newslots[2]="00001000";
  2939.                 $newslots[3]="00000800";
  2940.                 $recognized=-1;
  2941.         }
  2942.         # Assume 5GB is 4x1GB + 4x256MB instead of 4x1280MB
  2943.         if ($newslots[1] eq "00001400") {
  2944.                 $newslots[1]="00001000";
  2945.                 $newslots[2]="00001000";
  2946.                 $newslots[3]="00000400";
  2947.                 $recognized=-1;
  2948.         }
  2949.         # Assume 4.5GB is 4x1GB + 4x128MB instead of 4x1152MB
  2950.         if ($newslots[1] eq "00001200") {
  2951.                 $newslots[1]="00001000";
  2952.                 $newslots[2]="00001000";
  2953.                 $newslots[3]="00000200";
  2954.                 $recognized=-1;
  2955.         }
  2956.         # Assume 3GB is 4x512MB + 4x256MB instead of 4x768MB
  2957.         if ($newslots[1] eq "00000c00") {
  2958.                 $newslots[1]="00000800";
  2959.                 $newslots[2]="00001000";
  2960.                 $newslots[3]="00000400";
  2961.                 $recognized=-1;
  2962.         }
  2963.         # Assume 2.5GB is 4x512MB + 4x128MB instead of 4x640MB
  2964.         if ($newslots[1] eq "00000a00") {
  2965.                 $newslots[1]="00000800";
  2966.                 $newslots[2]="00001000";
  2967.                 $newslots[3]="00000200";
  2968.                 $recognized=-1;
  2969.         }
  2970.         # Assume 1.5GB is 4x256MB + 4x128MB instead of 4x384MB
  2971.         if ($newslots[1] eq "00000600") {
  2972.                 $newslots[1]="00000400";
  2973.                 $newslots[2]="00001000";
  2974.                 $newslots[3]="00000200";
  2975.                 $recognized=-1;
  2976.         }
  2977. }
  2978.  
  2979. # Check for dual bank DIMMs on Ultra AXmp+
  2980. if ($ultra eq "AXmp+") {
  2981.         if ($#newslots eq 3) {
  2982.                 if ($newslots[2] =~ /00000[8c]00/) {
  2983.                         $simmrangex="00000800";
  2984.                         $dualbank=1 if ($newslots[1] eq $newslots[3]);
  2985.                 }
  2986.         }
  2987.         if ($#newslots ge 5) {
  2988.                 $dualbank=1 if ($newslots[4] =~ /00000[8c]00/);
  2989.         }
  2990.         if ($dualbank eq 1) {
  2991.                 @bankstr=("0,2","0,2","0,2","0,2","0,2","0,2","0,2","0,2","1,3","1,3","1,3","1,3","1,3","1,3","1,3","1,3");
  2992.                 # Rearrange slots if necessary
  2993.                 if ($#newslots ge 5) {
  2994.                         if ($newslots[4] eq "00000800") {
  2995.                                 $temp1=$newslots[2];
  2996.                                 $temp2=$newslots[3];
  2997.                                 $newslots[2]=$newslots[4];
  2998.                                 $newslots[3]=$newslots[5];
  2999.                                 $newslots[4]=$temp1;
  3000.                                 $newslots[5]=$temp2;
  3001.                         }
  3002.                 }
  3003.         }
  3004. }
  3005.  
  3006. for($val=0; $val < scalar(@newslots); $val += 2) {
  3007.         $simmaddr=$newslots[$val];
  3008.         $simmsz=$newslots[$val + 1];
  3009.         $simmsize=hex("0x$simmsz");
  3010.         $perlhexbug=1 if ($simmsize < 0);
  3011.         $totmem += $simmsize;
  3012.  
  3013.         if (($model eq "Sun 4/75" | $model eq "SS-2") & $simmbanks < $bankcnt + 2) {
  3014.                 # SS2 SBus memory card
  3015.                 if ($simmaddr eq "00000080") {
  3016.                         $buffer .= "SBus primary contains ";
  3017.                 } else {
  3018.                         $buffer .= "SBus secondary contains ";
  3019.                 }
  3020.                 $start1=hex("0x$simmaddr") * $meg;
  3021.                 $perlhexbug=1 if ($start1 < 0);
  3022.                 $simmrange=hex("0x$simmrangex") * $meg;
  3023.                 $perlhexbug=1 if ($simmrange < 0);
  3024.                 $start1x=sprintf("%08lx", $start1);
  3025.                 $stop1x=sprintf("%08lx", $start1 + (2 * $simmrange) - 1);
  3026.                 $totmem += $simmsize;
  3027.                 $simmsize *= 2;
  3028.                 $val += 2;
  3029.                 $buffer .= "${simmsize}MB";
  3030.                 $buffer .= " (address 0x${start1x}-0x$stop1x)" if ($verbose);
  3031.                 $buffer .= "\n";
  3032.         } elsif ($simmbanks > 0) {
  3033.                 $start1=hex("0x$simmaddr") * $meg;
  3034.                 $perlhexbug=1 if ($start1 < 0);
  3035.                 $simmrange=hex("0x$simmrangex") * $meg;
  3036.                 $perlhexbug=1 if ($simmrange < 0);
  3037.                 if ($simmrange < hex("0x00001000") * $meg) {
  3038.                         $start1x=sprintf("%08lx", $start1);
  3039.                         $stop1x=sprintf("%08lx", $start1 + ($simmsize * $meg) - 1);
  3040.                 } else {
  3041.                         # Systems with > 4GB of memory
  3042.                         $start1x=$simmaddr . "00000";
  3043.                         $start1x =~ s/^0000//g;
  3044.                         $stop1x=sprintf("%08lx", ($start1 / $meg) + $simmsize - 1) . "fffff";
  3045.                         $stop1x =~ s/^0000//g;
  3046.                 }
  3047.                 $cnt=0;
  3048.                 $maxcnt=$simmbanks * $simmsperbank / $simmspergroup;
  3049.                 while ($cnt < $maxcnt) {
  3050.                         if ($start1 >= ($simmrange * $cnt) & $start1 < ($simmrange * ($cnt + 1))) {
  3051.                                 $bankcnt=$cnt;
  3052.                                 $cnt3=($bankcnt * $simmsperbank / $simmspergroup);
  3053.                                 if ($#socketstr) {
  3054.                                         $socket=$socketstr[$cnt3];
  3055.                                         $socket=$socketstr[$cnt3+4] if ($found10bit & $newslots[$val] !~ /00000[0-3]00/);
  3056.                                 }
  3057.                                 $order=$orderstr[$cnt3] if ($#orderstr);
  3058.                                 $group=$groupstr[$cnt3] if ($#groupstr);
  3059.                                 $slotnum=$slotstr[$cnt3] if ($#slotstr);
  3060.                                 if ($#bankstr) {
  3061.                                         $bank=$bankstr[$cnt3];
  3062.                                         $bank=$bankstr[$cnt3+4] if ($found10bit & $newslots[$val] !~ /00000[0-3]00/);
  3063.                                 }
  3064.                                 $banks=$banksstr[$cnt3/$simmsperbank] if ($#banksstr);
  3065.                                 $byte=$bytestr[$cnt3] if ($#bytestr);
  3066.                         }
  3067.                         $cnt++;
  3068.                 }
  3069.                 #
  3070.                 # Check for stacked DIMMs. A 128MB DIMM is sometimes seen as 2
  3071.                 # 64MB DIMMs with a hole in the address range. This may report
  3072.                 # more slots than are really in a system. (i.e. a SS20 with
  3073.                 # 8 32MB SIMMs reports 16 slots of 16MB each).
  3074.                 # Special handling for $sortslots == 0 systems (Ultra 5/10,
  3075.                 # Netra t1, Ultra CP 1400/1500, Ultra AXi/AXe/AXmp/AXmp+)
  3076.                 #
  3077.                 $stacked=0;
  3078.                 if ($val < $#newslots - 2) {
  3079.                         if ($sortslots == 0) {
  3080.                                 $start2=$start1 + ($simmrange * 2);
  3081.                                 if ($banner =~ /Ultra CP 1400\b/ | $ultra eq "cp1400") {
  3082.                                         $start2=$start1 + ($simmrange * 4);
  3083.                                 }
  3084.                                 $start2x=sprintf("%08lx", $start2 / $meg);
  3085.                                 $stacked=2 if ($stacked == 0 & $newslots[$val + 2] eq $start2x & $newslots[$val + 3] eq $simmsz);
  3086.                                 if ($memtype eq "memory card") {
  3087.                                         # Some 256MB mezzanine boards are seen
  3088.                                         # as 4 64MB memory blocks with holes in
  3089.                                         # the address range.
  3090.                                         if ($simmsize eq 64) {
  3091.                                                 $start3=$start1 + ($simmsize * 2 * $meg);
  3092.                                         }
  3093.                                         # Some 512MB mezzanine boards are seen
  3094.                                         # as 4 128MB memory blocks.
  3095.                                         if ($simmsize eq 128 & $banner !~ /Ultra CP 1400\b/ & $ultra ne "cp1400") {
  3096.                                                 $start3=$start1 + ($simmsize * $meg);
  3097.                                         }
  3098.                                         $start3x=sprintf("%08lx", $start3 / $meg);
  3099.                                         if ($val < $#newslots - 6 & $stacked != 0) {
  3100.                                                 $stacked=4 if ($newslots[$val + 4] eq $start3x & $newslots[$val + 5] eq $simmsz & $simmrange != $start3);
  3101.                                         }
  3102.                                 }
  3103.                                 if ($ultra eq "AXi") {
  3104.                                         # Check for 10-bit column address DIMMs
  3105.                                         if ($newslots[$val] =~ /00000[0-3]80/) {
  3106.                                                 $found10bit=1;
  3107.                                         } elsif ($stacked == 0) {
  3108.                                                 $found11bit=1;
  3109.                                         }
  3110.                                         if ($found10bit & $newslots[$val] !~ /00000[0-3]00/) {
  3111.                                                 $socket=$socketstr[$cnt3+4];
  3112.                                                 $bank=$bankstr[$cnt3+4];
  3113.                                         }
  3114.                                 }
  3115.                         } else {
  3116.                                 $start2=$start1 + ($simmrange / 2);
  3117.                                 $start2x=sprintf("%08lx", $start2 / $meg);
  3118.                                 $stacked=2 if ($newslots[$val + 2] eq $start2x & $newslots[$val + 3] eq $simmsz & ($simmsize ne 64));
  3119.                         }
  3120.                         #
  3121.                         # Check for 32MB SIMMs in bank 1 on Classic or LX.
  3122.                         # They look like 16MB SIMMs at 0x0000000 and 0x06000000
  3123.                         # Also check for 8MB SIMMs in bank 1 on Classic or LX.
  3124.                         # They look like 4MB SIMMs at 0x0000000 and 0x06000000
  3125.                         #
  3126.                         if ($model =~ /SPARCclassic/ | $model =~ /SPARCstation-LX/) {
  3127.                                 if ($start1 == 0 & ($simmsize == 32 | $simmsize == 8)) {
  3128.                                         if ($newslots[$#newslots - 1] eq "00000060") {
  3129.                                                 $totmem += $simmsize;
  3130.                                                 $start2=hex("0x$newslots[$#newslots - 1]") * $meg;
  3131.                                                 $start2x=sprintf("%08lx", $start2);
  3132.                                                 $stop2x=sprintf("%08lx", $start2 + ($simmsize * $meg) - 1);
  3133.                                                 $stop1x .= ", 0x${start2x}-0x$stop2x";
  3134.                                                 $simmsize *= 2;
  3135.                                                 pop(@newslots);
  3136.                                                 pop(@newslots);
  3137.                                         }
  3138.                                 }
  3139.                         }
  3140.                         if ($stacked == 2) {
  3141.                                 $totmem += $simmsize;
  3142.                                 $start2=hex("0x$newslots[$val + 2]") * $meg;
  3143.                                 $start2x=sprintf("%08lx", $start2);
  3144.                                 $stop2x=sprintf("%08lx", $start2 + ($simmsize * $meg) - 1);
  3145.                                 $stop1x .= ", 0x${start2x}-0x$stop2x";
  3146.                                 $simmsize *= 2;
  3147.                                 $val += 2;
  3148.                         }
  3149.                         if ($stacked == 4) {
  3150.                                 $totmem += $simmsize * 3;
  3151.                                 $start2=hex("0x$newslots[$val + 2]") * $meg;
  3152.                                 $start2x=sprintf("%08lx", $start2);
  3153.                                 $stop2x=sprintf("%08lx", $start2 + ($simmsize * $meg) - 1);
  3154.                                 $stop1x .= ", 0x${start2x}-0x$stop2x";
  3155.                                 $start3=hex("0x$newslots[$val + 4]") * $meg;
  3156.                                 $start3x=sprintf("%08lx", $start3);
  3157.                                 $stop3x=sprintf("%08lx", $start3 + ($simmsize * $meg) - 1);
  3158.                                 $stop1x .= ", 0x${start3x}-0x$stop3x";
  3159.                                 $start4=hex("0x$newslots[$val + 6]") * $meg;
  3160.                                 $start4x=sprintf("%08lx", $start4);
  3161.                                 $stop4x=sprintf("%08lx", $start4 + ($simmsize * $meg) - 1);
  3162.                                 $stop1x .= ", 0x${start4x}-0x$stop4x";
  3163.                                 $simmsize *= 4;
  3164.                                 $val += 6;
  3165.                         }
  3166.                 }
  3167.                 #
  3168.                 # Check for Voyager memory cards. A 32MB memory card is seen
  3169.                 # as 4 8MB memory blocks with holes in the address range.
  3170.                 #
  3171.                 if ($model eq "S240" & $start1 > 0 & $simmsize == 16 & $val < $#newslots - 4) {
  3172.                         $start=hex("0x$newslots[$val + 4]") - hex("0x$newslots[$val]");
  3173.                         $perlhexbug=1 if ($start < 0);
  3174.                         $startx=sprintf("%08lx", $start);
  3175.                         if ($newslots[$val + 1] eq "008" & $newslots[$val + 3] eq "008" & $startx eq "00000040") {
  3176.                                 $totmem += $simmsize;
  3177.                                 $startx=$newslots[$val + 2];
  3178.                                 $start=hex("0x$startx") * $meg;
  3179.                                 $startx=sprintf("%08lx", $start);
  3180.                                 $perlhexbug=1 if ($start < 0);
  3181.                                 $stopx=sprintf("%08lx", $start + ($simmsize * $meg) - 1);
  3182.                                 $stop1x .= ", 0x${startx}-0x$stopx";
  3183.                                 $startx=$newslots[$val + 4];
  3184.                                 $start=hex("0x$startx") * $meg;
  3185.                                 $startx=sprintf("%08lx", $start);
  3186.                                 $perlhexbug=1 if ($start < 0);
  3187.                                 $stopx=sprintf("%08lx", $start + ($simmsize * $meg) - 1);
  3188.                                 $stop1x .= ", 0x${startx}-0x$stopx";
  3189.                                 $simmsize *= 2;
  3190.                                 $val += 4;
  3191.                         }
  3192.                 }
  3193.                 $slot0=$simmsize if ($start1 == 0);
  3194.                 $simmsizeperbank=$simmsize / $simmsperbank;
  3195.                 $smallestsimm=$simmsizeperbank if ($simmsize < $smallestsimm);
  3196.                 $largestsimm=$simmsizeperbank if ($simmsize > $largestsimm);
  3197.                 $found8mb=1 if ($simmsizeperbank == 8);
  3198.                 $found16mb=1 if ($simmsizeperbank == 16);
  3199.                 $found32mb=1 if ($simmsizeperbank == 32);
  3200.                 push(@simmsizesfound, "$simmsizeperbank");
  3201.  
  3202.                 $cnt2=0;
  3203.                 $maxcnt2=$simmsperbank / $simmspergroup;
  3204.                 while ($cnt2 < $maxcnt2) {
  3205.                         $socket='?' if !defined($socket);
  3206.                         $bank='' if !defined($bank);
  3207.                         $byte='' if !defined($byte);
  3208.                         $socket='?' if ($socket eq "");
  3209.                         $recognized=0 if ($socket eq "?");
  3210.                         $sockets_used .= " $socket";
  3211.                         if ($simmspergroup > 1) {
  3212.                                 $buffer .= "${sockettype}s $socket have $simmsperbank ";
  3213.                                 $buffer .= $simmsize/$simmsperbank . "MB ${memtype}s";
  3214.                         } else {
  3215.                                 if ($socket eq "motherboard") {
  3216.                                         $buffer .= "$socket has ";
  3217.                                         $buffer .= $simmsize/$simmsperbank . "MB";
  3218.                                 } else {
  3219.                                         if ($model eq "SPARCsystem-600" | $model =~ /Sun.4.600/) {
  3220.                                                 if ($newslots[$val] =~ /00000[4-7]00/) {
  3221.                                                         $exp="Expansion board 0";
  3222.                                                 }
  3223.                                                 if ($newslots[$val] =~ /00000[89ab]00/) {
  3224.                                                         $exp="Expansion board 1";
  3225.                                                 }
  3226.                                                 if ($newslots[$val] =~ /00000[4-9ab]00/) {
  3227.                                                         $buffer .= "$exp ";
  3228.                                                         $banks="$exp bank $bank";
  3229.                                                 }
  3230.                                                 $banks_used .= " $banks" if ($banks ne "" & $banks_used !~ /$banks/);
  3231.                                         }
  3232.                                         if ($sockettype) {
  3233.                                                 $buffer .= "${sockettype} $socket has a ";
  3234.                                         } else {
  3235.                                                 $buffer .= "$socket is a ";
  3236.                                         }
  3237.                                         $buffer .= $simmsize/$simmsperbank . "MB";
  3238.                                         $buffer .= " (" . $simmsize/$simmsperbank/1024 . "GB)" if ($simmsize/$simmsperbank > 1023);
  3239.                                         $buffer .= " $memtype";
  3240.                                         push(@simmsizesfound, $simmsize/$simmsperbank);
  3241.                                 }
  3242.                         }
  3243.                         if ($verbose) {
  3244.                                 $buffer .= " (";
  3245.                                 if ($order ne "") {
  3246.                                         $buffer .= "$order";
  3247.                                         if ($memtype !~ /memory card/) {
  3248.                                                 $buffer .= " $memtype";
  3249.                                         }
  3250.                                 }
  3251.                                 if ($slotnum ne "") {
  3252.                                         $buffer .= "slot $slotnum";
  3253.                                 }
  3254.                                 if ($order ne "" | $slotnum ne "") {
  3255.                                         $buffer .= ", ";
  3256.                                 }
  3257.                                 $buffer .= "group $group, " if ($group ne "");
  3258.                                 if ($bank ne "") {
  3259.                                         if ($bank =~ /Quad/) {
  3260.                                                 $buffer .= "$bank, ";
  3261.                                         } elsif ($dualbank eq 1) {
  3262.                                                 $buffer .= "banks $bank, ";
  3263.                                         } else {
  3264.                                                 $buffer .= "bank $bank, ";
  3265.                                         }
  3266.                                         $foundbank1or3=1 if ($bank eq 1 | $bank eq 3);
  3267.                                 }
  3268.                                 $buffer .= "byte $byte, " if ($byte ne "");
  3269.                                 $buffer .= "address 0x${start1x}-0x$stop1x)";
  3270.                         }
  3271.                         $buffer .= "\n";
  3272.                         $cnt2++;
  3273.                         $cnt3=($bankcnt * $simmsperbank / $simmspergroup) + $cnt2;
  3274.                         if ($#socketstr) {
  3275.                                 $socket=$socketstr[$cnt3];
  3276.                                 $socket=$socketstr[$cnt3+4] if ($found10bit & $newslots[$val] !~ /00000[0-3]00/);
  3277.                         }
  3278.                         $order=$orderstr[$cnt3] if ($#orderstr);
  3279.                         $group=$groupstr[$cnt3] if ($#groupstr);
  3280.                         $slotnum=$slotstr[$cnt3] if ($#slotstr);
  3281.                         if ($#bankstr) {
  3282.                                 $bank=$bankstr[$cnt3];
  3283.                                 $bank=$bankstr[$cnt3+4] if ($found10bit & $newslots[$val] !~ /00000[0-3]00/);
  3284.                         }
  3285.                         $banks=$banksstr[$cnt3/$simmsperbank] if ($#banksstr);
  3286.                         $byte=$bytestr[$cnt3] if ($#bytestr);
  3287.                 }
  3288.         } elsif ($ultra eq 1 | $ultra eq 5 | $ultra eq 10 | $ultra eq 30) {
  3289.                 $buffer .= "bank $slot has a pair of " . $simmsize/2 . "MB DIMMs\n";
  3290.                 push(@simmsizesfound, $simmsize/2);
  3291.         } elsif ($ultra eq 2 | $ultra eq 250 | $ultra eq 450 | $ultra eq 80 | $ultra eq "420R" | $ultra eq "Netra ft1800") {
  3292.                 $buffer .= "group $slot has four " . $simmsize/4 . "MB DIMMs\n";
  3293.                 push(@simmsizesfound, $simmsize/4);
  3294.         } elsif ($ultra eq 60 | $ultra eq "220R") {
  3295.                 $buffer .= "group $slot has four " . $simmsize/2 . "MB DIMMs\n";
  3296.                 push(@simmsizesfound, $simmsize/2);
  3297.         } elsif ($ultra eq "e") {
  3298.                 $buffer .= "group $slot has eight " . $simmsize/8 . "MB DIMMs\n";
  3299.                 push(@simmsizesfound, $simmsize/8);
  3300.         } elsif ($socket eq "motherboard") {
  3301.                 $buffer .= "$slot has ${simmsize}MB\n";
  3302.                 push(@simmsizesfound, $simmsize);
  3303.         } else {
  3304.                 $buffer .= "slot $slot has a ${simmsize}MB";
  3305.                 $buffer .= " (" . $simmsize/1024 . "GB)" if ($simmsize > 1023);
  3306.                 $buffer .= " $memtype\n";
  3307.                 push(@simmsizesfound, $simmsize);
  3308.         }
  3309.         $slot++;
  3310. }
  3311.  
  3312. #
  3313. # Try to distinguish Ultra 5 from Ultra 10
  3314. # Cannot distinguish Ultra 5/333MHz from Ultra 10/333MHz (375-0066 motherboard)
  3315. # Cannot distinguish Ultra 5/440MHz from Ultra 10/440MHz (375-0079 motherboard)
  3316. #
  3317. if ($model eq "Ultra-5_10" | $ultra eq "5_10" | $ultra eq 5 | $ultra eq 10) {
  3318.         if ($motherboard =~ /375-0009/) {
  3319.                 $ultra=($sysfreq > 91) ? 10 : 5;
  3320.                 $realmodel=($ultra eq 5) ? "(Ultra 5)" : "(Ultra 10)";
  3321.         }
  3322.         # Determine if interleaving of banks using four identical sized DIMMs
  3323.         # Assume 1-way interleaving with mix of stacked and unstacked DIMMs
  3324.         $interleave=1;
  3325.         if ($#newslots == 3 & $stacked == 0) {
  3326.                 $interleave=2 if ($newslots[1] eq $newslots[3]);
  3327.         }
  3328.         if ($#newslots == 7 & $stacked == 2) {
  3329.                 $interleave=2 if ($newslots[1] eq $newslots[5]);
  3330.         }
  3331. }
  3332. &finish;
  3333.  
  3334. sub finish {
  3335.         &show_header;
  3336.         #print "newslots=@newslots\n" if ($#newslots > 0 & $verbose > 1);
  3337.         print $buffer if ($buffer ne "");
  3338.         #
  3339.         # Special memory options
  3340.         #
  3341.         if ($sxmem) {
  3342.                 # Currently assumes only one VSIMM is installed.
  3343.                 # Auxiliary Video Board 501-2020 (SS10SX) or 501-2488 (SS20)
  3344.                 # required if two VSIMMs are installed.
  3345.                 if ($model eq "SPARCstation-20" | $model eq "SuperCOMPstation-20S") {
  3346.                         # SS20 1st VSIMM in J0304/J0407, 2nd in J0305/J0406
  3347.                         print "sockets J0304/J0407 have";
  3348.                         $sockets_used .= " J0304";
  3349.                 } elsif ($model =~ /COMPstation-20A\b/) {
  3350.                         # 1st VSIMM in J0202, 2nd in J0301
  3351.                         print "socket J0202 has";
  3352.                         $sockets_used .= " J0202";
  3353.                 } else {
  3354.                         # SS10SX 1st VSIMM in J0301/J1203, 2nd in J0202/J1201
  3355.                         print "sockets J0301/J1203 have";
  3356.                         $sockets_used .= " J0301";
  3357.                 }
  3358.                 print " a ${sxmem}MB VSIMM installed for SX (CG14) graphics\n";
  3359.         }
  3360.         if ($nvmem) {
  3361.                 # NVSIMMs for Prestoserve
  3362.                 if ($model eq "SPARCstation-20" | $model eq "SuperCOMPstation-20S") {
  3363.                         # SS20 1st 2MB NVSIMM in J0305/J0406, 2nd in J0304/J0407
  3364.                         if ($nvmem1) {
  3365.                                 $sockets_used .= " J0305";
  3366.                                 print "sockets J0305/J0406 have a 2MB NVSIMM";
  3367.                                 print " installed for Prestoserve\n";
  3368.                         }
  3369.                         if ($nvmem2) {
  3370.                                 $sockets_used .= " J0304";
  3371.                                 print "sockets J0304/J0407 have a 2MB NVSIMM";
  3372.                                 print " installed for Prestoserve\n";
  3373.                         }
  3374.                 } elsif ($model =~ /COMPstation-20A\b/) {
  3375.                         # 1st 2MB NVSIMM in J0301, 2nd in J0202
  3376.                         if ($nvmem1) {
  3377.                                 $sockets_used .= " J0301";
  3378.                                 print "socket J0301 has a 2MB NVSIMM";
  3379.                                 print " installed for Prestoserve\n";
  3380.                         }
  3381.                         if ($nvmem2) {
  3382.                                 $sockets_used .= " J0202";
  3383.                                 print "socket J0202 has a 2MB NVSIMM";
  3384.                                 print " installed for Prestoserve\n";
  3385.                         }
  3386.                 } elsif ($model =~ /SPARCstation-10/ | $model eq "Premier-24") {
  3387.                         # SS10 1st 2MB NVSIMM in J0202/J1201, 2nd in J0301/J1203
  3388.                         if ($nvmem1) {
  3389.                                 $sockets_used .= " J0202";
  3390.                                 print "sockets J0202/J1201 have a 2MB NVSIMM";
  3391.                                 print " installed for Prestoserve\n";
  3392.                         }
  3393.                         if ($nvmem2) {
  3394.                                 $sockets_used .= " J0301";
  3395.                                 print "sockets J0301/J1203 have a 2MB NVSIMM";
  3396.                                 print " installed for Prestoserve\n";
  3397.                         }
  3398.                 } else {
  3399.                         # SS1000 supports two banks of four 1MB NVSIMMs
  3400.                         # SC2000 supports one bank of eight 1MB NVSIMMs
  3401.                         print "Has ${nvmem}MB of NVSIMM installed for Prestoserve ";
  3402.                         if ($model eq "SPARCserver-1000") {
  3403.                                 print "(1 bank of 4" if ($nvmem == 4);
  3404.                                 print "(2 banks of 4" if ($nvmem == 8);
  3405.                         } else {
  3406.                                 print "(1 bank of 8";
  3407.                         }
  3408.                         print " 1MB NVSIMMs$nvsimm_banks)\n";
  3409.                 }
  3410.         }
  3411.  
  3412.         #
  3413.         # Check for empty banks or sockets
  3414.         #
  3415.         if ($#banksstr > 0) {
  3416.                 print "empty banks:";
  3417.                 foreach $banks (@banksstr) {
  3418.                         if ($banks ne "?") {
  3419.                                 if ($banks_used !~ /\b$banks\b/ &
  3420.                                     $sockets_empty !~ /\b$banks\b/) {
  3421.                                         if ($sockets_empty ne "") {
  3422.                                                 $sockets_empty .= ", $banks";
  3423.                                         } else {
  3424.                                                 $sockets_empty .= " $banks";
  3425.                                         }
  3426.                                 }
  3427.                         }
  3428.                 }
  3429.                 if ($sockets_empty ne "") {
  3430.                         print "$sockets_empty\n";
  3431.                 } else {
  3432.                         print " None\n";
  3433.                 }
  3434.         } elsif ($#socketstr > 0) {
  3435.                 if ($sockettype) {
  3436.                         print "empty ${sockettype}s:";
  3437.                 } else {
  3438.                         print "empty memory slots:";
  3439.                 }
  3440.                 foreach $socket (@socketstr) {
  3441.                         if ($socket ne "?") {
  3442.                                 if ($sockets_used !~ /\b$socket\b/ &
  3443.                                     $sockets_empty !~ /\b$socket\b/) {
  3444.                                         if ($memtype =~ /memory card/ &
  3445.                                             $sockets_empty ne "") {
  3446.                                                 $sockets_empty .= ", $socket";
  3447.                                         } else {
  3448.                                                 $sockets_empty .= " $socket";
  3449.                                         }
  3450.                                 }
  3451.                         }
  3452.                 }
  3453.                 if ($sockets_empty ne "") {
  3454.                         print "$sockets_empty\n";
  3455.                 } else {
  3456.                         print " None\n";
  3457.                 }
  3458.         } elsif ($verbose > 1 & $sockets_used ne "") {
  3459.                 print "memory sockets used: ${sockets_used}\n";
  3460.         }
  3461.         # Look for duplicate sockets
  3462.         if ($sockets_used ne "" & $prtdiag_exec ne "") {
  3463.                 $dup_sockets="";
  3464.                 foreach $socket (sort split(' ', $sockets_used)) {
  3465.                         next if ($socket eq "board" | $socket eq "mezzanine");
  3466.                         next if ($model eq "SPARCsystem-600" | $model =~ /Sun.4.600/);
  3467.                         $pos=-1;
  3468.                         $cnt=0;
  3469.                         while (($pos=index(" $sockets_used ", " $socket ", $pos)) > -1) {
  3470.                                 $pos++;
  3471.                                 $cnt++;
  3472.                                 if ($cnt == 2 & $dup_sockets !~ /\b$socket\b/) {
  3473.                                         $dup_sockets .= " $socket";
  3474.                                         print "ERROR: Duplicate socket $socket found\n";
  3475.                                         $exitstatus=1;
  3476.                                 }
  3477.                         }
  3478.                 }
  3479.                 if ($dup_sockets ne "") {
  3480.                         print "WARNING: Memory was not properly reported by";
  3481.                         print " the 'prtdiag' command.\n";
  3482.                         &recommend_prtdiag_patch;
  3483.                 }
  3484.         }
  3485.         # Look for unlabeled sockets
  3486.         if ( $sockets_used =~ /\s-\s|^-\s|\s-$|^-$/) {
  3487.                 print "WARNING: Unlabeled socket found";
  3488.                 if ($prtdiag_exec ne "") {
  3489.                         print " in the 'prtdiag' command output";
  3490.                 }
  3491.                 print ".\n         This may cause the reported empty sockets";
  3492.                 print " to be incorrect.\n";
  3493.                 &recommend_prtdiag_patch;
  3494.         }
  3495.  
  3496.         #
  3497.         # Print total memory
  3498.         #
  3499.         print "total memory = ${totmem}MB";
  3500.         print " (", $totmem / 1024, "GB)" if ($totmem > 1023);
  3501.         print "\n";
  3502.  
  3503.         #
  3504.         # Check for illegal memory stuffings
  3505.         #
  3506.         if ($model eq "Sun 4/50" | $model eq "Sun 4/25") {      # IPX, ELC
  3507.                 if ($slot0 != 16 & $largestsimm == 16 & $sunos =~ /4.1.1/) {
  3508.                         print "ERROR: Install the highest capacity 16MB SIMM";
  3509.                         print " in socket $socketstr[0] under SunOS 4.1.1.\n";
  3510.                         $exitstatus=1;
  3511.                 }
  3512.         }
  3513.         if ($model =~ /SPARCclassic/ | $model =~ /SPARCstation-LX/) {
  3514.                 if ($found32mb) {
  3515.                         # Reportedly can accept 32MB SIMMs in bank 1, allowing
  3516.                         # 128MB total (2x32, 4x16)
  3517.                         print "WARNING: The 32MB SIMM is not supported in the";
  3518.                         print " $model according to\n    Sun. However it does";
  3519.                         print " appear to work in bank 1 only, allowing a";
  3520.                         print " maximum of\n    128MB of total memory (2x32MB";
  3521.                         print " bank 1 + 4x16MB banks 2 & 3).\n";
  3522.                 }
  3523.                 if ($found8mb) {
  3524.                         # Possibly can accept 8MB SIMMs in bank 1
  3525.                         print "WARNING: The 8MB SIMM is not supported in the";
  3526.                         print " $model according to\n    Sun. However it does";
  3527.                         print " appear to work in bank 1 only.\n";
  3528.                 }
  3529.         }
  3530.         if ($model =~ /SPARCstation-10/ | $model eq "Premier-24") {
  3531.                 if ($slot0 < $largestsimm & $BSD) {
  3532.                         print "ERROR: Install the highest capacity SIMM in";
  3533.                         print " socket $socketstr[0] under Solaris 1.X.\n";
  3534.                         $exitstatus=1;
  3535.                 }
  3536.                 if (! $found32mb & $found16mb & $romvermajor eq 2 & $romverminor < 19) {
  3537.                         print "WARNING: The 32MB SIMM is not supported in the";
  3538.                         print " SS10 or SS10SX according to\n    Sun. However";
  3539.                         print " it does work correctly depending on the Open";
  3540.                         print " Boot PROM\n    version. This system is running";
  3541.                         print " OBP $romvernum, so 32MB SIMMs will only be\n";
  3542.                         print "    recognized as 16MB SIMMs. You should";
  3543.                         print " upgrade to OBP 2.19 or later in order\n    to";
  3544.                         print " be able to detect and utilize 32MB SIMMs.\n";
  3545.                         # OBP 2.14 and earlier see the 32MB SIMM as 16MB.
  3546.                         # OBP 2.15 on a SS20 does see the 32MB SIMM as 32MB.
  3547.                         # Have not tested 32MB SIMMs on SS10 with OBP 2.15-2.18
  3548.                         if ($romverminor > 14) {
  3549.                                 $untested=1;
  3550.                                 $untested_type="OBP";
  3551.                         }
  3552.                 }
  3553.                 if ($found32mb & $romvermajor eq 2 & $romverminor < 19) {
  3554.                         print "WARNING: The 32MB SIMM is not supported in the";
  3555.                         print " SS10 or SS10SX according to\n    Sun. However";
  3556.                         print " it does work correctly depending on the Open";
  3557.                         print " Boot PROM\n    version. This system is running";
  3558.                         print " OBP $romvernum, and 32MB SIMMs were properly\n";
  3559.                         print "    recognized.\n";
  3560.                         @simmsizes=(16,32,64);
  3561.                         if ($romvernum ne "2.X") {
  3562.                                 $untested=1;
  3563.                                 $untested_type="OBP";
  3564.                         }
  3565.                 }
  3566.                 if (! $nvmem1 & $nvmem2) {
  3567.                         print "ERROR: First NVSIMM should be installed in";
  3568.                         print " socket J0202, not socket J0301\n";
  3569.                         $exitstatus=1;
  3570.                 }
  3571.         }
  3572.         if ($model eq "SPARCstation-20" | $model eq "SuperCOMPstation-20S") {
  3573.                 if (! $nvmem1 & $nvmem2) {
  3574. &nbs