1
0
Files
irix-657m-src/stand/arcs/lib/libsc/cmd/hinv_cmd.c
2022-09-29 17:59:04 +03:00

467 lines
11 KiB
C

#ident "lib/libsc/cmd/hinv_cmd.c: $Revision: 1.95 $"
/*
* Hardware inventory command for prom/standalone programs
*
*/
#include <sys/types.h>
#include <arcs/io.h>
#include <arcs/hinv.h>
#include <arcs/cfgdata.h>
#include <arcs/errno.h>
#include <arcs/pvector.h>
#include <libsc.h>
#include <libsc_internal.h>
static int is_MP; /* Flag indicating whether system is multiprocessor */
static void hinv_walk(COMPONENT *, int, int);
static void prcomponent(COMPONENT *, int, int);
static void irixprcomponent(COMPONENT *, int);
#define HINV_VERBOSE 0x01
#define HINV_PATHS 0x02
#define HINV_ARCS 0x04
#define HINV_BUSINFO 0x08
#define HINVCENTER 25 /* where : is centered */
/*ARGSUSED*/
int
hinv(int argc, char **argv, char **bunk1, struct cmd_table *bunk2)
{
int flags = 0;
if (GetChild(NULL) == NULL) { /* must be a SN0 system */
kl_hinv(argc, argv) ;
return 0 ;
}
while (--argc) {
++argv;
if (!strcmp(*argv,"-v"))
flags |= HINV_VERBOSE;
else if (!strcmp(*argv,"-t"))
flags |= HINV_ARCS;
else if (!strcmp(*argv,"-p"))
flags |= HINV_PATHS;
else if (!strcmp(*argv,"-b"))
flags |= HINV_BUSINFO;
else
return 1;
}
if (flags & HINV_BUSINFO) {
businfo(flags & HINV_VERBOSE);
return 0;
}
is_MP = (_get_numcpus() > 1);
hinv_walk(GetChild(NULL),0,flags);
return 0;
}
static char *_class[] = {
"system",
"processor",
"cache",
#ifndef _NT_PROM
"memory",
"adapter",
"controller",
"peripheral"
#else
"adapter",
"controller",
"peripheral",
"memory"
#endif
};
#define _CLASS_SIZE (sizeof _class / sizeof _class[0])
static char *_type[] = {
"ARC",
"CPU",
"FPU",
"primary icache",
"primary dcache",
"secondary icache",
"secondary dcache",
"secondary cache",
#ifndef _NT_PROM
"main",
#endif
"EISA",
"TC",
"SCSI",
"DTI",
"multi function",
"disk",
"tape",
"CDROM",
"WORM",
"serial",
"network",
"display",
"parallel",
"pointer",
"keyboard",
"audio",
"other",
"disk",
"floppy disk",
"tape",
"modem",
"monitor",
"printer",
"pointer",
"keyboard",
"terminal",
"line",
"network",
#ifdef _NT_PROM
"main",
#endif
"other",
"XTalk", /* xtalk adapters like heart, xbow, hub */
"PCI", /* pci adapters like bridge */
"GIO", /* gio adapters like bridge */
"TPU", /* TPU adapter */
};
#define _TYPE_SIZE (sizeof _type / sizeof _type[0])
/* high byte class, bottom triplet class */
#define ctmunge(class,type) ((class<<24)|type)
#define MEM_MM ctmunge(MemoryClass,Memory)
#define DEV_DISK ctmunge(PeripheralClass,DiskPeripheral)
#define DEV_OTHER ctmunge(ControllerClass,OtherController)
#define DEV_TAPE ctmunge(PeripheralClass,TapePeripheral)
#define DEV_FLOPPY ctmunge(PeripheralClass,FloppyDiskPeripheral)
#define DEV_NETWORK ctmunge(PeripheralClass,NetworkPeripheral)
#define PROC_CPU ctmunge(ProcessorClass,CPU)
#define PROC_FPU ctmunge(ProcessorClass,FPU)
#define CACHE_SCACHE ctmunge(CacheClass,SecondaryCache)
#define CACHE_PICACHE ctmunge(CacheClass,PrimaryICache)
#define CACHE_PDCACHE ctmunge(CacheClass,PrimaryDCache)
#define CACHE_SICACHE ctmunge(CacheClass,SecondaryICache)
#define CACHE_SDCACHE ctmunge(CacheClass,SecondaryDCache)
#define CTRL_DISP ctmunge(ControllerClass,DisplayController)
#define CTRL_AUDIO ctmunge(ControllerClass,AudioController)
#define CTRL_NETWORK ctmunge(ControllerClass,NetworkController)
#define SYS_ARC ctmunge(SystemClass,ARC)
#define BUS_XTALK ctmunge(AdapterClass, XTalkAdapter)
#define BUS_PCI ctmunge(AdapterClass, PCIAdapter)
#define BUS_GIO ctmunge(AdapterClass, GIOAdapter)
#define BUS_TPU ctmunge(AdapterClass, TPUAdapter)
#define PERIPH_OTHER ctmunge(PeripheralClass,OtherPeripheral)
static void
prcfgdata(COMPONENT *c, int n)
{
struct cfgdatahdr *p;
char *dsh = "-";
if (!c->ConfigurationDataSize)
return;
if (!(p=(struct cfgdatahdr *)malloc(c->ConfigurationDataSize)))
panic("cannot malloc space for cfgdata\n");
if (GetConfigurationData(p,c) != ESUCCESS) {
printf("GetConfigurationData FAILED!\n");
goto done;
}
printf("%*sv: ",2*n,"");
printf("%s %s %s %s ",
p->Type ? p->Type : dsh,
p->Vendor ? p->Vendor : dsh,
p->ProductName ? p->ProductName : dsh,
p->SerialNumber ? p->SerialNumber : dsh);
switch(c->Type) {
case NetworkController:
{
struct net_data *nd = (struct net_data *)p;
ulong i;
printf("type: %s MTU: %u HW: ",
nd->NetType, nd->NetMaxlength);
for (i = 0; i < nd->NetAddressSize; i++)
printf("%s%x", !i?"":":",
nd->NetAddress[i]);
}
break;
case DiskPeripheral:
if (c->Type && !strcmp(p->Type,SCSIDISK_TYPE)) {
struct scsidisk_data *d =
(struct scsidisk_data *)p;
printf("blocksize: %u maxblocks: %u",
d->BlockSize, d->MaxBlocks);
}
break;
}
printf("\n");
done:
free(p);
return;
}
static void
prcomponent(COMPONENT *c, int n, int f)
{
long classtype = ctmunge(c->Class,c->Type);
printf("%*s",2*n,"");
printf("%s %s",
c->Class < _CLASS_SIZE ? _class[c->Class] : "invalid class",
c->Type < _TYPE_SIZE ? _type[c->Type] : "invalid type");
if (c->Identifier)
printf(" %s",c->Identifier);
switch (classtype) {
case DEV_DISK:
case DEV_TAPE:
printf(" unit %u",c->Key);
break;
case CACHE_SCACHE:
case CACHE_PICACHE:
case CACHE_PDCACHE:
case CACHE_SICACHE:
case CACHE_SDCACHE:
{
union key_u key;
key.FullKey = c->Key;
printf(" %d Kbytes (block %d lines, line %d bytes)",
(1<<key.cache.c_size)*4,
key.cache.c_bsize,
1<<key.cache.c_lsize);
break;
}
case MEM_MM:
printf(" %u Mbytes",c->Key/256);
break;
default:
printf(" key %u",c->Key);
break;
}
if ((f & HINV_VERBOSE) && c->Flags)
printf(" (%s%s%s%s%s%s%s )",
c->Flags & Failed ? " Failed" : "",
c->Flags & ReadOnly ? " ReadOnly" : "",
c->Flags & Removable ? " Removable" : "",
c->Flags & ConsoleIn ? " ConsoleIn" : "",
c->Flags & ConsoleOut ? " ConsoleOut" : "",
c->Flags & Input ? " Input" : "",
c->Flags & Output ? " Output" : "");
printf("\n");
if (f & HINV_VERBOSE)
prcfgdata(c,n);
if (f & HINV_PATHS) {
char *p = (char *)getpath(c);
if (p) printf("%*sp: %s\n",2*n,"",getpath(c));
}
}
/*ARGSUSED*/
static void
irixprcomponent(COMPONENT *c, int f)
{
long classtype = ctmunge(c->Class,c->Type);
COMPONENT *pp, *p = GetParent(c);
char *str;
switch(classtype) {
case DEV_OTHER:
if (p->Type == SCSIAdapter) {
if (c->Type == OtherController) {
printf("%*s: Controller %lu ID %lu\n",HINVCENTER,
"SCSI Device",p->Key,c->Key);
}
}
break;
case DEV_DISK:
pp = GetParent(p);
if (pp->Type == SCSIAdapter) {
if (p->Type == CDROMController)
printf("%*s: scsi(%u)cdrom(%u)\n",
HINVCENTER,"SCSI CDROM",
pp->Key, p->Key);
else
printf("%*s: scsi(%u)disk(%u)\n",HINVCENTER,
"SCSI Disk",pp->Key,p->Key);
}
/* only support SCSI disk so far */
break;
case DEV_TAPE:
pp = GetParent(p);
if (pp->Type == SCSIAdapter) {
printf("%*s: scsi(%u)tape(%u)\n",HINVCENTER,"SCSI Tape",
pp->Key,p->Key);
}
/* only support SCSI tape so far */
break;
case DEV_FLOPPY:
pp = GetParent(p);
if (pp->Type == SCSIAdapter) {
printf("%*s: Controller %u, ID %u, removable media\n",
HINVCENTER,"SCSI Disk", pp->Key, p->Key);
}
break;
#ifndef _NT_PROM
case MEM_MM:
printf("%*s: %u Mbytes\n",HINVCENTER,"Memory size",c->Key/256);
break;
#endif
case SYS_ARC: /* root of tree */
printf("%*s: %s\n",HINVCENTER,"System",c->Identifier+4);
break;
case PROC_CPU: /* handle cpu/fpu */
printf("%*s: %d Mhz %s",HINVCENTER,"Processor",
cpufreq((int)c->Key), c->Identifier+5);
/* Display scache information */
if (is_MP && (pp = find_type(c, SecondaryCache)) &&
(pp->Type == SecondaryCache)) {
union key_u key;
key.FullKey = pp->Key;
printf(", %dM secondary cache", (1<<key.cache.c_size)/256);
}
if (c->Key != 0)
printf(", (cpu %u)", c->Key);
if ((pp = GetChild(c)) && (pp->Type == FPU) && !is_MP)
printf(", with FPU");
printf("\n");
break;
case CACHE_SCACHE:
str = "Secondary cache size";
goto commoncache;
case CACHE_PICACHE:
str = "Primary I-cache size";
goto commoncache;
case CACHE_PDCACHE:
str = "Primary D-cache size";
goto commoncache;
case CACHE_SICACHE:
str = "Secondary I-cache size";
goto commoncache;
case CACHE_SDCACHE:
str = "Secondary D-cache size";
commoncache:
{
union key_u key;
key.FullKey = c->Key;
if (!is_MP || (f & HINV_VERBOSE)) {
/* Caches 2MB and bigger report as MB. Pick
* this number so old R4k systems do not
* change.
*/
if (key.cache.c_size >= 9)
printf("%*s: %d Mbytes\n",HINVCENTER,
str,1<<(key.cache.c_size-8));
else
printf("%*s: %d Kbytes\n",HINVCENTER,
str,(1<<key.cache.c_size)*4);
}
}
break;
case CTRL_DISP:
printf("%*s: %s\n",HINVCENTER,"Graphics",c->Identifier+4);
break;
case CTRL_AUDIO:
if (!strcmp("HAL2",c->Identifier)) {
printf("%*s: Iris Audio Processor: version A2 revision %d.%d.%d\n",HINVCENTER,
"Audio",
(c->Key>>12)&0x7, /* board */
(c->Key>>4)&0xf, /* chip major */
c->Key&0xf); /* chip minor */
}
else {
printf("%*s: %s",HINVCENTER,"Audio",c->Identifier);
if (c->Key) printf(" revision %d\n",c->Key);
putchar('\n');
}
break;
case CTRL_NETWORK:
if (!strncmp("MACE",c->Identifier,4)) {
printf("%*s: %s", HINVCENTER, "Network",
c->Identifier+5);
printf(" revision %d\n", c->Key);
}
break;
case BUS_XTALK:
if (c->Key != 0) /* don't report primary (built-in) XTalk */
printf("%*s: %s %d\n",HINVCENTER,
"XIO Bus",c->Identifier,c->Key);
break;
case BUS_PCI:
/* Don't report any PCI buses that want to hide (mainly
* built in PC buses now.
*/
if (c->Identifier && c->Identifier[0] != '\0')
printf("%*s: %s (%d)\n",HINVCENTER,
"PCI Bus",c->Identifier,c->Key);
break;
case BUS_GIO:
printf("%*s: %s (%d)\n",HINVCENTER,
"GIO Bus",c->Identifier,c->Key);
break;
case BUS_TPU:
printf("%*s: %s\n", HINVCENTER,
"TPU",c->Identifier);
break;
case PERIPH_OTHER:
/* Print Unknown devices if bus code adds info about it */
if (c->Identifier) {
if (p->Type == PCIAdapter) {
printf("%*s: %s\n",HINVCENTER,
"PCI Device",c->Identifier);
} else {
printf("%*s: %s key %u\n",HINVCENTER,
"Unknown Device",c->Identifier,c->Key);
}
}
break;
case DEV_NETWORK:
/* For the builtin network device */
if (c->IdentifierLength && c->Identifier && c->Identifier[0] != '\0')
printf("%*s: %s\n",HINVCENTER,
"Network", c->Identifier);
break;
}
}
static void
hinv_walk(COMPONENT *c, int n, int f)
{
if (!c) return;
if (f&HINV_ARCS)
prcomponent(c,n,f);
else
irixprcomponent(c,f);
hinv_walk(GetChild(c),n+1,f);
hinv_walk(GetPeer(c),n,f);
return;
}