/*
* printinfo.c - Print more info about an option rom
*
* Copyright (C) 1998-2003 Gero Kuhlmann <gero@gkminix.han.de>
*
* 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
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: printinfo.c,v 1.4 2003/01/25 23:29:43 gkminix Exp $
*/
#include <stdio.h>
#include <dos.h>
#include <ctype.h>
#include "romcheck.h"
#include "pnp.h"
/*
* Convert PnP product identifier into readable text
*/
static char *convid(pnp)
struct pnphdr *pnp;
{
static char buf[8];
char *id = pnp->devid;
int i;
/* Check if we have an identifier at all */
if ((id[0] + id[1] + id[2] + id[3]) == 0)
return("(none)");
/* Convert compressed product identifier into ascii text */
buf[0] = ((id[0] & 0x7C) >> 2) + 0x40;
buf[1] = ((id[0] & 0x03) << 3) + ((id[1] & 0xE0) >> 5) + 0x40;
buf[2] = ((id[1] & 0x1F)) + 0x40;
buf[3] = ((id[2] & 0xF0) >> 4);
buf[4] = ((id[2] & 0x0F));
buf[5] = ((id[3] & 0xF0) >> 4);
buf[6] = ((id[3] & 0x0F));
buf[7] = 0x00;
/* Convert BCD number into ascii text */
for (i = 3; i < 7; i++) {
buf[i] += '0';
if (buf[i] > '9')
buf[i] += 'A' - '0';
}
return(buf);
}
/*
* Get zero terminated string from ROM into static buffer
*/
static char *convstr(ofs, seg)
unsigned short ofs;
unsigned short seg;
{
static char buf[50];
char *cp;
/* Check if we have a string at all */
if (ofs == 0)
return("(none)");
/* Copy string into local buffer */
movedata(seg, ofs, __get_ds(), buf, 49);
buf[49] = '\0';
/* Convert all special characters to blanks */
for (cp = buf; *cp; cp++)
if (*cp && *cp < 0x20)
*cp = ' ';
return(buf);
}
/*
* Print information for one single PnP expansion header
*/
static void printsingle(pnp, seg)
struct pnphdr *pnp;
unsigned short seg;
{
int pnptype;
static char *basetypes[] = {
"Mass Storage Device",
"Network Interface Controller",
"Display Controller",
"Multimedia Controller",
"Memory",
"Bridge Controller",
"Communications Device",
"System Peripherals",
"Input Devices",
"Docking Station",
"CPU Type",
"Serial Controller" };
printf(" Revision number of header: %d\n", (int)(pnp->revision));
printf(" Device identifier: %s\n", convid(pnp));
printf(" Manufacturer string: %s\n",
convstr(pnp->manufacturer, seg));
printf(" Product name string: %s\n",
convstr(pnp->productname, seg));
printf(" Device type code: %02X %02X %02X ",
pnp->devtype[2], pnp->devtype[1], pnp->devtype[0]);
pnptype = pnp->devtype[2];
if (pnptype < 1 || pnptype > 11)
printf("(unknown)\n");
else
printf("(%s)\n", basetypes[pnptype - 1]);
printf(" Device indicators:\n");
if (pnp->devind == 0) {
printf(" none\n");
} else {
if (pnp->devind & DEVIND_IPL)
printf(" Device is an Initial Program Load device\n");
if (pnp->devind & DEVIND_INPUT)
printf(" Device is an input device\n");
if (pnp->devind & DEVIND_DISP)
printf(" Device is a display device\n");
if (pnp->devind & DEVIND_DDIM)
printf(" ROM supports Device Driver Initialization Model\n");
if (pnp->devind & DEVIND_SHADOW)
printf(" ROM may be shadowed in RAM\n");
if (pnp->devind & DEVIND_CACHE)
printf(" ROM is read cacheable\n");
if (pnp->devind & DEVIND_BOOT)
printf(" ROM is only required if device selected for boot\n");
}
}
/*
* Print PnP expansion header information
*/
static void printpnp(sip, index)
struct scaninfo *sip;
int index;
{
static struct pnphdr pnp;
unsigned short hdrofs;
unsigned short hdrlen, i;
unsigned short hdrchksum = 0;
unsigned short segend;
int hdrnum = 0;
/* Don't do anything if the index number or rom signature are invalid */
if (index < 0 || index >= sip->signum || !sip->sigvalid[index])
return;
/* Determine last possible offset for PnP expansion header */
if ((sip->sigsize[index] & 0xF000) != 0)
segend = 0xFFFF - sizeof(pnp);
else
segend = (sip->sigsize[index] * 16) - sizeof(pnp);
/* Get address of first expansion header */
movedata(sip->sigsegs[index], PNP_HDROFS, __get_ds(), &hdrofs, sizeof(hdrofs));
/* Scan through all expansion headers */
while (hdrofs > 0 && hdrofs < segend) {
/* Copy expansion header into local memory */
movedata(sip->sigsegs[index], hdrofs, __get_ds(), &pnp, sizeof(pnp));
/* Check if we have a valid PnP header */
if (memcmp(pnp.sig, "$PnP", 4))
break;
/* Check for correct header size */
if (pnp.size != (sizeof(pnp) / 16)) {
printf(" PnP compatible ROM header found with invalid size at offset %04X\n",
hdrofs);
return;
}
hdrlen = pnp.size * 16;
if (hdrlen > sizeof(pnp))
hdrlen = sizeof(pnp);
/* Compute checksum of PnP expansion header */
for (i = 0; i < hdrlen; i++) {
hdrchksum += ((unsigned char *)&pnp)[i];
hdrchksum &= 0x00FF;
}
if (hdrchksum != 0) {
printf(" PnP compatible ROM header found with invalid checksum at offset %04X\n",
hdrofs);
return;
}
/* Print PnP header information */
printf(" Information from PnP expansion header %d:\n", hdrnum);
printsingle(&pnp, sip->sigsegs[index]);
hdrnum++;
/* Get offset to next header */
hdrofs = pnp.next;
}
/* Finally print how many headers we found */
if (hdrnum == 0)
printf(" No PnP compatible ROM header found\n");
else if (hdrnum == 1)
printf(" Found one PnP compatible ROM header\n");
else
printf(" Found %d PnP compatible ROM headers\n", hdrnum);
}
/*
* Print a rom area or the whole memory as a hex dump.
*/
void printinfo(sip)
struct scaninfo *sip;
{
int index;
/* Ask the user about which rom to print information for */
printf("\n\n");
index = readint("Enter rom area number", 1, sip->signum, 1) - 1;
/* Print information for rom */
printf("\n\nInformation for rom area number %d:\n", index + 1);
printf(" Starting segment: %4X", sip->sigsegs[index]);
if (sip->flashseg == sip->sigsegs[index])
printf(" (at beginning of flash EPROM)");
printf("\n Rom size: %d kB\n", sip->sigsize[index] / 64);
printf(" Copyright: %s\n", convstr(sip->sigcpyrt[index], sip->sigsegs[index]));
if (!sip->sigvalid[index])
printf(" The checksum of the rom is invalid!\n");
else
printpnp(sip, index);
if (index == sip->nbindex)
printf(" This rom is a netboot bootrom\n");
}
/*
* Print information about netboot bootrom
*/
void printnb(sip)
struct scaninfo *sip;
{
unsigned short index = sip->nbindex;
if (index >= 0 && index < sip->signum) {
printf("\n\nFound netboot bootrom:\n");
printf(" Rom area number: %d\n", index + 1);
printf(" Starting segment: %4X", sip->sigsegs[index]);
if (sip->flashseg == sip->sigsegs[index])
printf(" (at beginning of flash EPROM)");
printf("\n Rom size: %d kB\n", sip->sigsize[index] / 64);
printf(" Version: %d.%d\n", sip->nbmajor, sip->nbminor);
printf(" Copyright: %s\n", convstr(sip->sigcpyrt[index], sip->sigsegs[index]));
if (!sip->sigvalid[index])
printf(" The checksum of the netboot bootrom is invalid!\n");
else
printpnp(sip, index);
} else {
printf("\nNo netboot bootrom found\n");
}
}
syntax highlighted by Code2HTML, v. 0.9.1