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:
Jean Delvare committed 2002-11-07 15:24:20 +00:00
1 parent 1c48b4e402
commit f0d334292d
2 files changed
+565 -72

No files matched your search

+1 -1
View File
@@ -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
View File
@@ -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;
}