mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-10-28 12:40:42 +00:00
Upgrade dmidecode to version 1.8
git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@1583 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
1 parent
1c48b4e402
commit
f0d334292d
2 files changed
+565
-72
No files matched your search
@@ -40,7 +40,7 @@ ask CVS about it:
|
||||
Module lm87: Add multiple VRM version support
|
||||
Module w83781d: Fix in0/in1 initialization
|
||||
Module smartbatt: New
|
||||
Program dmidecode: Fix read bug
|
||||
Program dmidecode: Fix read bug; upgrade to version 1.8
|
||||
Program doc-insmod: Complete rewrite; fix author output
|
||||
Program doc-features: Complete rewrite; handle missing sysctl entries;
|
||||
handle unknown prefix with suggestion
|
||||
|
||||
+564
-71
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* DMI decode rev 1.4
|
||||
* DMI decode rev 1.8
|
||||
*
|
||||
* (C) 2000,2001 Alan Cox <alan@redhat.com>
|
||||
* (C) 2000-2002 Alan Cox <alan@redhat.com>
|
||||
*
|
||||
* 2-July-2001 Matt Domsch <Matt_Domsch@dell.com>
|
||||
* Additional structures displayed per SMBIOS 2.3.1 spec
|
||||
@@ -33,10 +33,89 @@
|
||||
* C++ style comments removed
|
||||
* Commented out code removed
|
||||
* DMI 0.0 case handled
|
||||
* Fix return value in dmi_port_type and dmi_port_connector_type
|
||||
* Fix return value of dmi_port_type and dmi_port_connector_type
|
||||
*
|
||||
* Licensed under the GNU Public license. If you want to use it in with
|
||||
* another license just ask.
|
||||
* 23-August-2002 Alan Cox <alan@redhat.com>
|
||||
* Make the code pass -Wall -pedantic by fixing a few harmless sign of
|
||||
* pointer mismatches
|
||||
* Correct main prototype
|
||||
* Check for compilers with wrong type sizes
|
||||
*
|
||||
* 17-Sep-2002 Larry Lile <llile@dreamworks.com>
|
||||
* Type 16 & 17 structures displayed per SMBIOS 2.3.1 spec
|
||||
*
|
||||
* 20-September-2002 Dave Johnson <ddj@cascv.brown.edu>
|
||||
* Fix comparisons in dmi_bus_name
|
||||
* Fix comparison in dmi_processor_type
|
||||
* Fix bitmasking in dmi_onboard_type
|
||||
* Fix return value of dmi_temp_loc
|
||||
*
|
||||
* 28-September-2002 Jean Delvare <khali@linux-fr.org>
|
||||
* Fix missing coma in dmi_bus_name
|
||||
* Remove unwanted bitmaskings in dmi_mgmt_dev_type, dmi_mgmt_addr_type,
|
||||
* dmi_fan_type, dmi_volt_loc, dmi_temp_loc and dmi_status
|
||||
* Fix DMI table read bug ("dmi: read: Success")
|
||||
* Make the code pass -W again
|
||||
* Fix return value of dmi_card_size
|
||||
*
|
||||
* 05-October-2002 Jean Delvare <khali@linux-fr.org>
|
||||
* More ACPI decoded
|
||||
* More PNP decoded
|
||||
* More SYSID decoded
|
||||
* PCI Interrupt Routing decoded
|
||||
* BIOS32 Service Directory decoded
|
||||
* Sony system detection (unconfirmed)
|
||||
* Checksums verified whenever possible
|
||||
* Better checks on file read and close
|
||||
* Define VERSION and display version at beginning
|
||||
* More secure decoding (won't run off the table in any case)
|
||||
* Do not try to decode more structures than announced
|
||||
* Fix an off-by-one error that caused the last address being
|
||||
* scanned to be 0x100000, not 0xFFFF0 as it should
|
||||
*
|
||||
* 10-October-2002 Jean Delvare <khali@linux-fr.org>
|
||||
* Remove extra semicolon at the end of dmi_memory_array_use
|
||||
* Fix compilation warnings
|
||||
* Add missing backslash in DMI case 37
|
||||
* Fix BIOS ROM size (DMI case 0)
|
||||
*
|
||||
* 12-October-2002 Jean Delvare <khali@linux-fr.org>
|
||||
* Fix maximum cache size and installed size being inverted
|
||||
* Fix typos in port types
|
||||
*
|
||||
* 14-October-2002 Jean Delvare <khali@linux-fr.org>
|
||||
* Fix typo in dmi_memory_array_location
|
||||
* Replace Kbyte by kB in DMI case 16
|
||||
* Add DDR entry in dmi_memory_device_type
|
||||
* Fix extra s in SYSIS
|
||||
*
|
||||
* 15-October-2002 Jean Delvare <khali@linux-fr.org>
|
||||
* Fix bad index in DMI case 27 (cooling device)
|
||||
*
|
||||
* Licensed under the GNU Public license. If you want to use it in with
|
||||
* another license just ask.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* For the avoidance of doubt the "preferred form" of this code is one which
|
||||
* is in an open unpatent encumbered format. Where cryptographic key signing
|
||||
* forms part of the process of creating an executable the information
|
||||
* including keys needed to generate an equivalently functional executable
|
||||
* are deemed to be part of the source code.
|
||||
* [In the light of TCPA and Palladium the author urges
|
||||
* other open source authors to add such a clarification]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -45,6 +124,8 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define VERSION "1.8"
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
@@ -52,7 +133,7 @@ typedef unsigned int u32;
|
||||
static void
|
||||
dump_raw_data(void *data, unsigned int length)
|
||||
{
|
||||
unsigned char buffer1[80], buffer2[80], *b1, *b2, c;
|
||||
char buffer1[80], buffer2[80], *b1, *b2, c;
|
||||
unsigned char *p = data;
|
||||
unsigned long column=0;
|
||||
unsigned int length_printed = 0;
|
||||
@@ -91,18 +172,21 @@ struct dmi_header
|
||||
u16 handle;
|
||||
};
|
||||
|
||||
static char *dmi_string(struct dmi_header *dm, u8 s)
|
||||
static const char *dmi_string(struct dmi_header *dm, u8 s)
|
||||
{
|
||||
u8 *bp=(u8 *)dm;
|
||||
if (!s) return NULL;
|
||||
char *bp=(char *)dm;
|
||||
if(s==0)
|
||||
return "";
|
||||
|
||||
bp+=dm->length;
|
||||
while(s>1)
|
||||
while(s>1 && *bp)
|
||||
{
|
||||
bp+=strlen(bp);
|
||||
bp++;
|
||||
s--;
|
||||
}
|
||||
if(!*bp)
|
||||
return "<bad index>";
|
||||
return bp;
|
||||
}
|
||||
|
||||
@@ -168,7 +252,7 @@ const char *dmi_bus_name(u8 num)
|
||||
"MCA ",
|
||||
"EISA ",
|
||||
"PCI ",
|
||||
"PCMCIA "
|
||||
"PCMCIA ",
|
||||
"VLB ",
|
||||
"Proprietary ",
|
||||
"CPU Slot ",
|
||||
@@ -188,9 +272,9 @@ const char *dmi_bus_name(u8 num)
|
||||
"PC98/Card"
|
||||
};
|
||||
|
||||
if(num<=0x12)
|
||||
if(num<=0x11)
|
||||
return bus[num];
|
||||
if(num>=0xA0 && num<0xA5)
|
||||
if(num>=0xA0 && num<=0xA4)
|
||||
return jpbus[num - 0xA0];
|
||||
return "";
|
||||
}
|
||||
@@ -214,9 +298,9 @@ const char *dmi_bus_width(u8 code)
|
||||
|
||||
const char *dmi_card_size(u8 v)
|
||||
{
|
||||
if(v==2)
|
||||
return("Short ");
|
||||
if(v==3)
|
||||
return("Short ");
|
||||
if(v==4)
|
||||
return("Long ");
|
||||
return "";
|
||||
}
|
||||
@@ -334,6 +418,149 @@ const char *dmi_port_connector_type(u8 code)
|
||||
return "";
|
||||
}
|
||||
|
||||
static const char *dmi_memory_array_location(u8 num)
|
||||
{
|
||||
static const char *memory_array_location[]={
|
||||
"",
|
||||
"Other",
|
||||
"Unknown",
|
||||
"System board or motherboard",
|
||||
"ISA add-on card",
|
||||
"EISA add-on card",
|
||||
"PCI add-on card",
|
||||
"MCA add-on card",
|
||||
"PCMCIA add-on card",
|
||||
"Proprietary add-on card",
|
||||
"NuBus",
|
||||
};
|
||||
static const char *jp_memory_array_location[]={
|
||||
"PC-98/C20 add-on card",
|
||||
"PC-98/C24 add-on card",
|
||||
"PC-98/E add-on card",
|
||||
"PC-98/Local bus add-on card",
|
||||
};
|
||||
if(num<=0x0A)
|
||||
return memory_array_location[num];
|
||||
if(num>=0xA0 && num<0xA3)
|
||||
return jp_memory_array_location[num];
|
||||
return "";
|
||||
}
|
||||
|
||||
static const char *dmi_memory_array_use(u8 num)
|
||||
{
|
||||
static const char *memory_array_use[]={
|
||||
"",
|
||||
"Other",
|
||||
"Unknown",
|
||||
"System memory",
|
||||
"Video memory",
|
||||
"Flash memory",
|
||||
"Non-volatile RAM",
|
||||
"Cache memory",
|
||||
};
|
||||
if (num > 0x07)
|
||||
return "";
|
||||
return memory_array_use[num];
|
||||
}
|
||||
|
||||
static const char *dmi_memory_array_error_correction_type(u8 num)
|
||||
{
|
||||
static const char *memory_array_error_correction_type[]={
|
||||
"",
|
||||
"Other",
|
||||
"Unknown",
|
||||
"None",
|
||||
"Parity",
|
||||
"Single-bit ECC",
|
||||
"Multi-bit ECC",
|
||||
"CRC",
|
||||
};
|
||||
if (num > 0x07)
|
||||
return "";
|
||||
return memory_array_error_correction_type[num];
|
||||
}
|
||||
|
||||
static const char *dmi_memory_device_form_factor(u8 num)
|
||||
{
|
||||
static const char *memory_device_form_factor[]={
|
||||
"",
|
||||
"Other",
|
||||
"Unknown",
|
||||
"SIMM",
|
||||
"SIP",
|
||||
"Chip",
|
||||
"DIP",
|
||||
"ZIP",
|
||||
"Proprietary Card",
|
||||
"DIMM",
|
||||
"TSOP",
|
||||
"Row of chips",
|
||||
"RIMM",
|
||||
"SODIMM",
|
||||
"SRIMM",
|
||||
};
|
||||
if (num > 0x0E)
|
||||
return "";
|
||||
return memory_device_form_factor[num];
|
||||
}
|
||||
|
||||
static const char *dmi_memory_device_type(u8 num)
|
||||
{
|
||||
static const char *memory_device_type[]={
|
||||
"",
|
||||
"Other",
|
||||
"Unknown",
|
||||
"DRAM",
|
||||
"EDRAM",
|
||||
"VRAM",
|
||||
"SRAM",
|
||||
"RAM",
|
||||
"ROM",
|
||||
"FLASH",
|
||||
"EEPROM",
|
||||
"FEPROM",
|
||||
"EPROM",
|
||||
"CDRAM",
|
||||
"3DRAM",
|
||||
"SDRAM",
|
||||
"SGRAM",
|
||||
"RDRAM",
|
||||
"DDR"
|
||||
};
|
||||
if (num > 0x12)
|
||||
return "";
|
||||
return memory_device_type[num];
|
||||
}
|
||||
|
||||
static void dmi_memory_device_detail(u8 v)
|
||||
{
|
||||
printf("\t\tType Detail: ");
|
||||
if (v&(1<<1))
|
||||
printf("Other ");
|
||||
if (v&(1<<2))
|
||||
printf("Unknown ");
|
||||
if (v&(1<<3))
|
||||
printf("Fast-paged ");
|
||||
if (v&(1<<4))
|
||||
printf("Static column ");
|
||||
if (v&(1<<5))
|
||||
printf("Pseudo-static ");
|
||||
if (v&(1<<6))
|
||||
printf("RAMBUS ");
|
||||
if (v&(1<<7))
|
||||
printf("Synchronous ");
|
||||
if (v&(1<<8))
|
||||
printf("CMOS ");
|
||||
if (v&(1<<9))
|
||||
printf("EDO ");
|
||||
if (v&(1<<10))
|
||||
printf("Window DRAM ");
|
||||
if (v&(1<<11))
|
||||
printf("Cache DRAM ");
|
||||
if (v&(1<<12))
|
||||
printf("Non-volatile ");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
const char *dmi_port_type(u8 code)
|
||||
{
|
||||
@@ -346,8 +573,8 @@ const char *dmi_port_type(u8 code)
|
||||
"Parallel Port ECP/EPP",
|
||||
"Serial Port XT/AT Compatible",
|
||||
"Serial Port 16450 Compatible",
|
||||
"Serial Port 16650 Compatible",
|
||||
"Serial Port 16650A Compatible",
|
||||
"Serial Port 16550 Compatible",
|
||||
"Serial Port 16550A Compatible",
|
||||
"SCSI Port",
|
||||
"MIDI Port",
|
||||
"Joy Stick Port",
|
||||
@@ -401,7 +628,7 @@ const char *dmi_processor_type(u8 code)
|
||||
if(code == 0xFF)
|
||||
return "Other";
|
||||
|
||||
if (code > 0xA1)
|
||||
if (code > 6)
|
||||
return "";
|
||||
return processor_type[code];
|
||||
}
|
||||
@@ -458,7 +685,7 @@ const char *dmi_onboard_type(u8 code)
|
||||
"Token Ring",
|
||||
"Sound",
|
||||
};
|
||||
code &= 0x80;
|
||||
code &= ~0x80;
|
||||
if (code > 7)
|
||||
return "";
|
||||
return onboard_type[code];
|
||||
@@ -482,7 +709,7 @@ const char *dmi_mgmt_dev_type(u8 code)
|
||||
"W83781D",
|
||||
"HT82H791",
|
||||
};
|
||||
code &= 0x80;
|
||||
|
||||
if (code > 0x0d)
|
||||
return "";
|
||||
return type[code];
|
||||
@@ -498,7 +725,7 @@ const char *dmi_mgmt_addr_type(u8 code)
|
||||
"Memory",
|
||||
"SMBus",
|
||||
};
|
||||
code &= 0x80;
|
||||
|
||||
if (code > 5)
|
||||
return "";
|
||||
return type[code];
|
||||
@@ -526,7 +753,7 @@ const char *dmi_fan_type(u8 code)
|
||||
"Active Cooling",
|
||||
"Passive Cooling",
|
||||
};
|
||||
code &= 0x80;
|
||||
|
||||
if (code > 0x11)
|
||||
return "";
|
||||
return type[code];
|
||||
@@ -548,7 +775,7 @@ const char *dmi_volt_loc(u8 code)
|
||||
"Power Unit",
|
||||
"Add-in Card",
|
||||
};
|
||||
code &= 0x80;
|
||||
|
||||
if (code > 0x0b)
|
||||
return "";
|
||||
return type[code];
|
||||
@@ -562,10 +789,12 @@ const char *dmi_temp_loc(u8 code)
|
||||
"Power System Board",
|
||||
"Drive Back Plane",
|
||||
};
|
||||
code &= 0x80;
|
||||
|
||||
if (code <= 0x0b)
|
||||
return dmi_volt_loc(code);
|
||||
return type[code - 0x0c];
|
||||
if (code <= 0x0f)
|
||||
return type[code - 0x0c];
|
||||
return "";
|
||||
}
|
||||
|
||||
const char *dmi_status(u8 code)
|
||||
@@ -579,7 +808,7 @@ const char *dmi_status(u8 code)
|
||||
"Critical",
|
||||
"Non-recoverable",
|
||||
};
|
||||
code &= 0x80;
|
||||
|
||||
if (code > 6)
|
||||
return "";
|
||||
return type[code];
|
||||
@@ -640,9 +869,9 @@ const char *dmi_speed(u8 *data, int indx)
|
||||
|
||||
static void dmi_table(int fd, u32 base, int len, int num)
|
||||
{
|
||||
char *buf=malloc(len);
|
||||
unsigned char *buf=malloc(len);
|
||||
struct dmi_header *dm;
|
||||
u8 *data;
|
||||
u8 *data, *next;
|
||||
int i=0;
|
||||
int r=0, r2=0;
|
||||
|
||||
@@ -662,15 +891,20 @@ static void dmi_table(int fd, u32 base, int len, int num)
|
||||
perror("dmi: lseek");
|
||||
return;
|
||||
}
|
||||
while(r2!=len && (r=read(fd, buf+r2, len-r2))!=0)
|
||||
while(r2!=len && (r=read(fd, buf+r2, len-r2))!=0 && r!=-1)
|
||||
r2+=r;
|
||||
if(r==0)
|
||||
if(r==-1)
|
||||
{
|
||||
perror("dmi: read");
|
||||
return;
|
||||
}
|
||||
if(r==0)
|
||||
{
|
||||
fputs("dmi: read: Unexpected end of file\n", stderr);
|
||||
return;
|
||||
}
|
||||
data = buf;
|
||||
while(data+sizeof(struct dmi_header)<=(u8*)buf+len)
|
||||
while(i<num && data+sizeof(struct dmi_header)<=(u8*)buf+len)
|
||||
{
|
||||
u32 u, u2;
|
||||
dm=(struct dmi_header *)data;
|
||||
@@ -679,7 +913,11 @@ static void dmi_table(int fd, u32 base, int len, int num)
|
||||
dm->type, dm->length);
|
||||
|
||||
/* we won't read beyond allocated memory */
|
||||
if(data+dm->length>(u8*)buf+len)
|
||||
next=data+dm->length;
|
||||
while(next-buf+1<len && (next[0]!=0 || next[1]!=0))
|
||||
next++;
|
||||
next+=2;
|
||||
if(next-buf>len)
|
||||
{
|
||||
printf("\tIncomplete structure, abort decoding.\n");
|
||||
break;
|
||||
@@ -698,7 +936,7 @@ static void dmi_table(int fd, u32 base, int len, int num)
|
||||
printf("\t\tBIOS base: 0x%04X0\n",
|
||||
data[7]<<8|data[6]);
|
||||
printf("\t\tROM size: %dK\n",
|
||||
64*data[9]);
|
||||
64*(data[9]+1));
|
||||
printf("\t\tCapabilities:\n");
|
||||
u=data[13]<<24|data[12]<<16|data[11]<<8|data[10];
|
||||
u2=data[17]<<24|data[16]<<16|data[15]<<8|data[14];
|
||||
@@ -853,9 +1091,9 @@ static void dmi_table(int fd, u32 base, int len, int num)
|
||||
else
|
||||
printf("disabled\n");
|
||||
printf("\t\tL%d Cache Size: ", 1+(u&7));
|
||||
dmi_cache_size(data[7]|data[8]<<8);
|
||||
printf("\t\tL%d Cache Maximum: ", 1+(u&7));
|
||||
dmi_cache_size(data[9]|data[10]<<8);
|
||||
printf("\t\tL%d Cache Maximum: ", 1+(u&7));
|
||||
dmi_cache_size(data[7]|data[8]<<8);
|
||||
printf("\t\tL%d Cache Type: ", 1+(u&7));
|
||||
dmi_decode_cache(data[13]);
|
||||
printf("\n");
|
||||
@@ -959,9 +1197,97 @@ static void dmi_table(int fd, u32 base, int len, int num)
|
||||
|
||||
case 16:
|
||||
printf("\tPhysical Memory Array\n");
|
||||
printf("\t\tLocation: %s\n",
|
||||
dmi_memory_array_location(data[4]));
|
||||
printf("\t\tUse: %s\n",
|
||||
dmi_memory_array_use(data[5]));
|
||||
printf("\t\tError Correction Type: %s\n",
|
||||
dmi_memory_array_error_correction_type(data[6]));
|
||||
u2 = data[10]<<24|data[9]<<16|data[8]<<8|data[7];
|
||||
printf("\t\tMaximum Capacity: ");
|
||||
if (u2 == 0x80000000)
|
||||
printf("Unknown\n");
|
||||
else
|
||||
printf("%u kB\n", u2);
|
||||
printf("\t\tError Information Handle: ");
|
||||
u = data[12]<<8|data[11];
|
||||
if (u == 0xffff) {
|
||||
printf("None\n");
|
||||
} else if (u == 0xfffe) {
|
||||
printf("Not Provided\n");
|
||||
} else {
|
||||
printf("0x%04X\n", u);
|
||||
}
|
||||
printf("\t\tNumber of Devices: %u\n", data[14]<<8|data[13]);
|
||||
break;
|
||||
case 17:
|
||||
printf("\tMemory Device\n");
|
||||
printf("\t\tArray Handle: 0x%04X\n", data[5]<<8|data[4]);
|
||||
printf("\t\tError Information Handle: ");
|
||||
u = data[7]<<8|data[6];
|
||||
if (u == 0xffff) {
|
||||
printf("None\n");
|
||||
} else if (u == 0xfffe) {
|
||||
printf("Not Provided\n");
|
||||
} else {
|
||||
printf("0x%04X\n", u);
|
||||
}
|
||||
u = data[9]<<8|data[8];
|
||||
printf("\t\tTotal Width: ");
|
||||
if (u == 0xffff)
|
||||
printf("Unknown\n");
|
||||
else
|
||||
printf("%u bits\n", u);
|
||||
u = data[11]<<8|data[10];
|
||||
printf("\t\tData Width: ");
|
||||
if (u == 0xffff)
|
||||
printf("Unknown\n");
|
||||
else
|
||||
printf("%u bits\n", u);
|
||||
u = data[13]<<8|data[12];
|
||||
printf("\t\tSize: ");
|
||||
if (u == 0xffff)
|
||||
printf("Unknown\n");
|
||||
else
|
||||
printf("%u %sbyte\n", (u&0x7fff), (u&0x8000) ? "K" : "M");
|
||||
printf("\t\tForm Factor: %s\n",
|
||||
dmi_memory_device_form_factor(data[14]));
|
||||
if (data[15] != 0) {
|
||||
printf("\t\tSet: ");
|
||||
if (data[15] == 0xff)
|
||||
printf("Unknown\n");
|
||||
else
|
||||
printf("0x%02X\n", data[15]);
|
||||
}
|
||||
printf("\t\tLocator: %s\n",
|
||||
dmi_string(dm, data[16]));
|
||||
printf("\t\tBank Locator: %s\n",
|
||||
dmi_string(dm, data[17]));
|
||||
printf("\t\tType: %s\n",
|
||||
dmi_memory_device_type(data[18]));
|
||||
u = data[20]<<8|data[19];
|
||||
if (u&0x1ffe)
|
||||
dmi_memory_device_detail(u);
|
||||
if (dm->length > 21) {
|
||||
u = data[22]<<8|data[21];
|
||||
printf("\t\tSpeed: ");
|
||||
if (u == 0)
|
||||
printf("Unknown\n");
|
||||
else
|
||||
printf("%u MHz (%.1f ns)\n", u, (1000.0/u));
|
||||
}
|
||||
if (dm->length > 23)
|
||||
printf("\t\tManufacturer: %s\n",
|
||||
dmi_string(dm, data[23]));
|
||||
if (dm->length > 24)
|
||||
printf("\t\tSerial Number: %s\n",
|
||||
dmi_string(dm, data[24]));
|
||||
if (dm->length > 25)
|
||||
printf("\t\tAsset Tag: %s\n",
|
||||
dmi_string(dm, data[25]));
|
||||
if (dm->length > 26)
|
||||
printf("\t\tPart Number: %s\n",
|
||||
dmi_string(dm, data[26]));
|
||||
break;
|
||||
case 18:
|
||||
printf("\t32-bit Memory Error Information\n");
|
||||
@@ -1023,9 +1349,9 @@ static void dmi_table(int fd, u32 base, int len, int num)
|
||||
case 27:
|
||||
printf("\tCooling Device\n");
|
||||
printf("\t\tDevice Type: %s\n",
|
||||
dmi_fan_type(data[5] & 0x1f));
|
||||
dmi_fan_type(data[6] & 0x1f));
|
||||
printf("\t\tDevice Status: %s\n",
|
||||
dmi_status(data[5] >> 5));
|
||||
dmi_status(data[6] >> 5));
|
||||
if(dm->length > 0x0c)
|
||||
printf("\t\tNominal Speed: %s\n",
|
||||
dmi_speed(data, 0x0c));
|
||||
@@ -1112,7 +1438,7 @@ static void dmi_table(int fd, u32 base, int len, int num)
|
||||
dump_raw_data(data+4, dm->length-4);
|
||||
break;
|
||||
case 37:
|
||||
printf("\tMemory Channeln");
|
||||
printf("\tMemory Channel\n");
|
||||
break;
|
||||
case 38:
|
||||
printf("\tIPMI Device\n");
|
||||
@@ -1140,30 +1466,88 @@ static void dmi_table(int fd, u32 base, int len, int num)
|
||||
|
||||
|
||||
}
|
||||
data+=dm->length;
|
||||
while(*data || data[1])
|
||||
data++;
|
||||
data+=2;
|
||||
data=next;
|
||||
i++;
|
||||
}
|
||||
if(i!=num)
|
||||
{
|
||||
printf("Wrong DMI structures count: %d announced, %d decoded.\n", num, i);
|
||||
printf("Wrong DMI structures count: %d announced, only %d decoded.\n",
|
||||
num, i);
|
||||
}
|
||||
if(data-(u8*)buf!=len)
|
||||
{
|
||||
printf("Wrong DMI structures length: %d bytes announced, %d bytes decoded.\n", len, data-(u8*)buf);
|
||||
printf("Wrong DMI structures length: %d bytes announced, %d bytes decoded.\n",
|
||||
len, data-(u8*)buf);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
static const char *acpi_version(u8 code)
|
||||
{
|
||||
unsigned char buf[20];
|
||||
static const char *version[]={
|
||||
" 1.0",
|
||||
"",
|
||||
" 2.0"
|
||||
};
|
||||
|
||||
if(code<=2)
|
||||
return version[code];
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
static const char *pnp_event_notification(u8 code)
|
||||
{
|
||||
static const char *notification[]={
|
||||
"Not Supported",
|
||||
"Polling",
|
||||
"Asynchronous"
|
||||
};
|
||||
|
||||
if(code<=2)
|
||||
return notification[code];
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
static void pir_exclusive_irqs(u16 code)
|
||||
{
|
||||
if(code==0)
|
||||
printf(" None");
|
||||
else
|
||||
{
|
||||
u8 a;
|
||||
for(a=0; a<16; a++)
|
||||
if(code&(1<<a))
|
||||
printf(" %u", a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static __inline__ int checksum(u8 *buf, int len)
|
||||
{
|
||||
u8 sum=0;
|
||||
int a;
|
||||
|
||||
for(a=0; a<len; a++)
|
||||
sum+=buf[a];
|
||||
return (sum==0);
|
||||
}
|
||||
|
||||
int main(__attribute__ ((unused)) int argc, const char *argv[])
|
||||
{
|
||||
u8 buf[48];
|
||||
int fd=open("/dev/mem", O_RDONLY);
|
||||
long fp=0xE0000L;
|
||||
u8 smmajver=0, smminver=0;
|
||||
|
||||
if(sizeof(u8)!=1 || sizeof(u16)!=2 || sizeof(u32)!=4 || '\0'!=0)
|
||||
{
|
||||
fprintf(stderr,"%s: compiler incompatibility.\n", argv[0]);
|
||||
exit(255);
|
||||
}
|
||||
printf("# dmidecode %s\n", VERSION);
|
||||
if(fd==-1)
|
||||
{
|
||||
perror("/dev/mem");
|
||||
@@ -1175,24 +1559,50 @@ int main(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
fp -= 16;
|
||||
|
||||
while( fp < 0xFFFFF)
|
||||
{
|
||||
fp+=16;
|
||||
if(read(fd, buf, 16)!=16)
|
||||
ssize_t r=0, r2=0;
|
||||
|
||||
while(r2!=16 && (r=read(fd, buf+r2, 16-r2))!=0 && r!=-1)
|
||||
r2+=r;
|
||||
if(r==-1)
|
||||
{
|
||||
perror("read");
|
||||
else if(memcmp(buf, "_SM_", 4)==0)
|
||||
exit(1);
|
||||
}
|
||||
if(r==0)
|
||||
{
|
||||
fputs("read: Unexpected end of file\n", stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(memcmp(buf, "_SM_", 4)==0)
|
||||
printf("SMBIOS %d.%d present.\n", smmajver=buf[6], smminver=buf[7]);
|
||||
else if(memcmp(buf, "_SYSID_", 7)==0)
|
||||
printf("SYSID present.\n");
|
||||
else if(memcmp(buf, "_DMI_", 5)==0)
|
||||
{
|
||||
/* complete buffer, compute checksum */
|
||||
read(fd, buf+16, 16); /* arbitrary, at least 1 */
|
||||
if(*(u16 *)(buf+8)<=32 && checksum(buf, *(u16 *)(buf+8)))
|
||||
{
|
||||
fp+=16;
|
||||
printf("SYSID present.\n");
|
||||
printf("\tRevision: %u\n",
|
||||
buf[16]);
|
||||
printf("%d structure%s.\n",
|
||||
*(u16 *)(buf+14), *(u16 *)(buf+14)>1?"s":"");
|
||||
printf("SYSID table at 0x%08X.\n",
|
||||
*(u32 *)(buf+10));
|
||||
}
|
||||
else
|
||||
lseek(fd, -16, SEEK_CUR);
|
||||
}
|
||||
else if(memcmp(buf, "_DMI_", 5)==0 && checksum(buf, 15))
|
||||
{
|
||||
u16 num=buf[13]<<8|buf[12];
|
||||
u16 len=buf[7]<<8|buf[6];
|
||||
u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
|
||||
|
||||
/* if version is 0.0, the real version is taken from _SM_ above */
|
||||
printf("DMI %d.%d present.\n",
|
||||
buf[14]?buf[14]>>4:smmajver, buf[14]?buf[14]&0x0F:smminver);
|
||||
printf("%d structures occupying %d bytes.\n",
|
||||
@@ -1205,28 +1615,111 @@ int main(void)
|
||||
lseek(fd, fp+16, SEEK_SET);
|
||||
}
|
||||
else if(memcmp(buf, "$PnP", 4)==0)
|
||||
printf("PNP BIOS present.\n");
|
||||
{
|
||||
/* complete buffer, compute checksum */
|
||||
read(fd, buf+16, 32); /* arbitrary, at least 1 */
|
||||
if(buf[5]<=48 && checksum(buf, buf[5]))
|
||||
{
|
||||
fp+=32;
|
||||
printf("PNP %u.%u present.\n",
|
||||
buf[4]>>4, buf[4]&0x0F);
|
||||
printf("\tEvent Notification: %s\n",
|
||||
pnp_event_notification((*(u16 *)(buf+6))&0x03));
|
||||
if(((*(u16 *)(buf+6))&0x03)==1)
|
||||
printf("\tEvent Notification Flag Address: 0x%08X\n",
|
||||
*(u32 *)(buf+9));
|
||||
printf("\tReal Mode Code Address: %04X:%04X\n",
|
||||
*(u16 *)(buf+0x0F), *(u16 *)(buf+0x0D));
|
||||
printf("\tReal Mode Data Address: %04X:0000\n",
|
||||
*(u16 *)(buf+0x1B));
|
||||
printf("\tProtected Mode Code Address: 0x%08X\n",
|
||||
*(u32 *)(buf+0x13)+*(u16 *)(buf+0x11));
|
||||
printf("\tProtected Mode Data Address: 0x%08X\n",
|
||||
*(u32 *)(buf+0x1D));
|
||||
if(*(u32 *)(buf+0x17)!=0)
|
||||
printf("\tOEM Device Identifier: 0x%08X\n",
|
||||
*(u32 *)(buf+0x17));
|
||||
}
|
||||
else
|
||||
lseek(fd, -32, SEEK_CUR);
|
||||
}
|
||||
else if(memcmp(buf, "RSD PTR ", 8)==0)
|
||||
{
|
||||
int a;
|
||||
unsigned char sum=0;
|
||||
printf("RSD PTR found at 0x%lX.\n", fp);
|
||||
|
||||
if(buf[15]!=0)
|
||||
/* complete buffer, compute checksum */
|
||||
read(fd, buf+16, 4);
|
||||
if(checksum(buf, 20))
|
||||
{
|
||||
printf("Reserved check failed.\n");
|
||||
lseek(fd, 12, SEEK_CUR);
|
||||
fp+=16;
|
||||
printf("ACPI%s present.\n",
|
||||
acpi_version(buf[15]));
|
||||
printf("\tOEM ID: ");
|
||||
fwrite(buf+9, 6, 1, stdout);
|
||||
printf("\n");
|
||||
printf("RSD table at 0x%08X.\n",
|
||||
*(u32 *)(buf+16));
|
||||
}
|
||||
printf("OEM ");
|
||||
fwrite(buf+9, 6, 1, stdout);
|
||||
printf("\n");
|
||||
read(fd,buf+16,4);
|
||||
lseek(fd, -4, SEEK_CUR);
|
||||
for(a=0;a<20;a++)
|
||||
sum+=buf[a];
|
||||
if(sum!=0)
|
||||
printf("Bad checksum.\n");
|
||||
else
|
||||
lseek(fd, -4, SEEK_CUR);
|
||||
}
|
||||
else if(memcmp(buf, "$SNY", 4)==0)
|
||||
{
|
||||
/* complete buffer, compute checksum */
|
||||
read(fd, buf+16, 16);
|
||||
if(buf[5]<=32 && checksum(buf, buf[5]))
|
||||
{
|
||||
fp+=16;
|
||||
printf("Sony system detected (?).\n");
|
||||
}
|
||||
else
|
||||
lseek(fd, -16, SEEK_CUR);
|
||||
}
|
||||
else if(memcmp(buf, "_32_", 4)==0)
|
||||
{
|
||||
/* complete buffer, reposition file, compute checksum */
|
||||
read(fd, buf+16, 32);
|
||||
lseek(fd, -32, SEEK_CUR);
|
||||
if(buf[9]>=1 && buf[9]<=3 && checksum(buf, buf[9]<<4))
|
||||
{
|
||||
printf("BIOS32 Service Directory present.\n");
|
||||
printf("\tCalling Interface Address: 0x%08X\n",
|
||||
*(u32 *)(buf+4));
|
||||
lseek(fd, (buf[9]-1)<<4, SEEK_CUR);
|
||||
fp+=(buf[9]-1)<<4;
|
||||
}
|
||||
}
|
||||
else if(memcmp(buf, "$PIR", 4)==0)
|
||||
{
|
||||
/* complete buffer, reposition file */
|
||||
read(fd, buf+16, 16);
|
||||
lseek(fd, -16, SEEK_CUR);
|
||||
if(buf[5]!=0 && buf[30]==0)
|
||||
{
|
||||
printf("PCI Interrupt Routing %u.%u present.\n",
|
||||
buf[5], buf[4]);
|
||||
printf("\tTable Size: %u bytes\n",
|
||||
*(u16 *)(buf+6));
|
||||
printf("\tRouter ID: %02x:%02x.%1x\n",
|
||||
buf[8], buf[9]>>3, buf[9]&0x07);
|
||||
printf("\tExclusive IRQs:");
|
||||
pir_exclusive_irqs(*(u16 *)(buf+10));
|
||||
printf("\n");
|
||||
if(*(u32 *)(buf+12)!=0)
|
||||
printf("\tCompatible Router: %04x:%04x\n",
|
||||
*(u16 *)(buf+12), *(u16 *)(buf+14));
|
||||
if(*(u32 *)(buf+16)!=0)
|
||||
printf("\tMiniport Data: 0x%08X\n",
|
||||
*(u32 *)(buf+16));
|
||||
}
|
||||
}
|
||||
fp+=16;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if(close(fd)==-1)
|
||||
{
|
||||
perror("/dev/mem");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user