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 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 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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