From 209d9675086fcc86ae89c2b93b6ba45b7038d7d3 Mon Sep 17 00:00:00 2001 From: beveloper Date: Tue, 30 Sep 2003 19:34:50 +0000 Subject: [PATCH] added decoding of PCI class included use of PCI Header file with vendor/device information git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4876 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/bus_managers/pci/pci_info.cpp | 488 +++++++++++++++++- 1 file changed, 480 insertions(+), 8 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/pci/pci_info.cpp b/src/add-ons/kernel/bus_managers/pci/pci_info.cpp index 1f15ef85b8..b1fe45b87b 100644 --- a/src/add-ons/kernel/bus_managers/pci/pci_info.cpp +++ b/src/add-ons/kernel/bus_managers/pci/pci_info.cpp @@ -1,17 +1,24 @@ #include #include +#include #include "pci_info.h" #include "pci.h" - -#define USE_PCI_HEADER 0 +#define PCI_VERBOSE 1 +#define USE_PCI_HEADER 1 #if USE_PCI_HEADER #include "pcihdr.h" #endif +void print_bridge_info(pci_info *info, bool verbose); +void print_generic_info(pci_info *info, bool verbose); +void print_info_basic(pci_info *info, bool verbose); +void get_vendor_info(uint16 vendorID, const char **venShort, const char **venFull); +void get_device_info(uint16 vendorID, uint16 deviceID, const char **devShort, const char **devFull); +const char *get_class_info(uint8 class_base, uint8 class_sub, uint8 class_api); void -print_bridge_info(pci_info *info) +print_bridge_info(pci_info *info, bool verbose) { dprintf("PCI: primary_bus %02x, secondary_bus %02x, subordinate_bus %02x, secondary_latency %02x\n", info->u.h1.primary_bus, info->u.h1.secondary_bus, info->u.h1.subordinate_bus, info->u.h1.secondary_latency); @@ -35,7 +42,7 @@ print_bridge_info(pci_info *info) } void -print_generic_info(pci_info *info) +print_generic_info(pci_info *info, bool verbose) { dprintf("PCI: ROM base host %08x, pci %08x, size %08x\n", info->u.h0.rom_base, info->u.h0.rom_base_pci, info->u.h0.rom_size); @@ -50,20 +57,45 @@ print_generic_info(pci_info *info) } void -print_info_basic(pci_info *info) +print_info_basic(pci_info *info, bool verbose) { dprintf("PCI: bus %2d, device %2d, function %2d: vendor %04x, device %04x, revision %02x\n", info->bus, info->device, info->function, info->vendor_id, info->device_id, info->revision); dprintf("PCI: class_base %02x, class_function %02x, class_api %02x\n", info->class_base, info->class_sub, info->class_api); + if (verbose) { +#if USE_PCI_HEADER + const char *venShort; + const char *venFull; + get_vendor_info(info->vendor_id, &venShort, &venFull); + if (!venShort && !venFull) { + dprintf("PCI: vendor %04x: Unknown\n", info->vendor_id); + } else if (venShort && venFull) { + dprintf("PCI: vendor %04x: %s - %s\n", info->vendor_id, venShort, venFull); + } else { + dprintf("PCI: vendor %04x: %s\n", info->vendor_id, venShort ? venShort : venFull); + } + const char *devShort; + const char *devFull; + get_device_info(info->vendor_id, info->device_id, &devShort, &devFull); + if (!devShort && !devFull) { + dprintf("PCI: device %04x: Unknown\n", info->device_id); + } else if (devShort && devFull) { + dprintf("PCI: device %04x: %s - %s\n", info->device_id, devShort, devFull); + } else { + dprintf("PCI: device %04x: %s\n", info->device_id, devShort ? devShort : devFull); + } +#endif + dprintf("PCI: info: %s\n", get_class_info(info->class_base, info->class_sub, info->class_api)); + } dprintf("PCI: line_size %02x, latency %02x, header_type %02x, BIST %02x\n", info->line_size, info->latency, info->header_type, info->bist); switch (info->header_type) { case 0: - print_generic_info(info); + print_generic_info(info, verbose); break; case 1: - print_bridge_info(info); + print_bridge_info(info, verbose); break; default: dprintf("PCI: unknown header type\n"); @@ -75,6 +107,446 @@ pci_print_info() { pci_info info; for (long index = 0; B_OK == pci_get_nth_pci_info(index, &info); index++) { - print_info_basic(&info); + print_info_basic(&info, PCI_VERBOSE); } } + +const char * +get_class_info(uint8 class_base, uint8 class_sub, uint8 class_api) +{ + switch (class_base) { + case PCI_early: + switch (class_sub) { + case PCI_early_not_vga: + return "Not VGA-compatible pre-2.0 PCI specification device"; + case PCI_early_vga: + return "VGA-compatible pre-2.0 PCI specification device"; + default: + return "Unknown pre-2.0 PCI specification device"; + } + + case PCI_mass_storage: + switch (class_sub) { + case PCI_scsi: + return "SCSI mass storage controller"; + case PCI_ide: + return "IDE mass storage controller"; + case PCI_floppy: + return "Floppy disk controller"; + case PCI_ipi: + return "IPI mass storage controller"; + case PCI_raid: + return "RAID mass storage controller"; + case PCI_mass_storage_other: + return "Other mass storage controller"; + default: + return "Unknown mass storage controller"; + } + + case PCI_network: + switch (class_sub) { + case PCI_ethernet: + return "Ethernet network controller"; + case PCI_token_ring: + return "Token ring network controller"; + case PCI_fddi: + return "FDDI network controller"; + case PCI_atm: + return "ATM network controller"; + case PCI_isdn: + return "ISDN network controller"; + case PCI_network_other: + return "Other network controller"; + default: + return "Unknown network controller"; + } + + case PCI_display: + switch (class_sub) { + case PCI_vga: + switch (class_api) { + case 0x00: + return "VGA-compatible display controller"; + case 0x01: + return "8514-compatible display controller"; + default: + return "Unknown VGA display controller"; + } + case PCI_xga: + return "XGA display controller"; + case PCI_3d: + return "3D display controller"; + case PCI_display_other: + return "Other display controller"; + default: + return "Unknown display controller"; + } + + case PCI_multimedia: + switch (class_sub) { + case PCI_video: + return "Video multimedia device"; + case PCI_audio: + return "Audio multimedia device"; + case PCI_telephony: + return "Computer telephony multimedia device"; + case PCI_multimedia_other: + return "Other multimedia device"; + default: + return "Unknown multimedia device"; + } + + case PCI_memory: + switch (class_sub) { + case PCI_ram: + return "RAM memory controller"; + case PCI_flash: + return "Flash memory controller"; + case PCI_memory_other: + return "Other memory controller"; + default: + return "Unknown memory controller"; + } + + case PCI_bridge: + switch (class_sub) { + case PCI_host: + return "Host/PCI bridge device"; + case PCI_isa: + return "PCI/ISA bridge device"; + case PCI_eisa: + return "PCI/EISA bridge device"; + case PCI_microchannel: + return "PCI/Micro Channel bridge device"; + case PCI_pci: + switch (class_api) { + case 0x00: + return "PCI/PCI bridge device"; + case 0x01: + return "Transparent PCI/PCI bridge device"; + default: + return "Unknown PCI/PCI bridge device"; + } + case PCI_pcmcia: + return "PCI/PCMCIA bridge device"; + case PCI_nubus: + return "PCI/NuBus bridge device"; + case PCI_cardbus: + return "PCI/CardBus bridge device"; + case PCI_raceway: + if (class_api & 1) + return "PCI/RACEway bridge device, end-point mode"; + else + return "PCI/RACEway bridge device, transparent mode"; + case PCI_bridge_other: + return "Other bridge device"; + default: + return "Unknown bridge device"; + } + + case PCI_simple_communications: + switch (class_sub) { + case PCI_serial: + switch (class_api) { + case PCI_serial_xt: + return "Generic XT-compatible serial communications controller"; + case PCI_serial_16450: + return "16450-compatible serial communications controller"; + case PCI_serial_16550: + return "16550-compatible serial communications controller"; + case 0x03: + return "16650-compatible serial communications controller"; + case 0x04: + return "16750-compatible serial communications controller"; + case 0x05: + return "16850-compatible serial communications controller"; + case 0x06: + return "16950-compatible serial communications controller"; + default: + return "Unknown serial communications controller"; + } + case PCI_parallel: + switch (class_api) { + case PCI_parallel_simple: + return "Simple parallel port communications controller"; + case PCI_parallel_bidirectional: + return "Bi-directional parallel port communications controller"; + case PCI_parallel_ecp: + return "ECP 1.x compliant parallel port communications controller"; + case 0x03: + return "IEEE 1284 parallel communications controller"; + case 0xfe: + return "IEEE 1284 parallel communications target device"; + default: + return "Unknown parallel communications controller"; + } + case PCI_multiport_serial: + return "Multiport serial communications controller"; + case PCI_modem: + switch (class_api) { + case 0x00: + return "Generic modem"; + case 0x01: + return "Hayes-compatible modem, 16450-compatible interface"; + case 0x02: + return "Hayes-compatible modem, 16550-compatible interface"; + case 0x03: + return "Hayes-compatible modem, 16650-compatible interface"; + case 0x04: + return "Hayes-compatible modem, 16750-compatible interface"; + default: + return "Unknown modem communications controller"; + } + case PCI_simple_communications_other: + return "Other simple communications controller"; + default: + return "Unknown simple communications controller"; + } + + case PCI_base_peripheral: + switch (class_sub) { + case PCI_pic: + switch (class_api) { + case PCI_pic_8259: + return "Generic 8259 programmable interrupt controller (PIC)"; + case PCI_pic_isa: + return "ISA programmable interrupt controller (PIC)"; + case PCI_pic_eisa: + return "EISA programmable interrupt controller (PIC)"; + case 0x10: + return "IO advanced programmable interrupt controller (APIC)"; + case 0x20: + return "IO(x) advanced programmable interrupt controller (APIC)"; + default: + return "Unknown programmable interrupt controller (PIC)"; + } + case PCI_dma: + switch (class_api) { + case PCI_dma_8237: + return "Generic 8237 DMA controller"; + case PCI_dma_isa: + return "ISA DMA controller"; + case PCI_dma_eisa: + return "EISA DMA controller"; + default: + return "Unknown DMA controller"; + } + case PCI_timer: + switch (class_api) { + case PCI_timer_8254: + return "Generic 8254 timer"; + case PCI_timer_isa: + return "ISA system timers"; + case PCI_timer_eisa: + return "EISA system timers"; + default: + return "Unknown timer"; + } + case PCI_rtc: + switch (class_api) { + case PCI_rtc_generic: + return "Generic real time clock (RTC) controller"; + case PCI_rtc_isa: + return "ISA real time clock (RTC) controller"; + default: + return "Unknown real time clock (RTC) controller"; + } + case PCI_generic_hot_plug: + return "Generic PCI Hot-Plug controller"; + case PCI_system_peripheral_other: + return "Other base system peripheral"; + default: + return "Unknown base system peripheral"; + } + + case PCI_input: + switch (class_sub) { + case PCI_keyboard: + return "Keyboard controller"; + case PCI_pen: + return "Digitizer (pen) input device"; + case PCI_mouse: + return "Mouse controller"; + case PCI_scanner: + return "Scanner controller"; + case PCI_gameport: + switch (class_api) { + case 0x00: + return "Generic gameport controller"; + case 0x10: + return "Gameport controller"; + default: + return "Unknown gameport controller"; + } + case PCI_input_other: + return "Other input controller"; + default: + return "Unknown input controller"; + } + + case PCI_docking_station: + switch (class_sub) { + case PCI_docking_generic: + return "Generic docking station"; + case 0x80: + return "Other type of docking station"; + default: + return "Unknown docking station"; + } + + case PCI_processor: + switch (class_sub) { + case PCI_386: + return "386 processor"; + case PCI_486: + return "486 processor"; + case PCI_pentium: + return "Pentium processor"; + case PCI_alpha: + return "Alpha processor"; + case PCI_PowerPC: + return "PowerPC processor"; + case PCI_mips: + return "MIPS processor"; + case PCI_coprocessor: + return "Co-processor"; + default: + return "Unknown processor"; + } + + case PCI_serial_bus: + switch (class_sub) { + case PCI_firewire: + switch (class_api) { + case 0x00: + return "Firewire (IEEE 1394) serial bus controller"; + case 0x10: + return "Firewire (IEEE 1394) OpenHCI serial bus controller"; + default: + return "Unknown Firewire (IEEE 1394) serial bus controller"; + } + case PCI_access: + return "ACCESS serial bus controller"; + case PCI_ssa: + return "Serial Storage Architecture (SSA) controller"; + case PCI_usb: + switch (class_api) { + case PCI_usb_uhci: + return "USB UHCI controller"; + case PCI_usb_ohci: + return "USB OHCI controller"; + case 0x80: + return "Other USB controller"; + case 0xfe: + return "USB device"; + default: + return "Unknown USB serial bus controller"; + } + case PCI_fibre_channel: + return "Fibre Channel serial bus controller"; + case 0x05: + return "System Management Bus (SMBus) controller"; + default: + return "Unknown serial bus controller"; + } + + case PCI_wireless: + switch (class_sub) { + case 0x00: + return "iRDA compatible wireless controller"; + case 0x01: + return "Consumer IR wireless controller"; + case 0x10: + return "RF wireless controller"; + case 0x80: + return "Other wireless controller"; + default: + return "Unknown wireless controller"; + } + + case PCI_intelligent_io: + switch (class_sub) { + case 0x00: + return "Intelligent IO controller"; + default: + return "Unknown intelligent IO controller"; + } + + case PCI_satellite_communications: + switch (class_sub) { + case 0x01: + return "TV satellite communications controller"; + case 0x02: + return "Audio satellite communications controller"; + case 0x03: + return "Voice satellite communications controller"; + case 0x04: + return "Data satellite communications controller"; + default: + return "Unknown satellite communications controller"; + } + + case PCI_encryption_decryption: + switch (class_sub) { + case 0x00: + return "Network and computing encryption/decryption controller"; + case 0x10: + return "Entertainment encryption/decryption controller"; + case 0x80: + return "Other encryption/decryption controller"; + default: + return "Unknown encryption/decryption controller"; + } + + case PCI_data_acquisition: + switch (class_sub) { + case 0x00: + return "DPIO modules (data acquisition and signal processing controller)"; + case 0x80: + return " Other data acquisition and signal processing controller"; + default: + return "Unknown data acquisition and signal processing controller"; + } + + case PCI_undefined: + return "Does not fit any defined class"; + + default: + return "Unknown device class base"; + } +} + +#if USE_PCI_HEADER +void +get_vendor_info(uint16 vendorID, const char **venShort, const char **venFull) +{ + for (int i = 0; i < (int)PCI_VENTABLE_LEN; i++) { + if (PciVenTable[i].VenId == vendorID) { + if (0 == strcmp(PciVenTable[i].VenShort, PciVenTable[i].VenFull)) { + *venShort = PciVenTable[i].VenShort[0] ? PciVenTable[i].VenShort : NULL; + *venFull = NULL; + } else { + *venShort = PciVenTable[i].VenShort[0] ? PciVenTable[i].VenShort : NULL; + *venFull = PciVenTable[i].VenFull[0] ? PciVenTable[i].VenFull : NULL; + } + return; + } + } + *venShort = NULL; + *venFull = NULL; +} + +void +get_device_info(uint16 vendorID, uint16 deviceID, const char **devShort, const char **devFull) +{ + for (int i = 0; i < (int)PCI_DEVTABLE_LEN; i++) { + if (PciDevTable[i].VenId == vendorID && PciDevTable[i].DevId == deviceID ) { + *devShort = PciDevTable[i].Chip[0] ? PciDevTable[i].Chip : NULL; + *devFull = PciDevTable[i].ChipDesc[0] ? PciDevTable[i].ChipDesc : NULL; + return; + } + } + *devShort = NULL; + *devFull = NULL; +} +#endif