Initial commit

This commit is contained in:
RichardG867
2021-08-13 18:55:06 -03:00
parent 27d4435582
commit 9fb92f1bc7
14 changed files with 2005 additions and 2 deletions

12
.gitignore vendored Normal file
View File

@@ -0,0 +1,12 @@
# cp437 tool
cp437/cp437
cp437/cp437.exe
*.cp437
# Watcom C
*.err
*.obj
# Python
__pycache__
*.pyc

View File

@@ -1,5 +1,5 @@
Probing Tools
=============
86Box Probing Tools
===================
This repository contains tools to probe hardware aspects of PC compatible or otherwise x86 systems developed by the [86Box project](/86Box/86Box).
Check each tool's directory for a README containing its description, usage, and build instructions.

17
cp437/README.md Normal file
View File

@@ -0,0 +1,17 @@
cp437
=====
Not a probing tool. Runs on the build host to convert UTF-8 source files to Code Page 437 for building DOS tools.
Usage
-----
```
cp437 infile [infile...]
- Converts UTF-8 input file(s) to CP437 output file(s) with .cp437 appended.
```
Building
--------
This tool is automatically built as needed by the build scripts for other tools. Alternatively:
**Windows:** Run `build.bat` from an OpenWatcom "Build Environment" command prompt.
**Linux:** Run `./build.sh` with OpenWatcom on `$PATH`.

46
cp437/build.bat Normal file
View File

@@ -0,0 +1,46 @@
@echo off
::
:: 86Box A hypervisor and IBM PC system emulator that specializes in
:: running old operating systems and software designed for IBM
:: PC systems and compatibles from 1981 through fairly recent
:: system designs based on the PCI bus.
::
:: This file is part of the 86Box Probing Tools distribution.
::
:: Universal Windows build script for Watcom C-based host tools.
::
::
::
:: Authors: RichardG, <richardg867@gmail.com>
::
:: Copyright 2021 RichardG.
::
:: Check for Watcom environment.
if "x%WATCOM%" == "x" (
echo *** WATCOM environment variable not set. Make sure you're on an OpenWatcom
echo "Build Environment" command prompt.
exit /b 1
)
:: Find source file.
for %%i in (*.c) do set srcfile=%%i
if "x%srcfile%" == "x" (
echo *** Source file not found.
exit /b 2
)
:: Generate output file name.
set destfile=%srcfile:~0,-2%.exe
:: Call compiler.
echo *** Building...
wcl386 -bcl=nt -fo="%destfile%" "%srcfile%"
:: Check for success.
if errorlevel 1 (
echo *** Build failed.
exit /b 4
) else (
echo *** Build successful.
)

44
cp437/build.sh Normal file
View File

@@ -0,0 +1,44 @@
#!/bin/sh
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box Probing Tools distribution.
#
# Universal *nix build script for Watcom C-based host tools.
#
#
#
# Authors: RichardG, <richardg867@gmail.com>
#
# Copyright 2021 RichardG.
#
if ! wcl386 -v >/dev/null 2>&1
then
echo '***' Watcom compiler not found. Make sure OpenWatcom is installed and in \$PATH.
exit 1
fi
# Find source file.
srcfile="$(ls *.c 2>/dev/null | head -1)"
if [ "x$srcfile" == "x" ]
then
echo '***' Source file not found.
exit 2
fi
# Generate output file name.
destfile=$(basename "$srcfile" .c)
# Call compiler and check for success.
if wcl386 -bcl=linux -fo="$destfile" "$srcfile"
then
echo '***' Build successful.
chmod +x "$destfile"
else
echo '***' Build failed.
exit 4
fi

122
cp437/cp437.c Normal file
View File

@@ -0,0 +1,122 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box Probing Tools distribution.
*
* UTF-8 -> CP437 source file conversion tool.
*
*
*
* Authors: RichardG, <richardg867@gmail.com>
*
* Copyright 2021 RichardG.
*/
#include <malloc.h>
#include <stdio.h>
#include <string.h>
/* This is the text renderer's CP437 character conversion table,
with 00, 09, 0A and 0D modified for text processing purposes. */
static const char *cp437[] = {
/* 00 */ "", "\xE2\x98\xBA", "\xE2\x98\xBB", "\xE2\x99\xA5", "\xE2\x99\xA6", "\xE2\x99\xA3", "\xE2\x99\xA0", "\xE2\x80\xA2", "\xE2\x97\x98", "\t", "\n", "\xE2\x99\x82", "\xE2\x99\x80", "\r", "\xE2\x99\xAB", "\xE2\x98\xBC",
/* 10 */ "\xE2\x96\xBA", "\xE2\x97\x84", "\xE2\x86\x95", "\xE2\x80\xBC", "\xC2\xB6", "\xC2\xA7", "\xE2\x96\xAC", "\xE2\x86\xA8", "\xE2\x86\x91", "\xE2\x86\x93", "\xE2\x86\x92", "\xE2\x86\x90", "\xE2\x88\x9F", "\xE2\x86\x94", "\xE2\x96\xB2", "\xE2\x96\xBC",
/* 20 */ " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/",
/* 30 */ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?",
/* 40 */ "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
/* 50 */ "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_",
/* 60 */ "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o",
/* 70 */ "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "\xE2\x8C\x82",
/* 80 */ "\xC3\x87", "\xC3\xBC", "\xC3\xA9", "\xC3\xA2", "\xC3\xA4", "\xC3\xA0", "\xC3\xA5", "\xC3\xA7", "\xC3\xAA", "\xC3\xAB", "\xC3\xA8", "\xC3\xAF", "\xC3\xAE", "\xC3\xAC", "\xC3\x84", "\xC3\x85",
/* 90 */ "\xC3\x89", "\xC3\xA6", "\xC3\x86", "\xC3\xB4", "\xC3\xB6", "\xC3\xB2", "\xC3\xBB", "\xC3\xB9", "\xC3\xBF", "\xC3\x96", "\xC3\x9C", "\xC2\xA2", "\xC2\xA3", "\xC2\xA5", "\xE2\x82\xA7", "\xC6\x92",
/* A0 */ "\xC3\xA1", "\xC3\xAD", "\xC3\xB3", "\xC3\xBA", "\xC3\xB1", "\xC3\x91", "\xC2\xAA", "\xC2\xBA", "\xC2\xBF", "\xE2\x8C\x90", "\xC2\xAC", "\xC2\xBD", "\xC2\xBC", "\xC2\xA1", "\xC2\xAB", "\xC2\xBB",
/* B0 */ "\xE2\x96\x91", "\xE2\x96\x92", "\xE2\x96\x93", "\xE2\x94\x82", "\xE2\x94\xA4", "\xE2\x95\xA1", "\xE2\x95\xA2", "\xE2\x95\x96", "\xE2\x95\x95", "\xE2\x95\xA3", "\xE2\x95\x91", "\xE2\x95\x97", "\xE2\x95\x9D", "\xE2\x95\x9C", "\xE2\x95\x9B", "\xE2\x94\x90",
/* C0 */ "\xE2\x94\x94", "\xE2\x94\xB4", "\xE2\x94\xAC", "\xE2\x94\x9C", "\xE2\x94\x80", "\xE2\x94\xBC", "\xE2\x95\x9E", "\xE2\x95\x9F", "\xE2\x95\x9A", "\xE2\x95\x94", "\xE2\x95\xA9", "\xE2\x95\xA6", "\xE2\x95\xA0", "\xE2\x95\x90", "\xE2\x95\xAC", "\xE2\x95\xA7",
/* D0 */ "\xE2\x95\xA8", "\xE2\x95\xA4", "\xE2\x95\xA5", "\xE2\x95\x99", "\xE2\x95\x98", "\xE2\x95\x92", "\xE2\x95\x93", "\xE2\x95\xAB", "\xE2\x95\xAA", "\xE2\x94\x98", "\xE2\x94\x8C", "\xE2\x96\x88", "\xE2\x96\x84", "\xE2\x96\x8C", "\xE2\x96\x90", "\xE2\x96\x80",
/* E0 */ "\xCE\xB1", "\xC3\x9F", "\xCE\x93", "\xCF\x80", "\xCE\xA3", "\xCF\x83", "\xC2\xB5", "\xCF\x84", "\xCE\xA6", "\xCE\x98", "\xCE\xA9", "\xCE\xB4", "\xE2\x88\x9E", "\xCF\x86", "\xCE\xB5", "\xE2\x88\xA9",
/* F0 */ "\xE2\x89\xA1", "\xC2\xB1", "\xE2\x89\xA5", "\xE2\x89\xA4", "\xE2\x8C\xA0", "\xE2\x8C\xA1", "\xC3\xB7", "\xE2\x89\x88", "\xC2\xB0", "\xE2\x88\x99", "\xC2\xB7", "\xE2\x88\x9A", "\xE2\x81\xBF", "\xC2\xB2", "\xE2\x96\xA0", "\xC2\xA0"
};
int
main(int argc, char **argv)
{
int i, j, success;
char *buf;
FILE *fin, *fout;
/* Disable stdout buffering. */
setbuf(stdout, NULL);
/* Print usage if no input files were specified. */
if (argc < 2) {
printf("Usage:\n");
printf("\n");
printf("cp437 infile [infile...]\n");
printf("- Converts UTF-8 input file(s) to CP437 output file(s) with .cp437 appended.\n");
return 1;
}
/* Process input files. */
success = 0;
for (i = 1; i < argc; i++) {
/* Open input file. */
fin = fopen(argv[i], "rb");
if (!fin) {
printf("Could not open input file \"%s\"\n", argv[i]);
continue;
}
/* Generate output file name. */
buf = malloc(strlen(argv[i]) + 7);
sprintf(buf, "%s.cp437", argv[i]);
/* Open output file. */
fout = fopen(buf, "wb");
if (!fout) {
fclose(fin);
printf("Could not open output file \"%s\"\n", buf);
continue;
}
printf("Processing \"%s\"\n", argv[i]);
/* Perform the conversion. */
while (!feof(fin)) {
/* Read UTF-8 codepoint. */
memset(buf, 0, 5);
fread(buf, 1, 1, fin);
if ((buf[0] & 0xe0) == 0xc0)
fread(&buf[1], 1, 1, fin);
else if ((buf[0] & 0xf0) == 0xe0)
fread(&buf[1], 2, 1, fin);
else if ((buf[0] & 0xf8) == 0xf0)
fread(&buf[1], 3, 1, fin);
for (j = 1; j < (sizeof(cp437) / sizeof(cp437[0])); j++) {
if (!strcmp(buf, cp437[j])) {
fputc(j, fout);
break;
}
}
}
/* Clean up. */
free(buf);
fclose(fin);
fclose(fout);
/* Increase success counter. */
success++;
}
if (--i == success)
return 0;
else if (success > 0)
return 1;
else
return 2;
}

BIN
pcireg/PCIIDS.BIN Normal file

Binary file not shown.

BIN
pcireg/PCIREG.EXE Normal file

Binary file not shown.

32
pcireg/README.md Normal file
View File

@@ -0,0 +1,32 @@
pcireg
======
DOS tool for reading, writing and dumping PCI configuration space registers; scanning the PCI bus; and more.
Usage
-----
```
PCIREG -s [-d]
∟ Display all devices on the PCI bus. Specify -d to dump registers as well.
PCIREG -i
∟ Display BIOS IRQ steering table.
PCIREG -r [bus] device [function] register
∟ Read the given register
PCIREG -w [bus] device [function] register value
∟ Write byte, word or dword to the given register
PCIREG {-d|-dw|-dl} [bus] device [function [register]]
∟ Dump registers as bytes (-d), words (-dw) or dwords (-dl). Optionally
specify the register to start from (requires bus to be specified as well).
All numeric parameters should be specified in hexadecimal (without 0x prefix).
{bus device function register} can be substituted for a single port CF8h dword.
Register dumps are saved to PCIbbddf.BIN where bb=bus, dd=device, f=function.
```
Building
--------
**Windows:** Run `build.bat` from an OpenWatcom "Build Environment" command prompt.
**Linux:** Run `./build.sh` with OpenWatcom on `$PATH`.

65
pcireg/build.bat Normal file
View File

@@ -0,0 +1,65 @@
@echo off
::
:: 86Box A hypervisor and IBM PC system emulator that specializes in
:: running old operating systems and software designed for IBM
:: PC systems and compatibles from 1981 through fairly recent
:: system designs based on the PCI bus.
::
:: This file is part of the 86Box Probing Tools distribution.
::
:: Universal Windows build script for Watcom C-based DOS tools.
::
::
::
:: Authors: RichardG, <richardg867@gmail.com>
::
:: Copyright 2021 RichardG.
::
:: Check for Watcom environment.
if "x%WATCOM%" == "x" (
echo *** WATCOM environment variable not set. Make sure you're on an OpenWatcom
echo "Build Environment" command prompt.
exit /b 1
)
:: Check for cp437 tool and build it if necessary.
if not exist ..\cp437\cp437.exe (
echo *** Building cp437 conversion tool for your host system...
pushd ..\cp437
call build.bat
popd
if errorlevel 1 exit /b %errorlevel%
)
:: Find source file.
for %%i in (*.c) do set srcfile=%%i
if "x%srcfile%" == "x" (
echo *** Source file not found.
exit /b 2
)
:: Convert source file to CP437.
echo *** Converting %srcfile% to CP437...
..\cp437\cp437.exe %srcfile%
if errorlevel 1 (
echo *** Conversion failed.
exit /b 3
)
:: Generate output file name.
set destfile=%srcfile:~0,-2%.exe
setlocal enabledelayedexpansion
for %%i in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set "destfile=!destfile:%%i=%%i!"
:: Call compiler.
echo *** Building...
wcl -bcl=dos -fo="!destfile!" "%srcfile%.cp437"
:: Check for success.
if errorlevel 1 (
echo *** Build failed.
exit /b 4
) else (
echo *** Build successful.
)

64
pcireg/build.sh Normal file
View File

@@ -0,0 +1,64 @@
#!/bin/sh
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box Probing Tools distribution.
#
# Universal *nix build script for Watcom C-based DOS tools.
#
#
#
# Authors: RichardG, <richardg867@gmail.com>
#
# Copyright 2021 RichardG.
#
# Check for Watcom environment.
if ! wcl -v >/dev/null 2>&1
then
echo '***' Watcom compiler not found. Make sure OpenWatcom is installed and in \$PATH.
exit 1
fi
# Check for cp437 tool and build it if necessary.
if [ ! -x ../cp437/cp437 ]
then
echo '***' Building cp437 conversion tool for your host system...
pushd ../cp437
if ! ./build.sh
then
exit $?
fi
popd
fi
# Find source file.
srcfile="$(ls *.c 2>/dev/null | head -1)"
if [ "x$srcfile" == "x" ]
then
echo '***' Source file not found.
exit 2
fi
# Convert source file to CP437.
echo '***' Converting $srcfile to CP437...
if ! ../cp437/cp437 "$srcfile"
then
echo '***' Conversion failed.
exit 3
fi
# Generate output file name.
destfile=$(basename "$srcfile" .c | tr [:lower:] [:upper:]).EXE
# Call compiler and check for success.
if wcl -bcl=dos -fo="$destfile" "$srcfile".cp437
then
echo '***' Build successful.
else
echo '***' Build failed.
exit 4
fi

105
pcireg/pciids.py Normal file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/python3
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box Probing Tools distribution.
#
# Conversion tool for pcireg's binary PCI ID database file.
#
#
#
# Authors: RichardG, <richardg867@gmail.com>
#
# Copyright 2021 RichardG.
#
import pciutil, struct, sys
def main():
# Load PCI ID database.
print('Loading database...')
pciutil.load_pci_db()
# Start databases.
vendor_db = b''
device_db = b''
class_db = b''
string_db = struct.pack('<B', 0)
string_db_lookup = {b'': 0}
end_entry = struct.pack('<H', 0xffff)
vendor_has_ffff = device_has_ffff = class_has_ffff = False
# Enumerate device IDs, while also going through vendor IDs.
print('Enumerating vendors and devices...')
last_vendor = None
for pci_id in sorted(pciutil._pci_devices):
vendor = pciutil.clean_vendor(pciutil._pci_vendors.get(pci_id >> 16, '')).encode('cp437', 'ignore')[:256]
if not vendor:
continue
elif last_vendor != vendor:
if last_vendor != None and not device_has_ffff:
device_db += end_entry
string_db_pos = string_db_lookup.get(vendor, None)
if string_db_pos == None:
string_db_pos = string_db_lookup[vendor] = len(string_db)
string_db += struct.pack('<B', len(vendor))
string_db += vendor
vendor_db += struct.pack('<HII', pci_id >> 16, len(device_db), string_db_pos)
vendor_has_ffff = (pci_id >> 16) == 0xffff
last_vendor = vendor
device = pciutil.clean_device(pciutil._pci_devices[pci_id]).encode('cp437', 'ignore')[:256]
string_db_pos = string_db_lookup.get(device, None)
if string_db_pos == None:
string_db_pos = string_db_lookup[device] = len(string_db)
string_db += struct.pack('<B', len(device))
string_db += device
device_db += struct.pack('<HI', pci_id & 0xffff, string_db_pos)
device_has_ffff = (pci_id & 0xffff) == 0xffff
# Enumerate class-subclass IDs.
print('Enumerating classes...')
for pci_subclass in sorted(pciutil._pci_subclasses):
class_name = pciutil._pci_subclasses[pci_subclass].encode('cp437', 'ignore')[:256]
string_db_pos = string_db_lookup.get(class_name, None)
if string_db_pos == None:
string_db_pos = string_db_lookup[class_name] = len(string_db)
string_db += struct.pack('<B', len(class_name))
string_db += class_name
class_db += struct.pack('<HI', pci_subclass, string_db_pos)
class_has_ffff = pci_subclass == 0xffff
# Add ffff end entry to the databases if required.
if not device_has_ffff:
device_db += end_entry
if not vendor_has_ffff:
vendor_db += end_entry
if not class_has_ffff:
class_db += end_entry
# Write binary file.
print('Writing binary database...')
f = open('PCIIDS.BIN', 'wb')
f.write(struct.pack('<III',
12 + len(vendor_db), # device DB offset
12 + len(vendor_db) + len(device_db), # class DB offset
12 + len(vendor_db) + len(device_db) + len(class_db) # string DB offset
))
f.write(vendor_db)
f.write(device_db)
f.write(class_db)
f.write(string_db)
f.close()
if __name__ == '__main__':
main()

1288
pcireg/pcireg.c Normal file

File diff suppressed because it is too large Load Diff

208
pcireg/pciutil.py Normal file
View File

@@ -0,0 +1,208 @@
#!/usr/bin/python3
#
# 86Box A hypervisor and IBM PC system emulator that specializes in
# running old operating systems and software designed for IBM
# PC systems and compatibles from 1981 through fairly recent
# system designs based on the PCI bus.
#
# This file is part of the 86Box Probing Tools distribution.
#
# Utility library for identifying PCI device/vendor IDs.
#
#
#
# Authors: RichardG, <richardg867@gmail.com>
#
# Copyright 2021 RichardG.
#
import re, urllib.request
clean_device_abbr = [
('100Base-T', 'FE'),
('100Base-TX', 'FE'),
('1000Base-T', 'GbE'),
('Acceleration', 'Accel.'),
('Accelerator', 'Accel.'),
('Alert on LAN', 'AoL'),
('Chipset Family', 'Chipset'),
('Chipset Graphics', 'iGPU'),
('Connection', 'Conn.'),
('DECchip', ''),
('Dual Port', '2-port'),
('Fast Ethernet', 'FE'),
('Fibre Channel', 'FC'),
('Function', 'Func.'),
('([0-9]{1,3})G Ethernet', '\\2GbE'),
('(?:([0-9]{1,3}) ?)?(?:G(?:bit|ig) Ethernet|GbE)', '\\2GbE'),
('Graphics Processor', 'GPU'),
('High Definition Audio', 'HDA'),
('Host Adapter', 'HBA'),
('Host Bus Adapter', 'HBA'),
('Host Controller', 'HC'),
('Input/Output', 'I/O'),
('Integrated ([^\s]+) Graphics', '\\2 iGPU'), # VIA CLE266
('Integrated Graphics', 'iGPU'),
('([0-9]) lane', '\\2-lane'),
('Local Area Network', 'LAN'),
('Low Pin Count', 'LPC'),
('Memory Controller Hub', 'MCH'),
('Network Adapter', 'NIC'),
('Network (?:Interface )?Card', 'NIC'),
('Network (?:Interface )?Controller', 'NIC'),
('NVM Express', 'NVMe'),
('Parallel ATA', 'PATA'),
('PCI-E', 'PCIe'),
('PCI Express', 'PCIe'),
('PCI[- ]to[- ]PCI', 'PCI-PCI'),
('Platform Controller Hub', 'PCH'),
('([0-9]) port', '\\2-port'),
('Processor Graphics', 'iGPU'),
('Quad Port', '4-port'),
('Serial ATA', 'SATA'),
('Serial Attached SCSI', 'SAS'),
('Single Port', '1-port'),
('USB ?([0-9])\\.0', 'USB\\2'),
('USB ?([0-9])\\.[0-9] ?Gen([0-9x]+)', 'USB\\2.\\3'),
('USB ?([0-9]\\.[0-9])', 'USB\\2'),
('Virtual Machine', 'VM'),
('Wake on LAN', 'WoL'),
('Wireless LAN', 'WLAN'),
]
clean_device_bit_pattern = re.compile('''( |^|\(|\[|\{|/)(?:([0-9]{1,4}) )?(?:(K)(?:ilo)?|(M)(?:ega)?|(G)(?:iga)?)bit( |$|\)|\]|\})''', re.I)
clean_device_group_pattern = re.compile('''\\\\([0-9]+)''')
clean_device_suffix_pattern = re.compile(''' (?:Adapter|Card|Device|(?:Host )?Controller)( (?: [0-9#]+)?|$|\)|\]|\})''', re.I)
clean_vendor_abbr_pattern = re.compile(''' \[([^\]]+)\]''')
clean_vendor_suffix_pattern = re.compile(''' (?:Semiconductors?|(?:Micro)?electronics?|Interactive|Technolog(?:y|ies)|(?:Micro)?systems|Computer(?: works)?|Products|Group|and subsidiaries|of(?: America)?|Co(?:rp(?:oration)?|mpany)?|Inc|LLC|Ltd|GmbH|AG|SA|(?:\(|\[|\{).*)$''', re.I)
clean_vendor_force = {
'National Semiconductor Corporation': 'NSC',
}
clean_vendor_final = {
'Chips and': 'C&T',
'Digital Equipment': 'DEC',
'Microchip Technology/SMSC': 'Microchip/SMSC',
'NVidia/SGS Thomson': 'NVIDIA/ST',
'S3 Graphics': 'S3',
'Silicon Integrated': 'SiS',
'Silicon Motion': 'SMI',
'STMicroelectronics': 'ST',
'Texas Instruments': 'TI',
'VMWare': 'VMware',
}
_clean_device_abbr_cache = []
_pci_vendors = {}
_pci_devices = {}
_pci_classes = {}
_pci_subclasses = {}
_pci_progifs = {}
def clean_device(device, vendor=None):
"""Make a device name more compact if possible."""
# Generate pattern cache if required.
if not _clean_device_abbr_cache:
for pattern, replace in clean_device_abbr:
_clean_device_abbr_cache.append((
re.compile('''( |^|\(|\[|\{|/)''' + pattern + '''( |$|\)|\]|\})''', re.I),
'\\g<1>' + replace + '\\g<' + str(1 + len(clean_device_group_pattern.findall(pattern))) + '>',
))
# Apply patterns.
device = clean_device_bit_pattern.sub('\\1\\2\\3\\4\\5bit\\6', device)
for pattern, replace in _clean_device_abbr_cache:
device = pattern.sub(replace, device)
device = clean_device_suffix_pattern.sub('\\1', device)
# Remove duplicate vendor ID.
if vendor and device[:len(vendor)] == vendor:
device = device[len(vendor):]
# Remove duplicate spaces.
return ' '.join(device.split())
def clean_vendor(vendor):
"""Make a vendor name more compact if possible."""
# Apply force table.
vendor_force = clean_vendor_force.get(vendor, None)
if vendor_force:
return vendor_force
# Use an abbreviation if the name already includes it.
vendor = vendor.replace(' / ', '/')
match = clean_vendor_abbr_pattern.search(vendor)
if match:
return match.group(1)
# Apply patterns.
match = True
while match:
vendor = vendor.rstrip(' ,.')
match = clean_vendor_suffix_pattern.search(vendor)
if match:
vendor = vendor[:match.start()]
# Apply final cleanup table.
vendor = clean_vendor_final.get(vendor, vendor)
# Remove duplicate spaces.
return ' '.join(vendor.split())
def get_pci_id(vendor_id, device_id):
"""Get the PCI device vendor and name for vendor_id and device_id."""
# Load PCI ID database if required.
if not _pci_vendors:
load_pci_db()
# Get identification.
vendor = _pci_vendors.get(vendor_id, '').strip()
return vendor or '[Unknown]', _pci_devices.get((vendor_id << 16) | device_id, vendor and '[Unknown]' or '').strip()
def load_pci_db():
"""Loads PCI ID database from disk or the website."""
# Try loading from disk or the website.
try:
f = open('/usr/share/misc/pci.ids', 'rb')
except:
try:
f = urllib.request.urlopen('https://pci-ids.ucw.cz/v2.2/pci.ids', timeout=30)
except:
# No sources available.
return
vendor = 0
class_num = subclass_num = None
for line in f:
if len(line) < 2 or line[0] == 35:
continue
elif line[0] == 67: # class
class_num = int(line[2:4], 16)
_pci_classes[class_num] = line[6:-1].decode('utf8', 'ignore')
elif class_num != None: # subclass/progif
if line[1] != 9: # subclass
subclass_num = (class_num << 8) | int(line[1:3], 16)
_pci_subclasses[subclass_num] = line[5:-1].decode('utf8', 'ignore')
else: # progif
progif_num = (subclass_num << 8) | int(line[2:4], 16)
_pci_progifs[progif_num] = line[6:-1].decode('utf8', 'ignore')
elif line[0] != 9: # vendor
vendor = int(line[:4], 16)
_pci_vendors[vendor] = line[6:-1].decode('utf8', 'ignore')
elif line[1] != 9: # device
device = (vendor << 16) | int(line[1:5], 16)
_pci_devices[device] = line[7:-1].decode('utf8', 'ignore')
f.close()
# Debugging feature.
if __name__ == '__main__':
s = input()
if len(s) == 8 and ' ' not in s:
vendor, device = get_pci_id(int(s[:4], 16), int(s[4:], 16))
vendor = clean_vendor(vendor)
print(vendor)
print(clean_device(device, vendor))
else:
print(clean_device(s))