blob: 8a400b9f6b7880105b4609132252a1080241b48e [file] [log] [blame]
#!/usr/bin/perl
#
# Copyright 1998, 1999 Philip Edelbrock <phil@netroedge.com>
# and Mark Studebaker <mdsxyz123@yahoo.com>
#
# Version 0.1
#
#
# ID ROM data decoding for Xeon processors.
# Each Xeon processor contains two memories:
# - A scratch EEPROM at an even location 0x50, 52, 54, or 56;
# - An ID ROM at an odd location 0x51, 53, 55, or 57.
# This program decodes the ID ROM's only.
# The scratch EEPROMs have no prescribed format.
# If the output of this program makes no sense for a particular device,
# it is probably decoding a DIMM Serial Presence Detect (SPD) EEPROM.
# See decode-dimms to decode those devices.
#
#
# The eeprom driver must be loaded. For kernels older than 2.6.0, the
# eeprom driver can be found in the lm-sensors package.
#
# To do:
# Calculate and check checksums for each section
# Decode flags in byte 0x7B (cartridge feature flags)
#
# References:
# "Pentium II Xeon Processor at 400 and 450 MHz" Data Sheet
# Intel
#
#
#
print "Xeon Processor Information ROM Decoder\n";
print "Written by Philip Edelbrock and Mark Studebaker. Copyright 1998, 1999.\n";
print "Version 2.6.3\n\n";
$dimm_count=0;
$_=`ls /proc/sys/dev/sensors/`;
@dimm_list=split();
for $i ( 0 .. $#dimm_list ) {
$_=$dimm_list[$i];
if ((/^eeprom-/) && (/-51$/ || /-53$/ || /-55$/ || /-57$/)) {
$dimm_count=$dimm_count + 1;
print "\nDecoding Xeon ROM: /proc/sys/dev/sensors/$dimm_list[$i]\n";
if (/^[^-]+-[^-]+-[^-]+-([^-]+)$/) {
$dimm_num=($1 - 49) / 2;
print "Guessing Xeon is number $dimm_num\n";
}
# Decode first 16 bytes
print "\t\t----=== Xeon ROM Header Data ===----\n";
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/00`;
@bytes=split(" ");
printf("\tData Format Revision: \t\t\t\t0x%.4X\n", $bytes[0]);
print "\tTotal number of bytes in EEPROM:\t\t";
print ($bytes[1] << 4) + $bytes[2];
print "\n";
printf("\tProcessor Data Address:\t\t\t\t0x%.2X\n", $bytes[3]);
printf("\tProcessor Core Data Address:\t\t\t0x%.2X\n", $bytes[4]);
printf("\tL2 Cache Data Address:\t\t\t\t0x%.2X\n", $bytes[5]);
printf("\tSEC Cartridge Data Address:\t\t\t0x%.2X\n", $bytes[6]);
printf("\tPart Number Data Address:\t\t\t0x%.2X\n", $bytes[7]);
printf("\tThermal Reference Data Address:\t\t\t0x%.2X\n", $bytes[8]);
printf("\tFeature Data Address:\t\t\t\t0x%.2X\n", $bytes[9]);
printf("\tOther Data Address:\t\t\t\t0x%.2X\n", $bytes[10]);
print "\t\t----=== Xeon ROM Processor Data ===----\n";
# Decode next 16 bytes
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/10`;
@bbytes=split(" ");
print "\tS-spec/QDF Number:\t\t\t\t\"";
print pack("cccccc",$bytes[14],$bytes[15],$bbytes[0],
$bbytes[1],$bbytes[2],$bbytes[3]);
print "\"\n";
$tmp = $bbytes[4] & 0xC0 >> 6;
printf("\tSample / Production:\t\t\t\t0x%.2X", $tmp);
if($tmp) {
print " (Production)\n";
} else {
print " (Sample)\n";
}
print "\t\t----=== Xeon ROM Core Data ===----\n";
printf("\tProcessor Core Type:\t\t\t\t0x%.2X\n",
($bbytes[6] & 0xC0) >> 6);
printf("\tProcessor Core Family:\t\t\t\t0x%.2X\n",
($bbytes[6] & 0x3C) >> 2);
printf("\tProcessor Core Model:\t\t\t\t0x%.2X\n",
(($bbytes[6] & 0x03) << 2) + (($bbytes[7] & 0xC0) >> 6));
printf("\tProcessor Core Stepping:\t\t\t0x%.2X\n",
($bbytes[7] & 0x30) >> 4);
print "\tMaximum Core Frequency (Mhz):\t\t\t";
print ($bbytes[13] << 4) + $bbytes[14];
print "\n";
# Decode next 16 bytes (32-47)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/20`;
@bytes=split(" ");
print "\tCore Voltage ID (mV):\t\t\t\t";
print ($bbytes[15] << 4) + $bytes[0];
print "\n";
print "\tCore Voltage Tolerance, High (mV):\t\t";
print $bytes[1];
print "\n";
print "\tCore Voltage Tolerance, Low (mV):\t\t";
print $bytes[2];
print "\n";
print "\t\t----=== Xeon ROM L2 Cache Data ===----\n";
print "\tL2 Cache Size (KB):\t\t\t\t";
print ($bytes[9] << 4) + $bytes[10];
print "\n";
printf("\tNumber of SRAM Components:\t\t\t%d\n",
($bytes[11] & 0xF0) >> 4);
print "\tL2 Cache Voltage ID (mV):\t\t\t";
print ($bytes[12] << 4) + $bytes[13];
print "\n";
print "\tL2 Cache Voltage Tolerance, High (mV):\t\t";
print $bytes[14];
print "\n";
print "\tL2 Cache Voltage Tolerance, Low (mV):\t\t";
print $bytes[15];
print "\n";
# Decode next 16 bytes (48-63)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/30`;
@bytes=split(" ");
printf("\tCache/Tag Stepping ID:\t\t\t\t0x%.2X\n",
($bytes[0] & 0xF0) >> 4);
print "\t\t----=== Xeon ROM Cartridge Data ===----\n";
print "\tCartridge Revision:\t\t\t\t\"";
print pack("cccc",$bytes[2],$bytes[3],$bytes[4],$bytes[5]);
print "\"\n";
printf("\tSubstrate Rev. Software ID:\t\t\t0x%.2X\n",
($bbytes[6] & 0xC0) >> 6);
print "\t\t----=== Xeon ROM Part Number Data ===----\n";
print "\tProcessor Part Number:\t\t\t\t\"";
print pack("ccccccc",$bytes[8],$bytes[9],$bytes[10],
$bytes[11],$bytes[12],$bytes[13],$bytes[14]);
print "\"\n";
$byte15=$byte[15];
# Decode next 16 bytes (64-79)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/40`;
@bytes=split(" ");
print "\tProcessor BOM ID:\t\t\t\t\"";
print pack("cccccccccccccc",$byte15,$bytes[0],$bytes[1],
$bytes[2],$bytes[3],$bytes[4],$bytes[5],$bytes[6],
$bytes[7],$bytes[8],$bytes[9],$bytes[10],$bytes[11],
$bytes[12]);
print "\"\n";
# Decode next 16 bytes (80-95)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/50`;
@bbytes=split(" ");
printf("\tProcessor Electronic Signature: \t\t0x%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X\n",
$bytes[13],$bytes[14],$bytes[15],$bbytes[0],
$bbytes[1],$bbytes[2],$bbytes[3],$bbytes[4]);
# Decode next 16 bytes (96-111)
# Not used...
# Decode next 16 bytes (112-127)
$_=`cat /proc/sys/dev/sensors/$dimm_list[$i]/70`;
@bytes=split(" ");
print "\t\t----=== Xeon Thermal Reference Data ===----\n";
printf("\tThermal Reference Byte: \t\t\t0x%.2X\n", $bytes[0]);
print "\t\t----=== Xeon ROM Feature Data ===----\n";
printf("\tProcessor Core Feature Flags: \t\t\t0x%.2X%.2X%.2X%.2X\n",
$bytes[4],$bytes[5],$bytes[6],$bytes[7]);
printf("\tCartridge Feature Flags: \t\t\t0x%.2X%.2X%.2X%.2X\n",
$bytes[8],$bytes[9],$bytes[10],$bytes[11]);
printf("\tNumber of Devices in TAP Chain:\t\t\t%d\n",
($bytes[12] & 0xF0) >> 4);
}
}
print "\n\nNumber of Xeon ROMs detected and decoded: $dimm_count\n";