xref: /netbsd-src/sys/arch/prep/prep/residual.c (revision e43fe3179e5fcdc68798d1351d1a39732a57eee8)
1 /*      $NetBSD: residual.c,v 1.19 2023/11/24 16:49:59 christos Exp $     */
2 
3 /*-
4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by NONAKA Kimihiro.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: residual.c,v 1.19 2023/11/24 16:49:59 christos Exp $");
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/inttypes.h>
38 
39 #include <machine/residual.h>
40 #include <machine/pnp.h>
41 
42 #include "opt_residual.h"
43 
44 #ifdef RESIDUAL_DATA_DUMP
45 
46 #include <machine/chpidpnp.h>
47 #include <machine/pcipnp.h>
48 
49 static void make_pnp_device_tree(void *);
50 static void bustype_subr(DEVICE_ID *);
51 
52 int dump_residual_data = 1;
53 
54 #define	NELEMS(array)	((size_t)(sizeof(array)/sizeof(array[0])))
55 
56 static const char *FirmwareSupplier[] = {
57 	"IBMFirmware",
58 	"MotoFirmware",
59 	"FirmWorks",
60 	"Bull",
61 };
62 
63 static const char *FirmwareSupports[] = {
64 	"Conventional",
65 	"OpenFirmware",
66 	"Diagnostics",
67 	"LowDebug",
68 	"Multiboot",
69 	"LowClient",
70 	"Hex41",
71 	"FAT",
72 	"ISO9660",
73 	"SCSI_InitiatorID_Override",
74 	"Tape_Boot",
75 	"FW_Boot_Path",
76 };
77 
78 static const char *EndianSwitchMethod[] = {
79 	"Unknown",
80 	"UsePort92",
81 	"UsePCIConfigA8",
82 	"UseFF001030",
83 };
84 
85 static const char *SpreadIOMethod[] = {
86 	"UsePort850",
87 };
88 
89 static const char *CacheAttrib[] = {
90 	"No cache",
91 	"Split cache",
92 	"Combined cache",
93 };
94 
95 static const char *TLBAttrib[] = {
96 	"No TLB",
97 	"Split TLB",
98 	"Combined TLB",
99 };
100 
101 static const char *Usage[] = {
102 	"FirmwareStack",
103 	"FirmwareHeap",
104 	"FirmwareCode",
105 	"BootImage",
106 	"Free",
107 	"Unpopulated",
108 	"ISAAddr",
109 	"PCIConfig",
110 	"PCIAddr",
111 	"SystemRegs",
112 	"SystemIO",
113 	"IOMemory",
114 	"UnPopSystemROM",
115 	"SystemROM",
116 	"ResumeBlock",
117 	"Other",
118 };
119 
120 static const char *BusId[] = {
121 	"ISA",
122 	"EISA",
123 	"PCI",
124 	"PCMCIA",
125 	"ISAPNP",
126 	"MCA",
127 	"MX",
128 	"PROCESSOR",
129 	"VME",
130 };
131 
132 static const char *Flags[] = {
133 	"Output",
134 	"Input",
135 	"ConsoleOut",
136 	"ConsoleIn",
137 	"Removable",
138 	"ReadOnly",
139 	"PowerManaged",
140 	"Disableable",
141 	"Configurable",
142 	"Boot",
143 	"Dock",
144 	"Static",
145 	"Failed",
146 	"Integrated",
147 	"Enabled",
148 };
149 
150 #endif /* RESIDUAL_DATA_DUMP */
151 
152 
153 /*
154  * Convert a pnp DevId to a string.
155  */
156 
157 void
pnp_devid_to_string(uint32_t devid,char * s)158 pnp_devid_to_string(uint32_t devid, char *s)
159 {
160 	uint8_t p[4];
161 	uint32_t l;
162 
163 	if (res->Revision == 0)
164 		l = le32toh(devid);
165 	else
166 		l = be32toh(devid);
167 	p[0] = (l >> 24) & 0xff;
168 	p[1] = (l >> 16) & 0xff;
169 	p[2] = (l >> 8) & 0xff;
170 	p[3] = l & 0xff;
171 
172 	*s++ = ((p[0] >> 2) & 0x1f) + 'A' - 1;
173 	*s++ = (((p[0] & 0x03) << 3) | ((p[1] >> 5) & 0x07)) + 'A' - 1;
174 	*s++ = (p[1] & 0x1f) + 'A' - 1;
175 	*s++ = HEXDIGITS[(p[2] >> 4) & 0xf];
176 	*s++ = HEXDIGITS[p[2] & 0xf];
177 	*s++ = HEXDIGITS[(p[3] >> 4) & 0xf];
178 	*s++ = HEXDIGITS[p[3] & 0xf];
179 	*s = '\0';
180 }
181 
182 /*
183  * Count the number of a specific deviceid on the pnp tree.
184  */
185 
186 int
count_pnp_devices(const char * devid)187 count_pnp_devices(const char *devid)
188 {
189 	PPC_DEVICE *ppc_dev;
190 	int i, found=0;
191 	uint32_t ndev;
192 	char deviceid[8];
193 
194 	ndev = be32toh(res->ActualNumDevices);
195 	ppc_dev = res->Devices;
196 
197 	for (i = 0; i < ((ndev > MAX_DEVICES) ? MAX_DEVICES : ndev); i++) {
198 		DEVICE_ID *id = &ppc_dev[i].DeviceId;
199 
200 		pnp_devid_to_string(id->DevId, deviceid);
201 		if (strcmp(deviceid, devid) == 0)
202 			found++;
203 	}
204 	return found;
205 }
206 
207 /*
208  * find and return a pointer to the N'th device of a given type.
209  */
210 
211 PPC_DEVICE *
find_nth_pnp_device(const char * devid,int busid,int n)212 find_nth_pnp_device(const char *devid, int busid, int n)
213 {
214 	PPC_DEVICE *ppc_dev;
215 	int i, found=0;
216 	uint32_t ndev, l, bid = 0;
217 	char deviceid[8];
218 
219 	ndev = be32toh(res->ActualNumDevices);
220 	ppc_dev = res->Devices;
221 	n++;
222 
223 	if (busid != 0)
224 		bid = 1UL << busid;
225 
226 	for (i = 0; i < ((ndev > MAX_DEVICES) ? MAX_DEVICES : ndev); i++) {
227 		DEVICE_ID *id = &ppc_dev[i].DeviceId;
228 
229 		if (bid) {
230 			printf("???\n");
231 			l = be32toh(id->BusId);
232 			if ((l & bid) == 0)
233 				continue;
234 		}
235 		pnp_devid_to_string(id->DevId, deviceid);
236 		if (strcmp(deviceid, devid) == 0) {
237 			found++;
238 			if (found == n)
239 				return &ppc_dev[i];
240 		}
241 	}
242 	return NULL;
243 }
244 
245 int
pnp_pci_busno(void * v,int * bus)246 pnp_pci_busno(void *v, int *bus)
247 {
248 	struct _L4_Pack *pack = v;
249 	struct _L4_PPCPack *p = &pack->L4_Data.L4_PPCPack;
250 	int item, size, tag = *(unsigned char *)v;
251 	unsigned char *q = v;
252 
253 	item = tag_large_item_name(tag);
254 	size = (q[1] | (q[2] << 8)) + 3 /* tag + length */;
255 	*bus = -1;
256 
257 	if (res->Revision == 0)
258                 return size;
259 	if (item != LargeVendorItem)
260 		return size;
261 	if (p->Type != LV_PCIBridge) /* PCI Bridge type */
262 		return size;
263 
264 	*bus = p->PPCData[16];
265 	return size;
266 }
267 
268 /* Get the PCI config base and addr from PNP */
269 
270 int
pnp_pci_configbase(void * v,uint32_t * addr,uint32_t * data)271 pnp_pci_configbase(void *v, uint32_t *addr, uint32_t *data)
272 {
273 	struct _L4_Pack *pack = v;
274 	struct _L4_PPCPack *p = &pack->L4_Data.L4_PPCPack;
275 	int item, size, tag = *(unsigned char *)v;
276 	unsigned char *q = v;
277 
278 	item = tag_large_item_name(tag);
279 	size = (q[1] | (q[2] << 8)) + 3 /* tag + length */;
280 	/* init to zero so we don't return garbage values */
281 	*addr = 0;
282 	*data = 0;
283 
284 	if (res->Revision == 0)
285 		return size;
286 	if (item != LargeVendorItem)
287 		return size;
288 	if (p->Type != LV_PCIBridge) /* PCI Bridge type */
289 		return size;
290 
291 	*addr = (uint32_t)le64dec(&p->PPCData[0]);
292 	*data = (uint32_t)le64dec(&p->PPCData[8]);
293 	return size;
294 }
295 
296 #ifdef RESIDUAL_DATA_DUMP
297 
298 void
print_residual_device_info(void)299 print_residual_device_info(void)
300 {
301 	VPD *vpd;
302 	PPC_CPU *ppc_cpu;
303 	MEM_MAP *mem_map;
304 	PPC_MEM *ppc_mem;
305 	PPC_DEVICE *ppc_dev;
306 	const char *str;
307 	unsigned long l;
308 	unsigned short s;
309 	unsigned long nmseg;
310 	unsigned long nmem;
311 	unsigned long ndev;
312 	unsigned long page_size;
313 	int ncpus;
314 	int first;
315 	int i, j;
316 	char deviceid[9];
317 
318 	if (!dump_residual_data)
319 		return;
320 
321 	if (be32toh(res->ResidualLength) == 0)
322 		return;
323 
324 	printf("ResidualLength = %ld\n", be32toh(res->ResidualLength));
325 	printf("Version = %d\n", res->Version);
326 	printf("Revision = %d\n", res->Revision);
327 	printf("EC = %d\n", be16toh(res->EC));
328 
329 	/*
330 	 * VPD
331 	 */
332 	vpd = &res->VitalProductData;
333 	printf("\nVPD\n");
334 	printf("  PrintableModel = %-32s\n", vpd->PrintableModel);
335 	printf("  Serial = %-16s\n", vpd->Serial);
336 
337 	l = be32toh(vpd->FirmwareSupplier);
338 	printf("  FirmwareSupplier = %s\n",
339 	    (l >= NELEMS(FirmwareSupplier)) ? "Unknown" : FirmwareSupplier[l]);
340 	l = be32toh(vpd->FirmwareSupports);
341 	printf("  FirmwareSupports = 0x%08lx\n", l);
342 	for (first = 1, i = 0; i < sizeof(unsigned long) * 8; i++) {
343 		if ((l & (1UL << i)) != 0) {
344 			printf("    : %s\n", i >= NELEMS(FirmwareSupports)
345 			    ? "Unknown" : FirmwareSupports[i]);
346 			   first = 0;
347 		}
348 	}
349 	if (first)
350 		printf("    : None\n");
351 
352 	printf("  NvramSize = %ld\n", be32toh(vpd->NvramSize));
353 	printf("  NumSIMMSlots = %ld\n", be32toh(vpd->NumSIMMSlots));
354 	s = be16toh(vpd->EndianSwitchMethod);
355 	printf("  EndianSwitchMethod = %s\n",
356 	    (s >= NELEMS(EndianSwitchMethod))
357 	      ? "Unknown" : EndianSwitchMethod[s]);
358 	s = be16toh(vpd->SpreadIOMethod);
359 	printf("  SpreadIOMethod = %s\n",
360 	    (s >= NELEMS(SpreadIOMethod)) ? "Unknown" : SpreadIOMethod[s]);
361 	printf("  SmpIar = %ld\n", be32toh(vpd->SmpIar));
362 	printf("  RAMErrLogOffset = %ld\n", be32toh(vpd->RAMErrLogOffset));
363 	printf("  ProcessorHz = %ld\n", be32toh(vpd->ProcessorHz));
364 	printf("  ProcessorBusHz = %ld\n", be32toh(vpd->ProcessorBusHz));
365 	printf("  TimeBaseDivisor = %ld\n", be32toh(vpd->TimeBaseDivisor));
366 	printf("  WordWidth = %ld\n", be32toh(vpd->WordWidth));
367 	page_size = be32toh(vpd->PageSize);
368 	printf("  PageSize = %ld\n", page_size);
369 	printf("  CoherenceBlockSize = %ld\n",be32toh(vpd->CoherenceBlockSize));
370 	printf("  GranuleSize = %ld\n", be32toh(vpd->GranuleSize));
371 
372 	printf("  L1 Cache variables\n");
373 	printf("    CacheSize = %ld\n", be32toh(vpd->CacheSize));
374 	l = be32toh(vpd->CacheAttrib);
375 	printf("    CacheAttrib = %s\n",
376 	    (l >= NELEMS(CacheAttrib)) ? "Unknown" : CacheAttrib[l]);
377 	printf("    CacheAssoc = %ld\n", be32toh(vpd->CacheAssoc));
378 	printf("    CacheLineSize = %ld\n", be32toh(vpd->CacheLineSize));
379 	printf("    I-CacheSize = %ld\n", be32toh(vpd->I_CacheSize));
380 	printf("    I-CacheAssoc = %ld\n", be32toh(vpd->I_CacheAssoc));
381 	printf("    I-CacheLineSize = %ld\n", be32toh(vpd->I_CacheLineSize));
382 	printf("    D-CacheSize = %ld\n", be32toh(vpd->D_CacheSize));
383 	printf("    D-CacheAssoc = %ld\n", be32toh(vpd->D_CacheAssoc));
384 	printf("    D-CacheLineSize = %ld\n", be32toh(vpd->D_CacheLineSize));
385 	printf("  Translation Lookaside Buffer variables\n");
386 	printf("    Number of TLB entries = %ld\n", be32toh(vpd->TLBSize));
387 	l = be32toh(vpd->TLBAttrib);
388 	printf("    TLBAttrib = %s\n",
389 	    (l >= NELEMS(TLBAttrib)) ? "Unknown" : TLBAttrib[l]);
390 	printf("    TLBAssoc = %ld\n", be32toh(vpd->TLBAssoc));
391 	printf("    I-TLBSize = %ld\n", be32toh(vpd->I_TLBSize));
392 	printf("    I-TLBAssoc = %ld\n", be32toh(vpd->I_TLBAssoc));
393 	printf("    D-TLBSize = %ld\n", be32toh(vpd->D_TLBSize));
394 	printf("    D-TLBAssoc = %ld\n", be32toh(vpd->D_TLBAssoc));
395 	printf("  ExtendedVPD = 0x%lx\n", be32toh(vpd->ExtendedVPD));
396 
397 	/*
398 	 * PPC_CPU
399 	 */
400 	printf("\n");
401 	printf("MaxNumCpus = %d\n", be16toh(res->MaxNumCpus));
402 	ncpus = be16toh(res->ActualNumCpus);
403 	printf("ActualNumCpus = %d\n", ncpus);
404 	ppc_cpu = res->Cpus;
405 	for (i = 0; i < ((ncpus > MAX_CPUS) ? MAX_CPUS : ncpus); i++) {
406 		printf("%d:\n", i);
407 		printf("  CpuType = %08lx\n", be32toh(ppc_cpu[i].CpuType));
408 		printf("  CpuNumber = %d\n", ppc_cpu[i].CpuNumber);
409 		switch (ppc_cpu[i].CpuState) {
410 		case CPU_GOOD:
411 			str = "CPU is present, and active";
412 			break;
413 		case CPU_GOOD_FW:
414 			str = "CPU is present, and in firmware";
415 			break;
416 		case CPU_OFF:
417 			str = "CPU is present, but inactive";
418 			break;
419 		case CPU_FAILED:
420 			str = "CPU is present, but failed POST";
421 			break;
422 		case CPU_NOT_PRESENT:
423 			str = "CPU not present";
424 			break;
425 		default:
426 			str = "Unknown state";
427 			break;
428 		}
429 		printf("  CpuState: %s (%d)\n", str, ppc_cpu[i].CpuState);
430 	}
431 
432 	printf("\n");
433 	printf("TotalMemory = %ld (0x%08lx)\n",
434 	    be32toh(res->TotalMemory) ,be32toh(res->TotalMemory));
435 	printf("GoodMemory  = %ld (0x%08lx)\n",
436 	    be32toh(res->GoodMemory), be32toh(res->GoodMemory));
437 
438 	/*
439 	 * MEM_MAP
440 	 */
441 	printf("\n");
442 	nmseg = be32toh(res->ActualNumMemSegs);
443 	printf("ActualNumMemSegs = %ld\n", nmseg);
444 	mem_map = res->Segs;
445 	for (i = 0; i < ((nmseg > MAX_MEM_SEGS) ? MAX_MEM_SEGS : nmseg); i++) {
446 		unsigned long pc;
447 
448 		printf("%d:\n", i);
449 		l = be32toh(mem_map[i].Usage);
450 		printf("  Usage = ");
451 		for (first = 1, j = 0; j < sizeof(unsigned long) * 8; j++) {
452 			if ((l & (1UL << j)) != 0) {
453 				printf("%s%s", first ? "" : ", ",
454 				    j >= NELEMS(Usage) ? "Unknown" : Usage[j]);
455 				first = 0;
456 			}
457 		}
458 		printf(" (0x%08lx)\n", l);
459 		printf("  BasePage  = 0x%05lx000\n",
460 		    be32toh(mem_map[i].BasePage));
461 		pc = be32toh(mem_map[i].PageCount);
462 		printf("  PageCount = 0x%08lx (%ld page%s)\n",
463 		    page_size * pc, pc, pc == 1 ? "" : "s");
464 	}
465 
466 	/*
467 	 * PPC_MEM
468 	 */
469 	printf("\n");
470 	nmem = be32toh(res->ActualNumMemories);
471 	printf("ActualNumMemories = %ld\n", nmem);
472 	ppc_mem = res->Memories;
473 	for (i = 0; i < ((nmem > MAX_MEMS) ? MAX_MEMS : nmem); i++) {
474 		printf("%d:\n", i);
475 		printf("  SIMMSize = %ld MB\n", be32toh(ppc_mem[i].SIMMSize));
476 	}
477 
478 	/*
479 	 * PPC_DEVICE
480 	 */
481 	printf("\n");
482 	ndev = be32toh(res->ActualNumDevices);
483 	printf("ActualNumDevices = %ld\n", ndev);
484 	ppc_dev = res->Devices;
485 	for (i = 0; i < ((ndev > MAX_DEVICES) ? MAX_DEVICES : ndev); i++) {
486 		DEVICE_ID *id = &ppc_dev[i].DeviceId;
487 		BUS_ACCESS *bus = &ppc_dev[i].BusAccess;
488 
489 		printf("\n%d:\n", i);
490 
491 		printf("  DEVICE_ID\n");
492 		l = be32toh(id->BusId);
493 		printf("    BusId = ");
494 		for (j = 0; j < sizeof(unsigned long) * 8; j++) {
495 			if ((l & (1UL << j)) != 0) {
496 				printf("%s",
497 				    j >= NELEMS(BusId) ? "Unknown" : BusId[j]);
498 				break;
499 			}
500 		}
501 		printf("\n");
502 		pnp_devid_to_string(id->DevId, deviceid);
503 		printf("    DevId = 0x%08lx (%s)\n", id->DevId, deviceid);
504 		printf("    SerialNum = 0x%08lx\n", be32toh(id->SerialNum));
505 		l = be32toh(id->Flags);
506 		printf("    Flags = 0x%08lx\n", l);
507 		for (first = 1, j = 0; j < sizeof(unsigned long) * 8; j++) {
508 			if ((l & (1UL << j)) != 0) {
509 				printf("      : %s\n",
510 				    j >= NELEMS(Flags) ? "Unknown" : Flags[j]);
511 				first = 0;
512 			}
513 		}
514 		if (first)
515 			printf("      : None\n");
516 
517 		bustype_subr(id);
518 
519 		printf("  BUS_ACCESS\n");
520 		printf("    info0 = %d\n", bus->PnPAccess.CSN);
521 		printf("    info1 = %d\n", bus->PnPAccess.LogicalDevNumber);
522 
523 		l = be32toh(ppc_dev[i].AllocatedOffset);
524 		printf("  AllocatedOffset  = 0x%08lx\n", l);
525 		make_pnp_device_tree(res->DevicePnPHeap + l);
526 
527 		l = be32toh(ppc_dev[i].PossibleOffset);
528 		printf("  PossibleOffset   = 0x%08lx\n", l);
529 		make_pnp_device_tree(res->DevicePnPHeap + l);
530 
531 		l = be32toh(ppc_dev[i].CompatibleOffset);
532 		printf("  CompatibleOffset = 0x%08lx\n", l);
533 		make_pnp_device_tree(res->DevicePnPHeap + l);
534 	}
535 }
536 
537 enum {
538 	TAG_SMALL = 0,
539 	TAG_LARGE
540 };
541 
542 /*--
543  * pnp device
544  */
545 static int pnp_small_pkt(void *);
546 static int pnp_large_pkt(void *);
547 
548 static void
make_pnp_device_tree(void * v)549 make_pnp_device_tree(void *v)
550 {
551 	unsigned char *p = v;
552 	int size;
553 
554 	if (p == NULL)
555 		return;
556 
557 	for (; p[0] != END_TAG; p += size) {
558 		if (tag_type(p[0]) == TAG_SMALL)
559 			size = pnp_small_pkt(p);
560 		else
561 			size = pnp_large_pkt(p);
562 	}
563 }
564 
small_vendor_chipid(void * v)565 static void small_vendor_chipid(void *v)
566 {
567 	ChipIDPack *p = v;
568 	char chipid[8];
569 	int16_t id;
570 	int i, j;
571 	struct _svid {
572 		int16_t id;
573 		const char *name;
574 		int type;
575 	} svid[] = {
576 		{ Dakota,	"IBM North/South Dakota", Chip_MemCont },
577 		{ Idaho,	"IBM Idaho", Chip_MemCont },
578 		{ Eagle,	"Motorola Eagle", Chip_MemCont },
579 		{ Kauai_Lanai,	"IBM Kauai/Lanai", Chip_MemCont },
580 		{ Montana_Nevada,"IBM Montana/Nevada", Chip_MemCont },
581 		{ Union,	"IBM Union", Chip_MemCont },
582 		{ Cobra_Viper,	"IBM Cobra/Viper", Chip_MemCont },
583 		{ Grackle,	"Motorola Grackle", Chip_MemCont },
584 		{ SIO_ZB,	"Intel 82378ZB", Chip_ISABridge },
585 		{ FireCoral,	"IBM FireCoral", Chip_ISABridge },
586 		{ Python,	"IBM Python", Chip_PCIBridge },
587 		{ DEC21050,	"PCI-PCI (DEC 21050)", Chip_PCIBridge },
588 		{ IBM2782351,	"PCI-PCI (IBM 2782351)", Chip_PCIBridge },
589 		{ IBM2782352,	"PCI-PCI (IBM 2782352)", Chip_PCIBridge },
590 		{ INTEL_8236SL,	"Intel 8236SL", Chip_PCMCIABridge },
591 		{ RICOH_RF5C366C,"RICOH RF5C366C", Chip_PCMCIABridge },
592 		{ INTEL_82374,	"Intel 82374/82375", Chip_EISABridge },
593 		{ MCACoral,	"MCA Coral", Chip_MCABridge },
594 		{ Cheyenne,	"IBM Cheyenne", Chip_L2Cache },
595 		{ IDT,		"IDT", Chip_L2Cache },
596 		{ Sony1PB,	"Sony1PB", Chip_L2Cache },
597 		{ Mamba,	"IBM Mamba", Chip_L2Cache },
598 		{ Alaska,	"IBM Alaska", Chip_L2Cache },
599 		{ Glance,	"IBM Glance", Chip_L2Cache },
600 		{ Ocelot,	"IBM Ocelot", Chip_L2Cache },
601 		{ Carrera,	"IBM Carrera", Chip_PM },
602 		{ Sig750,	"Signetics 87C750", Chip_PM },
603 		{ MPIC_2,	"IBM MPIC-2", Chip_IntrCont },
604 		{ DallasRTC,	"Dallas 1385 compatible", Chip_MiscPlanar },
605 		{ Dallas1585,	"Dallas 1585 compatible", Chip_MiscPlanar },
606 		{ Timer8254,	"8254-compatible timer", Chip_MiscPlanar },
607 		{ HarddiskLt,	"Op Panel HD light", Chip_MiscPlanar },
608 		{ 0,		NULL, -1 },
609 	};
610 	const char *chiptype[] = {
611 		"Memory Controller",
612 		"ISA Bridge",
613 		"PCI Bridge",
614 		"PCMCIA Bridge",
615 		"EISA Bridge",
616 		"MCA Bridge",
617 		"L2 Cache Controller",
618 		"Power Management Controller",
619 		"Interrupt Controller",
620 		"Misc. Planar Device"
621 	};
622 
623 	id = le16dec(&p->Name[0]);
624 	snprintf(chipid, 8, "%c%c%c%0hX",
625 	    ((p->VendorID0 >> 2) & 0x1f) + 'A' - 1,
626 	    (((p->VendorID0 & 3) << 3) | ((p->VendorID1 >> 5) & 7)) + 'A' - 1,
627 	    (p->VendorID1 & 0x1f) + 'A' - 1, id);
628 	for (i = 0, j = -1; svid[i].name != NULL; i++) {
629 		if (id == svid[i].id) {
630 			j = i;
631 			break;
632 		}
633 	}
634 	printf("Chip ID: %s\n", chipid);
635 	if (j == -1) {
636 		printf("      Unknown Chip Type\n");
637 		return;
638 	}
639 	printf("      %s: %s\n", chiptype[svid[j].type], svid[j].name);
640 	return;
641 }
642 
643 static int
pnp_small_pkt(void * v)644 pnp_small_pkt(void *v)
645 {
646 	int tag = *(unsigned char *)v;
647 	int item, size;
648 	int i, j;
649 	int first;
650 
651 	item = tag_small_item_name(tag);
652 	size = tag_small_count(tag) + 1 /* tag */;
653 
654 	switch (item) {
655 	case CompatibleDevice: {
656 		struct _S3_Pack *p = v;
657 		unsigned char *q = p->CompatId;
658 
659 		printf("    CompatibleDevice = %c%c%c%c%c%c%c\n",
660 		    ((q[0] >> 2) & 0x1f) + 'A' - 1,
661 		    (((q[0] & 0x03) << 3) | ((q[1] >> 5) & 0x07)) + 'A' - 1,
662 		    (q[1] & 0x1f) + 'A' - 1,
663 		    HEXDIGITS[(q[2] >> 4) & 0xf], HEXDIGITS[q[2] & 0xf],
664 		    HEXDIGITS[(q[3] >> 4) & 0xf], HEXDIGITS[q[3] & 0xf]);
665 		}
666 		break;
667 
668 	case IRQFormat: {
669 		struct _S4_Pack *p = v;
670 
671 		printf("    IRQ: ");
672 		for (first = 1, j = 0; j < 2; j++) {
673 			for (i = 0; i < 8; i++) {
674 				if (p->IRQMask[j] & (1 << i)) {
675 					printf("%s%d",
676 					    first ? "" : ", ", j * 8 + i);
677 					first = 0;
678 				}
679 			}
680 		}
681 		if (first)
682 			printf("None ");
683 
684 		if (size == 3) {
685 			static const char *IRQInfo[] = {
686 				"high true edge sensitive",
687 				"low true edge sensitive",
688 				"high true level sensitive",
689 				"low true level sensitive",
690 			};
691 
692 			if (p->IRQInfo & 0xf0)
693 				goto IRQout;
694 
695 			for (first = 1, i = 0; i < NELEMS(IRQInfo); i++) {
696 				if (p->IRQInfo & (1 << i)) {
697 					printf("%s%s", first ? " (" : ", ",
698 					    IRQInfo[i]);
699 					first = 0;
700 				}
701 			}
702 			if (!first)
703 				printf(")");
704 		}
705 IRQout:
706 		printf("\n");
707 		}
708 		break;
709 
710 	case DMAFormat: {
711 		struct _S5_Pack *p = v;
712 
713 		printf("    DMA: ");
714 		for (first = 1, i = 0; i < 8; i++) {
715 			if (p->DMAMask & (1 << i)) {
716 				printf("%s%d", first ? "" : ", ", i);
717 				first = 0;
718 			}
719 		}
720 		printf("%s", first ? "None" : "");
721 
722 		printf("\n");
723 		}
724 		break;
725 
726 	case StartDepFunc:
727 	case EndDepFunc:
728 		break;
729 
730 	case IOPort: {
731 		struct _S8_Pack *p = v;
732 		unsigned short mask;
733 		unsigned short iomin, iomax;
734 		int align, len;
735 
736 		mask = p->IOInfo & ISAAddr16bit ? 0xffff : 0x03ff;
737 		iomin = (p->RangeMin[0] | (p->RangeMin[1] << 8)) & mask;
738 		iomax = (p->RangeMax[0] | (p->RangeMax[1] << 8)) & mask;
739 		align = p->IOAlign;
740 		len = p->IONum;
741 
742 		if (len != 1) {
743 			if (iomin == iomax)
744 				printf("    IOPort: 0x%x-0x%x",
745 				    iomin, iomin + len-1);
746 			else
747 				printf("    IOPort: min 0x%x-0x%x,"
748 				    " max 0x%x-0x%x (%d byte%s align)",
749 				      iomin, iomin + len-1,
750 				      iomax, iomax + len-1,
751 				      align, align != 1 ? "s" : "");
752 		} else {
753 			if (iomin == iomax)
754 				printf("    IOPort: 0x%x", iomin);
755 			else
756 				printf("    IOPort: min 0x%x, max 0x%x"
757 				    " (%d byte%s align)",
758 				      iomin, iomax,
759 				      align, align != 1 ? "s" : "");
760 		}
761 		printf("\n");
762 		}
763 		break;
764 
765 	case FixedIOPort: {
766 		struct _S9_Pack *p = v;
767 		unsigned short ioport;
768 		int len;
769 
770 		ioport = (p->Range[0] | (p->Range[1] << 8)) & 0x3ff;
771 		len = p->IONum;
772 
773 		if (len != 1)
774 			printf("    FixedIOPort: 0x%x-0x%x",
775 			    ioport, ioport + len - 1);
776 		else
777 			printf("    FixedIOPort: 0x%x", ioport);
778 		printf("\n");
779 		}
780 		break;
781 
782 	case SmallVendorItem: {
783 		unsigned char *p = v;
784 
785 		printf("    SmallVendorItem: ");
786 		switch (p[1]) {
787 		case 1:
788 			small_vendor_chipid(v);
789 			break;
790 
791 		case 3:
792 			printf("Processor Number: %d\n", p[2]);
793 			break;
794 
795 		default:
796 			printf("\n");
797 			for (i = 0; i < size - 1; i++) {
798 				if ((i % 16) == 0)
799 					printf("      ");
800 				printf("%02x ", p[i + 1]);
801 				if ((i % 16) == 15)
802 					printf("\n");
803 			}
804 			if ((i % 16) != 0)
805 				printf("\n");
806 			break;
807 		}
808 		break;
809 	}
810 	default: {
811 		unsigned char *p = v;
812 
813 		printf("small\n");
814 		printf("item = %d\n", item);
815 		printf("size = %d\n", size);
816 
817 		for (i = 1; i < size; i++)
818 			printf("%02x ", p[i]);
819 		printf("\n");
820 		}
821 		break;
822 	}
823 
824 	return size;
825 }
826 
827 /*
828  * large vendor items
829  */
830 
831 static void large_vendor_default_subr(struct _L4_PPCPack *p, void *v, int size);
832 static void large_vendor_floppy_subr(struct _L4_PPCPack *p, void *v, int size);
833 static void large_vendor_l2cache_subr(struct _L4_PPCPack *p, void *v, int size);
834 static void large_vendor_pcibridge_subr(struct _L4_PPCPack *p, void *v,
835     int size);
836 static void large_vendor_bat_subr(struct _L4_PPCPack *p, void *v, int size);
837 static void large_vendor_bba_subr(struct _L4_PPCPack *p, void *v, int size);
838 static void large_vendor_scsi_subr(struct _L4_PPCPack *p, void *v, int size);
839 static void large_vendor_pms_subr(struct _L4_PPCPack *p, void *v, int size);
840 static void large_vendor_gaddr_subr(struct _L4_PPCPack *p, void *v, int size);
841 static void large_vendor_isaintr_subr(struct _L4_PPCPack *p, void *v, int size);
842 
843 static void
large_vendor_default_subr(struct _L4_PPCPack * p,void * v,int size)844 large_vendor_default_subr(struct _L4_PPCPack *p, void *v, int size)
845 {
846 	int i;
847 
848 	for (i = 0; i < size - 3; i++) {
849 		if ((i % 16) == 0)
850 			printf("      ");
851 		printf("%02x ", p->PPCData[i]);
852 		if ((i % 16) == 15)
853 			printf("\n");
854 	}
855 	if ((i % 16) != 0)
856 		printf("\n");
857 }
858 
859 static void
large_vendor_floppy_subr(struct _L4_PPCPack * p,void * v,int size)860 large_vendor_floppy_subr(struct _L4_PPCPack *p, void *v, int size)
861 {
862 	int i;
863 	const char *str;
864 
865 	for (i = 0; i < (size - 4) / 2; i++) {
866 		switch (p->PPCData[i*2]) {
867 		case 0:
868 			str = "Not present";
869 			break;
870 		case 1:
871 			str = "3.5\" 2MiB";
872 			break;
873 		case 2:
874 			str = "3.5\" 4MiB";
875 			break;
876 		case 3:
877 			str = "5.25\" 1.6MiB";
878 			break;
879 		default:
880 			str = "Unknown type";
881 			break;
882 		}
883 		printf("      Floppy drive %d, %s", i, str);
884 		if (p->PPCData[i*2 + 1] & 0x01)
885 			printf(", Media sense");
886 		if (p->PPCData[i*2 + 1] & 0x02)
887 			printf(", Auto eject");
888 		if (p->PPCData[i*2 + 1] & 0x04)
889 			printf(", Alt speed");
890 		printf("\n");
891 	}
892 }
893 
894 static void
large_vendor_l2cache_subr(struct _L4_PPCPack * p,void * v,int size)895 large_vendor_l2cache_subr(struct _L4_PPCPack *p, void *v, int size)
896 {
897 	static const unsigned char *L2type[] =
898 	    { "None", "WriteThru", "CopyBack" };
899 	static const unsigned char *L2assoc[] =
900 	    { "None", "DirectMapped", "2-way set" };
901 	static const unsigned char *L2hw[] =
902 	    { "None", "Invalidate", "Flush", "Unknown" };
903 
904 	printf("      %u K %s %s %s L2 cache\n"
905 	    "\t%hd/%hd bytes line/sector size\n",
906 	    le32dec(&p->PPCData[0]), L2type[p->PPCData[10]],
907 	    L2assoc[le16dec(&p->PPCData[4])],
908 	    L2hw[p->PPCData[11]], le16dec(&p->PPCData[6]),
909 	    le16dec(&p->PPCData[8]));
910 }
911 
912 static void
large_vendor_pcibridge_subr(struct _L4_PPCPack * p,void * v,int size)913 large_vendor_pcibridge_subr(struct _L4_PPCPack *p, void *v, int size)
914 {
915 	int i, numslots;
916 	char tmpstr[30];
917 	PCIInfoPack *pi = v;
918 	static const unsigned char *intrtype[] =
919 	    { "8259", "MPIC", "RS6k BUID %d" };
920 
921 	/* rev 0 residual has no valid pcibridge data */
922 	if (res->Revision == 0) {
923 		large_vendor_default_subr(p, v, size);
924 		return;
925 	}
926 	numslots = (le16dec(&pi->count0)-21)/sizeof(IntrMap);
927 
928 	printf("    PCI Bridge parameters\n"
929 	    "      ConfigBaseAddress 0x%0" PRIx64" \n"
930 	    "      ConfigBaseData 0x%0" PRIx64 "\n"
931 	    "      Bus number %d\n",
932 	    le64dec(&pi->configbaseaddr), le64dec(&pi->configbasedata),
933 	    pi->busnum);
934 
935 	printf("    PCI Bridge Slot Data\n");
936 	for (i = 0; i < numslots; i++) {
937 		int j, first, l;
938 		char *t;
939 
940 		if (pi->map[i].slotnum)
941 			printf("      PCI Slot %d", pi->map[i].slotnum);
942 		else
943 			printf("      Integrated PCI device");
944 		printf(" DevFunc 0x%02x\n", pi->map[i].devfunc);
945 		for (j = 0, first = 1, t = tmpstr; j < MAX_PCI_INTRS; j++) {
946 			if (pi->map[i].intr[j] != 0xFFFF) {
947 				if (first)
948 					first = 0;
949 				else
950 					*t++ = '/';
951 				*t++ = 'A' + j;
952 			}
953 		}
954 		*t = '\0';
955 		if (first)
956 			continue; /* there were no valid intrs */
957 		printf("        interrupt line(s) %s routed to", tmpstr);
958 		snprintf(tmpstr, sizeof(tmpstr),
959 		    intrtype[pi->map[i].intrctrltype - 1],
960 		    pi->map[i].intrctrlnum);
961 		printf(" %s line(s) ", tmpstr);
962 		for (j = 0, first = 1, l = 0; j < MAX_PCI_INTRS; j++) {
963 			int line = bswap16(pi->map[i].intr[j]);
964 
965 			if (pi->map[i].intr[j] != 0xFFFF) {
966 				l += snprintf(tmpstr + l, sizeof(tmpstr) - l,
967 				    "%s%d(%c)", l == 0 ? "/" : "",
968 				    line & 0x7fff, line & 0x8000 ? 'E' : 'L');
969 				if (l > sizeof(tmpstr))
970 					break;
971 			}
972 		}
973 		printf("%s\n", tmpstr);
974 	}
975 }
976 
977 static void
large_vendor_bat_subr(struct _L4_PPCPack * p,void * v,int size)978 large_vendor_bat_subr(struct _L4_PPCPack *p, void *v, int size)
979 {
980 	static const unsigned char *convtype[] =
981 	    { "Bus Memory", "Bus I/O", "DMA" };
982 	static const unsigned char *transtype[] =
983 	    { "direct", "mapped", "PPC special storage segment" };
984 
985 	printf("      Bridge address translation, %s decoding:\n"
986 	    "      Parent Base\tBus Base\tRange\t   Conversion\tTranslation\n"
987 	    "      0x%8.8" PRIx64 "\t0x%8.8" PRIx64 "\t0x%8.8" PRIx64
988 	    " %s%s%s\n",
989 	    p->PPCData[0] & 1 ? "positive" : "subtractive",
990 	    le64dec(&p->PPCData[4]), le64dec(&p->PPCData[12]),
991 	    le64dec(&p->PPCData[20]), convtype[p->PPCData[2] - 1],
992 	    p->PPCData[2] == 3 ? "\t\t" : "\t",
993 	    transtype[p->PPCData[1] - 1]);
994 }
995 
996 static void
large_vendor_bba_subr(struct _L4_PPCPack * p,void * v,int size)997 large_vendor_bba_subr(struct _L4_PPCPack *p, void *v, int size)
998 {
999 	printf("      Bus speed %ld Hz, %d slot(s)\n",
1000 	    (long)le32dec(&p->PPCData), p->PPCData[4]);
1001 }
1002 
1003 static void
large_vendor_scsi_subr(struct _L4_PPCPack * p,void * v,int size)1004 large_vendor_scsi_subr(struct _L4_PPCPack *p, void *v, int size)
1005 {
1006 	int i;
1007 
1008 	printf("    SCSI buses: %d id(s):", p->PPCData[0]);
1009 	for (i = 1; i <= p->PPCData[0]; i++)
1010 		printf("\t\t\t%d%c", p->PPCData[i],
1011 		    i == p->PPCData[0] ? '\n' : ',');
1012 }
1013 
1014 static void
large_vendor_pms_subr(struct _L4_PPCPack * p,void * v,int size)1015 large_vendor_pms_subr(struct _L4_PPCPack *p, void *v, int size)
1016 {
1017 	unsigned int flags;
1018 	int i;
1019 	static const unsigned char *power[] = {
1020 	    "Hibernation", "Suspend", "Laptop lid events", "Laptop battery",
1021 	    "Modem-triggered resume from hibernation",
1022 	    "Modem-triggered resume from suspend",
1023 	    "Timer-triggered resume from hibernation",
1024 	    "Timer-triggered resume from suspend",
1025 	    "Timer-triggered hibernation from suspend",
1026 	    "Software-controlled power switch", "External resume trigger",
1027 	    "Software main power switch can be overridden by hardware",
1028 	    "Resume button", "Automatic transition between states is inhibited"
1029 	};
1030 
1031 	printf("      Power management attributes:");
1032 	flags = le32dec(&p->PPCData);
1033 	if (!flags) {
1034 		printf(" (none)\n");
1035 		return;
1036 	}
1037 	printf("\n");
1038 	for (i = 0; i < 14; i++)
1039 		if (flags & 1 << i)
1040 			printf("\t%s\n", power[i]);
1041 	if (flags & 0xffffc000)
1042 		printf("\tunknown flags (0x%8.8x)\n", flags);
1043 }
1044 
1045 static void
large_vendor_gaddr_subr(struct _L4_PPCPack * p,void * v,int size)1046 large_vendor_gaddr_subr(struct _L4_PPCPack *p, void *v, int size)
1047 {
1048 	static const unsigned char *addrtype[] = { "I/O", "Memory", "System" };
1049 
1050 	printf("      %s address (%d bits), at 0x%" PRIx64 " size 0x%"
1051 	    PRIx64 " bytes\n", addrtype[p->PPCData[0] - 1], p->PPCData[1],
1052 	    le64dec(&p->PPCData[4]), le64dec(&p->PPCData[12]));
1053 }
1054 
1055 static void
large_vendor_isaintr_subr(struct _L4_PPCPack * p,void * v,int size)1056 large_vendor_isaintr_subr(struct _L4_PPCPack *p, void *v, int size)
1057 {
1058 	int i;
1059 	char tmpstr[30];
1060 	static const unsigned char *inttype[] =
1061 	    { "8259", "MPIC", "RS6k BUID %d" };
1062 
1063 	snprintf(tmpstr, sizeof(tmpstr), inttype[p->PPCData[0] - 1],
1064 	    p->PPCData[1]);
1065 	printf("      ISA interrupts routed to %s lines\n\t", tmpstr);
1066 
1067 	for (i = 0; i < 16; i++) {
1068 		int line = le16dec(&p->PPCData[2 + 2*i]);
1069 
1070 		if (line != 0xffff)
1071 			printf(" %d(IRQ%d)", line, i);
1072 		if (i == 8)
1073 			printf("\n\t");
1074 	}
1075 	printf("\n");
1076 }
1077 
1078 static int
pnp_large_pkt(void * v)1079 pnp_large_pkt(void *v)
1080 {
1081 	int tag = *(unsigned char *)v;
1082 	unsigned char *q = v;
1083 	int item, size;
1084 	int i;
1085 	static struct large_vendor_type {
1086 		const char	*str;
1087 		void	(*func)(struct _L4_PPCPack *p, void *vv, int sz);
1088 	} Large_Vendor_Type[] = {
1089 		{ "None",			NULL },
1090 		{ "Diskette Drive",		large_vendor_floppy_subr },
1091 		{ "L2 Cache",			large_vendor_l2cache_subr },
1092 		{ "PCI Bridge",			large_vendor_pcibridge_subr },
1093 		{ "Display",			large_vendor_default_subr },
1094 		{ "Bridge Address Translation",	large_vendor_bat_subr },
1095 		{ "Bus Bridge Attributes",	large_vendor_bba_subr },
1096 		{ "SCSI Controller Information",large_vendor_scsi_subr },
1097 		{ "Power Management Support",	large_vendor_pms_subr },
1098 		{ "Generic Address",		large_vendor_gaddr_subr },
1099 		{ "ISA Bridge Information",	large_vendor_isaintr_subr },
1100 		{ "Video Channels",		large_vendor_default_subr },
1101 		{ "Power Control",		large_vendor_default_subr },
1102 		{ "Memory SIMM PD Data",	large_vendor_default_subr },
1103 		{ "System Interrupts",		large_vendor_default_subr },
1104 		{ "Error Log",			large_vendor_default_subr },
1105 		{ "Extended VPD",		large_vendor_default_subr },
1106 		{ "Timebase Control",		large_vendor_default_subr },
1107 	};
1108 
1109 	item = tag_large_item_name(tag);
1110 	size = (q[1] | (q[2] << 8)) + 3 /* tag + length */;
1111 
1112 	switch (item) {
1113 	case LargeVendorItem: {
1114 		struct _L4_Pack *pack = v;
1115 		struct _L4_PPCPack *p =  &pack->L4_Data.L4_PPCPack;
1116 
1117 		printf("    LargeVendorItem: %s\n",
1118 		    Large_Vendor_Type[p->Type].str);
1119 		if (p->Type <= 17 && Large_Vendor_Type[p->Type].func != NULL)
1120 			(*Large_Vendor_Type[p->Type].func)(p, v, size);
1121 		break;
1122 	}
1123 	case MemoryRange: {
1124 		struct _L1_Pack *pack = v;
1125 
1126 		printf("    Memory Range:\n");
1127 		if (pack->Data[0] & L1_Shadow)
1128 			printf("      Memory is shadowable\n");
1129 		if (pack->Data[0] & L1_32bit_mem)
1130 			printf("      32-bit memory only\n");
1131 		if (pack->Data[0] & L1_8_16bit_mem)
1132 			printf("      8-bit and 16-bit supported\n");
1133 		if (pack->Data[0] & L1_Decode_Hi)
1134 			printf("      decode supports high address\n");
1135 		if (pack->Data[0] & L1_Cache)
1136 			printf("      read cacheable, write-through\n");
1137 		if (pack->Data[0] & L1_Writable)
1138 			printf("      Memory is writable\n");
1139 
1140 		if (pack->Count0 >= 0x9) {
1141 			printf("      minbase : 0x%x\n",
1142 			    (pack->Data[2] << 16) | (pack->Data[1] << 8));
1143 			printf("      maxbase : 0x%x\n",
1144 			    (pack->Data[4] << 16) | (pack->Data[3] << 8));
1145 			printf("      align   : 0x%x\n",
1146 			    (pack->Data[6] << 8) | pack->Data[5]);
1147 			printf("      length  : 0x%x\n",
1148 			    (pack->Data[8] << 16) | (pack->Data[7] << 8));
1149 		}
1150 		break;
1151 	}
1152 
1153 	default: {
1154 		unsigned char *p = v;
1155 
1156 		printf("large\n");
1157 		printf("item = %d\n", item);
1158 		printf("size = %d\n", size);
1159 
1160 		for (i = 3; i < size; i++)
1161 			printf("%02x ", p[i]);
1162 		printf("\n");
1163 		}
1164 		break;
1165 	}
1166 
1167 	return size;
1168 }
1169 
1170 /*--
1171  * bus type
1172  */
1173 static void mass_subr(DEVICE_ID *);
1174 static void nic_subr(DEVICE_ID *);
1175 static void display_subr(DEVICE_ID *);
1176 static void mm_subr(DEVICE_ID *);
1177 static void mem_subr(DEVICE_ID *);
1178 static void bridge_subr(DEVICE_ID *);
1179 static void comm_subr(DEVICE_ID *);
1180 static void sys_subr(DEVICE_ID *);
1181 static void input_subr(DEVICE_ID *);
1182 static void service_subr(DEVICE_ID *);
1183 
1184 static void
bustype_subr(DEVICE_ID * id)1185 bustype_subr(DEVICE_ID *id)
1186 {
1187 	static struct bustype {
1188 		const char	*str;
1189 		void	(*func)(DEVICE_ID *);
1190 	} BaseType[] = {
1191 		{ "Reserved"			, NULL },
1192 		{ "MassStorageDevice"		, mass_subr },
1193 		{ "NetworkInterfaceController"	, nic_subr },
1194 		{ "DisplayController"		, display_subr },
1195 		{ "MultimediaController"	, mm_subr },
1196 		{ "MemoryController"		, mem_subr },
1197 		{ "BridgeController"		, bridge_subr },
1198 		{ "CommunicationsDevice"	, comm_subr },
1199 		{ "SystemPeripheral"		, sys_subr },
1200 		{ "InputDevice"			, input_subr },
1201 		{ "ServiceProcessor"		, service_subr },
1202 	};
1203 	int type;
1204 
1205 	type = (id->BaseType >= NELEMS(BaseType)) ? 0 : id->BaseType;
1206 
1207 	printf("    BaseType = %s (%d)\n", BaseType[type].str, id->BaseType);
1208 	if (BaseType[type].func != NULL)
1209 		(*BaseType[type].func)(id);
1210 }
1211 
1212 static void
mass_subr(DEVICE_ID * id)1213 mass_subr(DEVICE_ID *id)
1214 {
1215 	static const char *IDEController_tabel[] = {
1216 		"GeneralIDE",
1217 		"ATACompatible",
1218 	};
1219 	static const char *FloppyController_table[] = {
1220 		"GeneralFloppy",
1221 		"Compatible765",
1222 		"NS398_Floppy",
1223 		"NS26E_Floppy",
1224 		"NS15C_Floppy",
1225 		"NS2E_Floppy",
1226 		"CHRP_Floppy",
1227 	};
1228 	const char *p, *q = NULL;
1229 
1230 	switch (id->SubType) {
1231 	case SCSIController:
1232 		p = "SCSIController";
1233 		q = "GeneralSCSI";
1234 		break;
1235 	case IDEController:
1236 		p = "IDEController";
1237 		q = id->Interface >= NELEMS(IDEController_tabel)
1238 		    ? NULL : IDEController_tabel[id->Interface];
1239 		break;
1240 	case FloppyController:
1241 		p = "FloppyController";
1242 		q = id->Interface >= NELEMS(FloppyController_table)
1243 		    ? NULL : FloppyController_table[id->Interface];
1244 		break;
1245 	case IPIController:
1246 		p = "IPIController";
1247 		q = "GeneralIPI";
1248 		break;
1249 	case OtherMassStorageController:
1250 		p = "OtherMassStorageController";
1251 		break;
1252 	default:
1253 		p = "UnknownStorageController";
1254 		break;
1255 	}
1256 
1257 	printf("    SubType = %s (%d)\n", p, id->SubType);
1258 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1259 }
1260 
1261 static void
nic_subr(DEVICE_ID * id)1262 nic_subr(DEVICE_ID *id)
1263 {
1264 	const char *p, *q = NULL;
1265 
1266 	switch (id->SubType) {
1267 	case EthernetController:
1268 		p = "EthernetController";
1269 		q = "GeneralEther";
1270 		break;
1271 	case TokenRingController:
1272 		p = "TokenRingController";
1273 		q = "GeneralToken";
1274 		break;
1275 	case FDDIController:
1276 		p = "FDDIController";
1277 		q = "GeneralFDDI";
1278 		break;
1279 	case OtherNetworkController:
1280 		p = "OtherNetworkController";
1281 		break;
1282 	default:
1283 		p = "UnknownNetworkController";
1284 		break;
1285 	}
1286 
1287 	printf("    SubType = %s (%d)\n", p, id->SubType);
1288 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1289 }
1290 
1291 static void
display_subr(DEVICE_ID * id)1292 display_subr(DEVICE_ID *id)
1293 {
1294 	const char *p, *q = NULL;
1295 
1296 	switch (id->SubType) {
1297 	case VGAController:
1298 		p = "VGAController";
1299 		q = "GeneralVGA";
1300 		break;
1301 	case SVGAController:
1302 		p = "SVGAController";
1303 		q = "GeneralSVGA";
1304 		break;
1305 	case XGAController:
1306 		p = "XGAController";
1307 		q = "GeneralXGA";
1308 		break;
1309 	case OtherDisplayController:
1310 		p = "OtherDisplayController";
1311 		break;
1312 	default:
1313 		p = "UnknownDisplayController";
1314 		break;
1315 	}
1316 
1317 	printf("    SubType = %s (%d)\n", p, id->SubType);
1318 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1319 }
1320 
1321 static void
mm_subr(DEVICE_ID * id)1322 mm_subr(DEVICE_ID *id)
1323 {
1324 	static const char *AudioController_table[] = {
1325 		"GeneralAudio",
1326 		"CS4232Audio",
1327 	};
1328 	const char *p, *q = NULL;
1329 
1330 	switch (id->SubType) {
1331 	case VideoController:
1332 		p = "VideoController";
1333 		q = "GeneralVideo";
1334 		break;
1335 	case AudioController:
1336 		p = "AudioController";
1337 		q = id->Interface >= NELEMS(AudioController_table)
1338 		    ? NULL : AudioController_table[id->Interface];
1339 		break;
1340 	case OtherMultimediaController:
1341 		p = "OtherMultimediaController";
1342 		break;
1343 	default:
1344 		p = "UnknownMultimediaController";
1345 		break;
1346 	}
1347 
1348 	printf("    SubType = %s (%d)\n", p, id->SubType);
1349 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1350 }
1351 
1352 static void
mem_subr(DEVICE_ID * id)1353 mem_subr(DEVICE_ID *id)
1354 {
1355 	const char *p, *q = NULL;
1356 
1357 	switch (id->SubType) {
1358 	case RAM:
1359 		p = "RAM";
1360 		q = "GeneralRAM";
1361 		break;
1362 	case FLASH:
1363 		p = "FLASH";
1364 		q = "GeneralFLASH";
1365 		break;
1366 	case OtherMemoryDevice:
1367 		p = "OtherMemoryDevice";
1368 		break;
1369 	default:
1370 		p = "UnknownMemoryDevice";
1371 		break;
1372 	}
1373 
1374 	printf("    SubType = %s (%d)\n", p, id->SubType);
1375 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1376 }
1377 
1378 static void
bridge_subr(DEVICE_ID * id)1379 bridge_subr(DEVICE_ID *id)
1380 {
1381 	static const char *PCIBridge_table[] = {
1382 		"GeneralPCIBridge",
1383 		"PCIBridgeIndirect",
1384 		"PCIBridgeRS6K",
1385 	};
1386 	const char *p, *q = NULL;
1387 
1388 	switch (id->SubType) {
1389 	case HostProcessorBridge:
1390 		p = "HostProcessorBridge";
1391 		q = "GeneralHostBridge";
1392 		break;
1393 	case ISABridge:
1394 		p = "ISABridge";
1395 		q = "GeneralISABridge";
1396 		break;
1397 	case EISABridge:
1398 		p = "EISABridge";
1399 		q = "GeneralEISABridge";
1400 		break;
1401 	case MicroChannelBridge:
1402 		p = "MicroChannelBridge";
1403 		q = "GeneralMCABridge";
1404 		break;
1405 	case PCIBridge:
1406 		p = "PCIBridge";
1407 		q = id->Interface >= NELEMS(PCIBridge_table)
1408 		    ? NULL : PCIBridge_table[id->Interface];
1409 		break;
1410 	case PCMCIABridge:
1411 		p = "PCMCIABridge";
1412 		q = "GeneralPCMCIABridge";
1413 		break;
1414 	case VMEBridge:
1415 		p = "VMEBridge";
1416 		q = "GeneralVMEBridge";
1417 		break;
1418 	case OtherBridgeDevice:
1419 		p = "OtherBridgeDevice";
1420 		break;
1421 	default:
1422 		p = "UnknownBridgeDevice";
1423 		break;
1424 	}
1425 
1426 	printf("    SubType = %s (%d)\n", p, id->SubType);
1427 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1428 }
1429 
1430 static void
comm_subr(DEVICE_ID * id)1431 comm_subr(DEVICE_ID *id)
1432 {
1433 	static const char *RS232Device_table[] = {
1434 		"GeneralRS232",
1435 		"COMx",
1436 		"Compatible16450",
1437 		"Compatible16550",
1438 		"NS398SerPort",
1439 		"NS26ESerPort",
1440 		"NS15CSerPort",
1441 		"NS2ESerPort",
1442 	};
1443 	static const char *ATCompatibleParallelPort_table[] = {
1444 		"GeneralParPort",
1445 		"LPTx",
1446 		"NS398ParPort",
1447 		"NS26EParPort",
1448 		"NS15CParPort",
1449 		"NS2EParPort",
1450 	};
1451 	const char *p, *q = NULL;
1452 
1453 	switch (id->SubType) {
1454 	case RS232Device:
1455 		p = "RS232Device";
1456 		q = id->Interface >= NELEMS(RS232Device_table)
1457 		    ? NULL : RS232Device_table[id->Interface];
1458 		break;
1459 	case ATCompatibleParallelPort:
1460 		p = "ATCompatibleParallelPort";
1461 		q = id->Interface >= NELEMS(ATCompatibleParallelPort_table)
1462 		    ? NULL : ATCompatibleParallelPort_table[id->Interface];
1463 		break;
1464 	case OtherCommunicationsDevice:
1465 		p = "OtherCommunicationsDevice";
1466 		break;
1467 	default:
1468 		p = "UnknownCommunicationsDevice";
1469 		break;
1470 	}
1471 
1472 	printf("    SubType = %s (%d)\n", p, id->SubType);
1473 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1474 }
1475 
1476 static void
sys_subr(DEVICE_ID * id)1477 sys_subr(DEVICE_ID *id)
1478 {
1479 	static const char *PIC_table[] = {
1480 		"GeneralPIC",
1481 		"ISA_PIC",
1482 		"EISA_PIC",
1483 		"MPIC",
1484 		"RS6K_PIC",
1485 	};
1486 	static const char *DMAController_table[] = {
1487 		"GeneralDMA",
1488 		"ISA_DMA",
1489 		"EISA_DMA",
1490 	};
1491 	static const char *SystemTimer_table[] = {
1492 		"GeneralTimer",
1493 		"ISA_Timer",
1494 		"EISA_Timer",
1495 	};
1496 	static const char *RealTimeClock_table[] = {
1497 		"GeneralRTC",
1498 		"ISA_RTC",
1499 	};
1500 	static const char *L2Cache_table[] = {
1501 		"None",
1502 		"StoreThruOnly",
1503 		"StoreInEnabled",
1504 		"RS6KL2Cache",
1505 	};
1506 	static const char *NVRAM_table[] = {
1507 		"IndirectNVRAM",
1508 		"DirectNVRAM",
1509 		"IndirectNVRAM24",
1510 	};
1511 	static const char *PowerManagement_table[] = {
1512 		"GeneralPowerManagement",
1513 		"EPOWPowerManagement",
1514 		"PowerControl",
1515 	};
1516 	static const char *GraphicAssist_table[] = {
1517 		"Unknown",
1518 		"TransferData",
1519 		"IGMC32",
1520 		"IGMC64",
1521 	};
1522 	static const char *OperatorPanel_table[] = {
1523 		"GeneralOPPanel",
1524 		"HarddiskLight",
1525 		"CDROMLight",
1526 		"PowerLight",
1527 		"KeyLock",
1528 		"ANDisplay",
1529 		"SystemStatusLED",
1530 		"CHRP_SystemStatusLED",
1531 	};
1532 	const char *p, *q = NULL;
1533 
1534 	switch (id->SubType) {
1535 	case ProgrammableInterruptController:
1536 		p = "ProgrammableInterruptController";
1537 		q = id->Interface >= NELEMS(PIC_table)
1538 		    ? NULL : PIC_table[id->Interface];
1539 		break;
1540 	case DMAController:
1541 		p = "DMAController";
1542 		q = id->Interface >= NELEMS(DMAController_table)
1543 		    ? NULL : DMAController_table[id->Interface];
1544 		break;
1545 	case SystemTimer:
1546 		p = "SystemTimer";
1547 		q = id->Interface >= NELEMS(SystemTimer_table)
1548 		    ? NULL : SystemTimer_table[id->Interface];
1549 		break;
1550 	case RealTimeClock:
1551 		p = "RealTimeClock";
1552 		q = id->Interface >= NELEMS(RealTimeClock_table)
1553 		    ? NULL : RealTimeClock_table[id->Interface];
1554 		break;
1555 	case L2Cache:
1556 		p = "L2Cache";
1557 		q = id->Interface >= NELEMS(L2Cache_table)
1558 		    ? NULL : L2Cache_table[id->Interface];
1559 		break;
1560 	case NVRAM:
1561 		p = "NVRAM";
1562 		q = id->Interface >= NELEMS(NVRAM_table)
1563 		    ? NULL : NVRAM_table[id->Interface];
1564 		break;
1565 	case PowerManagement:
1566 		p = "PowerManagement";
1567 		q = id->Interface >= NELEMS(PowerManagement_table)
1568 		    ? NULL : PowerManagement_table[id->Interface];
1569 		break;
1570 	case CMOS:
1571 		p = "CMOS";
1572 		q = "GeneralCMOS";
1573 		break;
1574 	case OperatorPanel:
1575 		p = "OperatorPanel";
1576 		q = id->Interface >= NELEMS(OperatorPanel_table)
1577 		    ? NULL : OperatorPanel_table[id->Interface];
1578 		break;
1579 	case ServiceProcessorClass1:
1580 		p = "ServiceProcessorClass1";
1581 		q = "GeneralServiceProcessor";
1582 		break;
1583 	case ServiceProcessorClass2:
1584 		p = "ServiceProcessorClass2";
1585 		q = "GeneralServiceProcessor";
1586 		break;
1587 	case ServiceProcessorClass3:
1588 		p = "ServiceProcessorClass3";
1589 		q = "GeneralServiceProcessor";
1590 		break;
1591 	case GraphicAssist:
1592 		p = "GraphicAssist";
1593 		q = id->Interface >= NELEMS(GraphicAssist_table)
1594 		    ? NULL : GraphicAssist_table[id->Interface];
1595 		break;
1596 	case SystemPlanar:
1597 		p = "SystemPlanar";
1598 		q = "GeneralSystemPlanar";
1599 		break;
1600 	case OtherSystemPeripheral:
1601 		p = "OtherSystemPeripheral";
1602 		break;
1603 	default:
1604 		p = "UnknownSystemPeripheral";
1605 		break;
1606 	}
1607 
1608 	printf("    SubType = %s (%d)\n", p, id->SubType);
1609 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1610 }
1611 
1612 static void
input_subr(DEVICE_ID * id)1613 input_subr(DEVICE_ID *id)
1614 {
1615 	const char *p, *q = NULL;
1616 
1617 	switch (id->SubType) {
1618 	case KeyboardController:
1619 		p = "KeyboardController";
1620 		break;
1621 	case Digitizer:
1622 		p = "Digitizer";
1623 		break;
1624 	case MouseController:
1625 		p = "MouseController";
1626 		break;
1627 	case TabletController:
1628 		p = "TabletController";
1629 		break;
1630 	case OtherInputController:
1631 		p = "OtherInputController";
1632 		break;
1633 	default:
1634 		p = "UnknownInputController";
1635 		break;
1636 	}
1637 
1638 	printf("    SubType = %s (%d)\n", p, id->SubType);
1639 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1640 }
1641 
1642 static void
service_subr(DEVICE_ID * id)1643 service_subr(DEVICE_ID *id)
1644 {
1645 	const char *p, *q = NULL;
1646 
1647 	switch (id->SubType) {
1648 	case ServiceProcessorClass1:
1649 		p = "ServiceProcessorClass1";
1650 		break;
1651 	case ServiceProcessorClass2:
1652 		p = "ServiceProcessorClass2";
1653 		break;
1654 	case ServiceProcessorClass3:
1655 		p = "ServiceProcessorClass3";
1656 		break;
1657 	default:
1658 		p = "UnknownServiceProcessor";
1659 		break;
1660 	}
1661 
1662 	printf("    SubType = %s (%d)\n", p, id->SubType);
1663 	printf("    Interface = %s (%d)\n", q ? q : "None", id->Interface);
1664 }
1665 
1666 #endif /* RESIDUAL_DATA_DUMP */
1667