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