/* * printinfo.c - Print more info about an option rom * * Copyright (C) 1998-2003 Gero Kuhlmann * * 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 #include #include #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"); } }