mirror of
https://github.com/86Box/probing-tools.git
synced 2026-02-21 17:15:34 -07:00
pcireg: Add -i switch to display information. Not 100% complete yet, -d infobox will be removed once it is
This commit is contained in:
@@ -19,6 +19,15 @@
|
||||
#include "wlib.h"
|
||||
|
||||
|
||||
int
|
||||
comp_ui8(const void *elem1, const void *elem2)
|
||||
{
|
||||
uint8_t a = *((uint8_t *) elem1);
|
||||
uint8_t b = *((uint8_t *) elem2);
|
||||
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
pci_cf8(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
{
|
||||
|
||||
@@ -68,8 +68,10 @@ void outl(uint16_t port, uint32_t data);
|
||||
modify [ax cx];
|
||||
#endif
|
||||
|
||||
/* Comparator functions. */
|
||||
extern int comp_ui8(const void *elem1, const void *elem2);
|
||||
|
||||
/* PCI functions. */
|
||||
/* PCI I/O functions. */
|
||||
extern uint32_t pci_cf8(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg);
|
||||
extern uint8_t pci_readb(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg);
|
||||
extern uint16_t pci_readw(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -11,6 +11,9 @@ PCIREG -s [-d]
|
||||
PCIREG -t [-8]
|
||||
∟ Display BIOS IRQ steering table. Specify -8 to display as 86Box code.
|
||||
|
||||
PCIREG -i [bus] device [function]
|
||||
∟ Show information about the specified device.
|
||||
|
||||
PCIREG -r [bus] device [function] register
|
||||
∟ Read the specified register.
|
||||
|
||||
|
||||
226
pcireg/pciids.py
226
pcireg/pciids.py
@@ -23,82 +23,192 @@ def main():
|
||||
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}
|
||||
vendor_db = device_db = subdevice_db = class_db = subclass_db = progif_db = string_db = b''
|
||||
vendor_devices_offset = {}
|
||||
string_db_lookup = {}
|
||||
vendor_has_termination = device_has_termination = class_has_termination = subclass_has_termination = progif_has_termination = False
|
||||
|
||||
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
|
||||
# Enumerate device IDs, while also going through subdevice IDs.
|
||||
print('Enumerating devices and subdevices...')
|
||||
current_vendor_id = 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
|
||||
# Check if the vendor ID has changed.
|
||||
if (pci_id >> 16) != current_vendor_id:
|
||||
# Add termination device entry if one isn't already present.
|
||||
if current_vendor_id != None and not device_has_termination:
|
||||
device_db += struct.pack('<HII', 0xffff, 0xffffffff, 0xffffffff)
|
||||
|
||||
# Mark this as the current vendor ID.
|
||||
current_vendor_id = pci_id >> 16
|
||||
|
||||
# Store the device entries offset for this vendor.
|
||||
vendor_devices_offset[current_vendor_id] = len(device_db)
|
||||
|
||||
# Enumerate this device's subdevices.
|
||||
subdevice_db_pos = len(subdevice_db)
|
||||
subdevice_has_termination = False
|
||||
for pci_subid in sorted(pciutil._pci_subdevices.get(pci_id, {})):
|
||||
# Store a null device entries offset for this vendor if one isn't already present.
|
||||
subvendor_id = (pci_subid >> 16) & 0xffff
|
||||
if subvendor_id not in vendor_devices_offset:
|
||||
vendor_devices_offset[subvendor_id] = None
|
||||
|
||||
# Look up subdevice ID.
|
||||
subdevice = pciutil.clean_device(pciutil._pci_subdevices[pci_id][pci_subid]).encode('cp437', 'ignore')[:256]
|
||||
|
||||
# Add to string database if a valid result was found.
|
||||
if subdevice:
|
||||
string_db_pos = string_db_lookup.get(subdevice, None)
|
||||
if string_db_pos == None:
|
||||
string_db_pos = string_db_lookup[subdevice] = len(string_db)
|
||||
string_db += struct.pack('<B', len(subdevice))
|
||||
string_db += subdevice
|
||||
else:
|
||||
string_db_pos = 0xffffffff
|
||||
|
||||
# Add to subdevice database.
|
||||
subdevice_db += struct.pack('<HHI', subvendor_id, pci_subid & 0xffff, string_db_pos)
|
||||
subdevice_has_termination = (pci_subid & 0xffff) == 0xffff
|
||||
|
||||
# Mark subdevice entry if there is at least one subdevice entry.
|
||||
if len(subdevice_db) != subdevice_db_pos:
|
||||
# Add termination subdevice entry if one isn't already present.
|
||||
if not subdevice_has_termination:
|
||||
subdevice_db += struct.pack('<HHI', 0xffff, 0xffff, 0xffffffff)
|
||||
else:
|
||||
subdevice_db_pos = 0xffffffff
|
||||
|
||||
# Look up device ID.
|
||||
device = pciutil.clean_device(pciutil._pci_devices[pci_id]).encode('cp437', 'ignore')[:256]
|
||||
|
||||
# Add to string database if a valid result was found.
|
||||
if device:
|
||||
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
|
||||
else:
|
||||
string_db_pos = 0xffffffff
|
||||
|
||||
# Add to device database.
|
||||
device_db += struct.pack('<HII', pci_id & 0xffff, subdevice_db_pos, string_db_pos)
|
||||
device_has_termination = (pci_id & 0xffff) == 0xffff
|
||||
|
||||
# Enumerate vendor IDs.
|
||||
print('Enumerating vendors...')
|
||||
for vendor_id in sorted(vendor_devices_offset):
|
||||
# Look up vendor ID.
|
||||
vendor = pciutil.clean_vendor(pciutil._pci_vendors.get(vendor_id, '')).encode('cp437', 'ignore')[:256]
|
||||
|
||||
# Add to string database if a valid result was found.
|
||||
if vendor:
|
||||
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
|
||||
else:
|
||||
string_db_pos = 0xffffffff
|
||||
|
||||
vendor_db += struct.pack('<HII', pci_id >> 16, len(device_db), string_db_pos)
|
||||
vendor_has_ffff = (pci_id >> 16) == 0xffff
|
||||
# Add to vendor database.
|
||||
devices_offset = vendor_devices_offset.get(vendor_id, None)
|
||||
if devices_offset == None:
|
||||
devices_offset = 0xffffffff
|
||||
if string_db_pos != 0xffffffff and devices_offset != 0xffffffff:
|
||||
vendor_db += struct.pack('<HII', vendor_id, devices_offset, string_db_pos)
|
||||
vendor_has_termination = vendor_id == 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.
|
||||
# Enumerate class IDs.
|
||||
print('Enumerating classes...')
|
||||
for pci_class in sorted(pciutil._pci_classes):
|
||||
# Look up class ID.
|
||||
class_name = pciutil._pci_classes[pci_class].encode('cp437', 'ignore')[:256]
|
||||
|
||||
# Add to string database if a valid result was found.
|
||||
if class_name:
|
||||
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
|
||||
else:
|
||||
string_db_pos = 0xffffffff
|
||||
|
||||
# Add to class database.
|
||||
class_db += struct.pack('<BI', pci_class, string_db_pos)
|
||||
class_has_termination = pci_class == 0xff
|
||||
|
||||
# Enumerate subclass IDs.
|
||||
print('Enumerating subclasses...')
|
||||
for pci_subclass in sorted(pciutil._pci_subclasses):
|
||||
class_name = pciutil._pci_subclasses[pci_subclass].encode('cp437', 'ignore')[:256]
|
||||
# Look up class-subclass ID.
|
||||
subclass_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
|
||||
# Add to string database if a valid result was found.
|
||||
if subclass_name:
|
||||
string_db_pos = string_db_lookup.get(subclass_name, None)
|
||||
if string_db_pos == None:
|
||||
string_db_pos = string_db_lookup[subclass_name] = len(string_db)
|
||||
string_db += struct.pack('<B', len(subclass_name))
|
||||
string_db += subclass_name
|
||||
else:
|
||||
string_db_pos = 0xffffffff
|
||||
|
||||
class_db += struct.pack('<HI', pci_subclass, string_db_pos)
|
||||
class_has_ffff = pci_subclass == 0xffff
|
||||
# Add to subclass database.
|
||||
subclass_db += struct.pack('<BBI', (pci_subclass >> 16) & 0xff, pci_subclass & 0xff, string_db_pos)
|
||||
subclass_has_termination = 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
|
||||
# Enumerate progif IDs.
|
||||
print('Enumerating progifs...')
|
||||
for pci_progif in sorted(pciutil._pci_progifs):
|
||||
# Look up class-subclass-progif ID.
|
||||
progif_name = pciutil._pci_progifs[pci_progif].encode('cp437', 'ignore')[:256]
|
||||
|
||||
# Write binary file.
|
||||
# Add to string database if a valid result was found.
|
||||
if progif_name:
|
||||
string_db_pos = string_db_lookup.get(progif_name, None)
|
||||
if string_db_pos == None:
|
||||
string_db_pos = string_db_lookup[progif_name] = len(string_db)
|
||||
string_db += struct.pack('<B', len(progif_name))
|
||||
string_db += progif_name
|
||||
else:
|
||||
string_db_pos = 0xffffffff
|
||||
|
||||
# Add to progif database.
|
||||
progif_db += struct.pack('<BBBI', (pci_progif >> 16) & 0xff, (pci_progif >> 8) & 0xff, pci_progif & 0xff, string_db_pos)
|
||||
progif_has_termination = pci_progif == 0xffffff
|
||||
|
||||
# Create 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)
|
||||
|
||||
# List all databases with their respective termination flags.
|
||||
dbs = [
|
||||
(vendor_db, 14, vendor_has_termination),
|
||||
(device_db, 10, device_has_termination),
|
||||
(subdevice_db, 8, True),
|
||||
(class_db, 5, class_has_termination),
|
||||
(subclass_db, 6, subclass_has_termination),
|
||||
(progif_db, 7, progif_has_termination),
|
||||
(string_db, None, True),
|
||||
]
|
||||
|
||||
# Write header containing database offsets.
|
||||
db_len = 4 * (len(dbs) - 1)
|
||||
for db, entry_length, has_termination in dbs[:-1]:
|
||||
db_len += len(db)
|
||||
if not has_termination:
|
||||
db_len += entry_length
|
||||
f.write(struct.pack('<I', db_len))
|
||||
|
||||
# Write the databases themselves, adding termination if required.
|
||||
for db, entry_length, has_termination in dbs:
|
||||
f.write(db)
|
||||
if not has_termination:
|
||||
f.write(b'\xff' * entry_length)
|
||||
|
||||
# Finish file.
|
||||
f.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
667
pcireg/pcireg.c
667
pcireg/pcireg.c
@@ -30,26 +30,94 @@
|
||||
#include "wlib.h"
|
||||
|
||||
|
||||
struct videoconfig vc;
|
||||
union REGPACK rp; /* things break if this is not a global variable... */
|
||||
static const char *command_flags[] = {
|
||||
"I/O",
|
||||
"Mem",
|
||||
"Master",
|
||||
"Special",
|
||||
"Invalidate",
|
||||
"Palette",
|
||||
"Parity",
|
||||
"Wait",
|
||||
"SErr",
|
||||
"FastBack",
|
||||
"DisableINTx",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
static const char *status_flags[] = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"IRQ",
|
||||
"CapList",
|
||||
"66MHz",
|
||||
"UDF",
|
||||
"FastBack",
|
||||
"ParityErr1",
|
||||
NULL,
|
||||
NULL,
|
||||
"TargetAbort",
|
||||
"TargetAbortAck",
|
||||
"MasterAbort",
|
||||
"SErr",
|
||||
"ParityErr2"
|
||||
};
|
||||
static const char *devsel[] = {
|
||||
"Fast",
|
||||
"Medium",
|
||||
"Slow",
|
||||
"Invalid"
|
||||
};
|
||||
|
||||
|
||||
static struct videoconfig vc;
|
||||
static union REGPACK rp; /* things break if this is not a global variable... */
|
||||
static FILE *pciids_f = NULL;
|
||||
|
||||
#pragma pack(push, 0)
|
||||
struct {
|
||||
uint32_t dev_db_off, cls_db_off, string_db_offset;
|
||||
static struct {
|
||||
uint32_t device_db_offset,
|
||||
subdevice_db_offset,
|
||||
class_db_offset,
|
||||
subclass_db_offset,
|
||||
progif_db_offset,
|
||||
string_db_offset;
|
||||
} pciids_header;
|
||||
struct {
|
||||
uint16_t vendor;
|
||||
uint32_t dev_off;
|
||||
uint32_t string_offset;
|
||||
static struct {
|
||||
uint16_t vendor_id;
|
||||
uint32_t devices_offset,
|
||||
string_offset;
|
||||
} pciids_vendor;
|
||||
struct {
|
||||
uint16_t device;
|
||||
uint32_t string_offset;
|
||||
static struct {
|
||||
uint16_t device_id;
|
||||
uint32_t subdevices_offset,
|
||||
string_offset;
|
||||
} pciids_device;
|
||||
struct {
|
||||
uint16_t subclass;
|
||||
uint32_t string_offset;
|
||||
static struct {
|
||||
uint16_t subvendor_id,
|
||||
subdevice_id;
|
||||
uint32_t string_offset;
|
||||
} pciids_subdevice;
|
||||
static struct {
|
||||
uint8_t class_id;
|
||||
uint32_t string_offset;
|
||||
} pciids_class;
|
||||
static struct {
|
||||
uint8_t class_id,
|
||||
subclass_id;
|
||||
uint32_t string_offset;
|
||||
} pciids_subclass;
|
||||
static struct {
|
||||
uint8_t class_id,
|
||||
subclass_id,
|
||||
progif_id;
|
||||
uint32_t string_offset;
|
||||
} pciids_progif;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t bus, dev;
|
||||
@@ -69,21 +137,222 @@ typedef struct {
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
char *
|
||||
read_string(FILE *f, uint32_t offset)
|
||||
static int
|
||||
pciids_open_database()
|
||||
{
|
||||
/* No action is required if the file is already open. */
|
||||
if (pciids_f)
|
||||
return 0;
|
||||
|
||||
/* Open file, and stop if the open failed or the header couldn't be read. */
|
||||
pciids_f = fopen("PCIIDS.BIN", "rb");
|
||||
if (pciids_f && (fread(&pciids_header, sizeof(pciids_header), 1, pciids_f) < 1)) {
|
||||
fclose(pciids_f);
|
||||
pciids_f = NULL;
|
||||
}
|
||||
|
||||
/* Return 0 if the file was opened successfully, 1 otherwise. */
|
||||
return !pciids_f;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
pciids_read_string(uint32_t offset)
|
||||
{
|
||||
uint8_t length, *buf;
|
||||
|
||||
fseek(f, pciids_header.string_db_offset + offset, SEEK_SET);
|
||||
fread(&length, sizeof(length), 1, f);
|
||||
/* Return nothing if the string offset is invalid. */
|
||||
if (offset == 0xffffffff)
|
||||
return NULL;
|
||||
|
||||
/* Open database if required. */
|
||||
if (pciids_open_database())
|
||||
return NULL;
|
||||
|
||||
/* Seek to string offset. */
|
||||
fseek(pciids_f, pciids_header.string_db_offset + offset, SEEK_SET);
|
||||
|
||||
/* Read string length, and return nothing if it's an empty string. */
|
||||
fread(&length, sizeof(length), 1, pciids_f);
|
||||
if (length == 0)
|
||||
return NULL;
|
||||
|
||||
/* Read string into buffer. */
|
||||
buf = malloc(length + 1);
|
||||
fread(buf, length, 1, f);
|
||||
if (fread(buf, length, 1, pciids_f) < 1) {
|
||||
/* Clean up and return nothing if the read failed. */
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
buf[length] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
static int
|
||||
pciids_find_vendor(uint16_t vendor_id)
|
||||
{
|
||||
/* Open database if required. */
|
||||
if (pciids_open_database())
|
||||
return 0;
|
||||
|
||||
/* Seek to vendor database. */
|
||||
fseek(pciids_f, sizeof(pciids_header), SEEK_SET);
|
||||
|
||||
/* Read vendor entries until the ID is matched or overtaken. */
|
||||
do {
|
||||
if (fread(&pciids_vendor, sizeof(pciids_vendor), 1, pciids_f) < 1)
|
||||
break;
|
||||
} while (pciids_vendor.vendor_id < vendor_id);
|
||||
|
||||
/* Return 1 if the ID was matched, 0 otherwise. */
|
||||
return pciids_vendor.vendor_id == vendor_id;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
pciids_get_vendor(uint16_t vendor_id)
|
||||
{
|
||||
/* Find vendor ID in the database, and return its name if found. */
|
||||
if (pciids_find_vendor(vendor_id))
|
||||
return pciids_read_string(pciids_vendor.string_offset);
|
||||
|
||||
/* Return nothing if the vendor ID was not found. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
pciids_get_device(uint16_t device_id)
|
||||
{
|
||||
/* Must be preceded by a call to {find|get}_vendor to establish the vendor ID! */
|
||||
|
||||
/* Open database if required. */
|
||||
if (pciids_open_database())
|
||||
return NULL;
|
||||
|
||||
/* Seek to device database entries for the established vendor. */
|
||||
fseek(pciids_f, pciids_header.device_db_offset + pciids_vendor.devices_offset, SEEK_SET);
|
||||
|
||||
/* Read device entries until the ID is matched or overtaken. */
|
||||
do {
|
||||
if (fread(&pciids_device, sizeof(pciids_device), 1, pciids_f) < 1)
|
||||
break;
|
||||
} while (pciids_device.device_id < device_id);
|
||||
|
||||
/* Return the device name if found. */
|
||||
if (pciids_device.device_id == device_id)
|
||||
return pciids_read_string(pciids_device.string_offset);
|
||||
|
||||
/* Return nothing if the device ID was not found. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
pciids_get_subdevice(uint16_t subvendor_id, uint16_t subdevice_id)
|
||||
{
|
||||
/* Must be preceded by calls to {find|get}_vendor and get_device to establish the vendor/device ID! */
|
||||
|
||||
/* Open database if required. */
|
||||
if (pciids_open_database())
|
||||
return NULL;
|
||||
|
||||
/* Seek to subdevice database entries for the established subvendor. */
|
||||
fseek(pciids_f, pciids_header.subdevice_db_offset + pciids_device.subdevices_offset, SEEK_SET);
|
||||
|
||||
/* Read subdevice entries until the ID is matched or overtaken. */
|
||||
do {
|
||||
if (fread(&pciids_subdevice, sizeof(pciids_subdevice), 1, pciids_f) < 1)
|
||||
break;
|
||||
} while ((pciids_subdevice.subvendor_id < subvendor_id) || (pciids_subdevice.subdevice_id < subdevice_id));
|
||||
|
||||
/* Return the subdevice name if found. */
|
||||
if ((pciids_subdevice.subvendor_id == subvendor_id) && (pciids_subdevice.subdevice_id == subdevice_id))
|
||||
return pciids_read_string(pciids_subdevice.string_offset);
|
||||
|
||||
/* Return nothing if the subdevice ID was not found. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
pciids_get_class(uint8_t class_id)
|
||||
{
|
||||
/* Open database if required. */
|
||||
if (pciids_open_database())
|
||||
return NULL;
|
||||
|
||||
/* Seek to class database. */
|
||||
fseek(pciids_f, pciids_header.class_db_offset, SEEK_SET);
|
||||
|
||||
/* Read class entries until the ID is matched or overtaken. */
|
||||
do {
|
||||
if (fread(&pciids_class, sizeof(pciids_class), 1, pciids_f) < 1)
|
||||
break;
|
||||
} while (pciids_class.class_id < class_id);
|
||||
|
||||
/* Return the class name if found. */
|
||||
if (pciids_class.class_id == class_id)
|
||||
return pciids_read_string(pciids_class.string_offset);
|
||||
|
||||
/* Return nothing if the class ID was not found. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
pciids_get_subclass(uint8_t class_id, uint8_t subclass_id)
|
||||
{
|
||||
/* Open database if required. */
|
||||
if (pciids_open_database())
|
||||
return NULL;
|
||||
|
||||
/* Seek to subclass database. */
|
||||
fseek(pciids_f, pciids_header.subclass_db_offset, SEEK_SET);
|
||||
|
||||
/* Read subclass entries until the ID is matched or overtaken. */
|
||||
do {
|
||||
if (fread(&pciids_subclass, sizeof(pciids_subclass), 1, pciids_f) < 1)
|
||||
break;
|
||||
} while ((pciids_subclass.class_id < class_id) || (pciids_subclass.subclass_id < subclass_id));
|
||||
|
||||
/* Return the subclass name if found. */
|
||||
if ((pciids_subclass.class_id == class_id) && (pciids_subclass.subclass_id == subclass_id))
|
||||
return pciids_read_string(pciids_subclass.string_offset);
|
||||
|
||||
/* Return nothing if the subclass ID was not found. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
pciids_get_progif(uint8_t class_id, uint8_t subclass_id, uint8_t progif_id)
|
||||
{
|
||||
/* Open database if required. */
|
||||
if (pciids_open_database())
|
||||
return NULL;
|
||||
|
||||
/* Seek to programming interface database. */
|
||||
fseek(pciids_f, pciids_header.progif_db_offset, SEEK_SET);
|
||||
|
||||
/* Read programming interface entries until the ID is matched or overtaken. */
|
||||
do {
|
||||
if (fread(&pciids_progif, sizeof(pciids_progif), 1, pciids_f) < 1)
|
||||
break;
|
||||
} while ((pciids_progif.class_id < class_id) || (pciids_progif.subclass_id < subclass_id) || (pciids_progif.progif_id < progif_id));
|
||||
|
||||
/* Return the programming interface name if found. */
|
||||
if ((pciids_progif.class_id == class_id) && (pciids_progif.subclass_id == subclass_id) && (pciids_progif.progif_id == progif_id))
|
||||
return pciids_read_string(pciids_progif.string_offset);
|
||||
|
||||
/* Return nothing if the programming interface ID was not found. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dump_regs(uint8_t bus, uint8_t dev, uint8_t func, uint8_t start_reg, char sz)
|
||||
{
|
||||
int i, width, infobox, flags, bar_id;
|
||||
@@ -489,7 +758,7 @@ blank:
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
static int
|
||||
scan_bus(uint8_t bus, int nesting, char dump, FILE *f, char *buf)
|
||||
{
|
||||
int i, j, count, last_count, children;
|
||||
@@ -539,55 +808,33 @@ scan_bus(uint8_t bus, int nesting, char dump, FILE *f, char *buf)
|
||||
dev_rev_class.u32 = pci_readl(bus, dev, func, 0x08);
|
||||
#endif
|
||||
|
||||
/* Look up vendor name in the database file. */
|
||||
if (f) {
|
||||
fseek(f, sizeof(pciids_header), SEEK_SET);
|
||||
do {
|
||||
if (fread(&pciids_vendor, sizeof(pciids_vendor), 1, f) < 1)
|
||||
break;
|
||||
} while (pciids_vendor.vendor < dev_id.u16[0]);
|
||||
if (pciids_vendor.vendor == dev_id.u16[0]) {
|
||||
/* Add vendor name to buffer. */
|
||||
temp = read_string(f, pciids_vendor.string_offset);
|
||||
strcat(buf, temp);
|
||||
strcat(buf, " ");
|
||||
free(temp);
|
||||
/* Look up vendor name in the PCI ID database. */
|
||||
temp = pciids_get_vendor(dev_id.u16[0]);
|
||||
if (temp) {
|
||||
/* Add vendor name to buffer. */
|
||||
strcat(buf, temp);
|
||||
strcat(buf, " ");
|
||||
free(temp);
|
||||
|
||||
/* Look up device name. */
|
||||
fseek(f, pciids_header.dev_db_off + pciids_vendor.dev_off, SEEK_SET);
|
||||
do {
|
||||
if (fread(&pciids_device, sizeof(pciids_device), 1, f) < 1)
|
||||
break;
|
||||
} while (pciids_device.device < dev_id.u16[1]);
|
||||
if (pciids_device.device == dev_id.u16[1]) {
|
||||
/* Add device name to buffer. */
|
||||
temp = read_string(f, pciids_device.string_offset);
|
||||
strcat(buf, temp);
|
||||
free(temp);
|
||||
} else {
|
||||
/* Device name not found. */
|
||||
goto unknown;
|
||||
}
|
||||
/* Look up device name. */
|
||||
temp = pciids_get_device(dev_id.u16[1]);
|
||||
if (temp) {
|
||||
/* Add device name to buffer. */
|
||||
strcat(buf, temp);
|
||||
free(temp);
|
||||
} else {
|
||||
/* Vendor name not found. */
|
||||
strcat(buf, "[Unknown] ");
|
||||
goto unknown;
|
||||
/* Device name not found. */
|
||||
goto unknown_device;
|
||||
}
|
||||
} else {
|
||||
unknown:
|
||||
/* Look up class ID. */
|
||||
/* Vendor name not found. */
|
||||
strcat(buf, "[Unknown] ");
|
||||
|
||||
fseek(f, pciids_header.cls_db_off, SEEK_SET);
|
||||
do {
|
||||
if (fread(&pciids_class, sizeof(pciids_class), 1, f) < 1)
|
||||
break;
|
||||
} while (pciids_class.subclass < dev_rev_class.u16[1]);
|
||||
if (pciids_class.subclass == dev_rev_class.u16[1]) {
|
||||
unknown_device: /* Look up class ID. */
|
||||
temp = pciids_get_class(dev_rev_class.u16[1]);
|
||||
if (temp) {
|
||||
/* Add class name to buffer. */
|
||||
strcat(buf, "[");
|
||||
temp = read_string(f, pciids_class.string_offset);
|
||||
strcat(buf, temp);
|
||||
strcat(buf, "]");
|
||||
sprintf(&buf[strlen(buf)], "[%s]", temp);
|
||||
free(temp);
|
||||
} else {
|
||||
/* Class name not found. */
|
||||
@@ -632,8 +879,10 @@ unknown:
|
||||
children--;
|
||||
rp.h.dh--;
|
||||
}
|
||||
intr(0x10, &rp);
|
||||
putchar('├');
|
||||
if (rp.h.dh != 0xff) {
|
||||
intr(0x10, &rp);
|
||||
putchar('├');
|
||||
}
|
||||
|
||||
/* Restore cursor position. */
|
||||
rp.h.ah = 0x02;
|
||||
@@ -689,7 +938,7 @@ unknown:
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
static int
|
||||
scan_buses(char dump)
|
||||
{
|
||||
int i;
|
||||
@@ -700,13 +949,6 @@ scan_buses(char dump)
|
||||
buf = malloc(1024);
|
||||
memset(buf, 0, 1024);
|
||||
|
||||
/* Initialize PCI ID database file. */
|
||||
f = fopen("PCIIDS.BIN", "rb");
|
||||
if (f && (fread(&pciids_header, sizeof(pciids_header), 1, f) < 1)) {
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
}
|
||||
|
||||
/* Get terminal size. */
|
||||
_getvideoconfig(&vc);
|
||||
|
||||
@@ -727,42 +969,219 @@ scan_buses(char dump)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
read_reg(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
static void
|
||||
info_flags_helper(uint16_t bitfield, const char **table)
|
||||
{
|
||||
/* Small helper function for printing PCI command/status flags. */
|
||||
int i, j;
|
||||
|
||||
/* Check each bit. */
|
||||
j = 0;
|
||||
for (i = 0; i < 16; i++) {
|
||||
/* Ignore if there is no table entry. */
|
||||
if (!table[i])
|
||||
continue;
|
||||
|
||||
/* Print flag name in [brackets] if set. */
|
||||
if (bitfield & (1 << i))
|
||||
printf(" [%s]", table[i]);
|
||||
else
|
||||
printf(" %s ", table[i]);
|
||||
|
||||
/* Add line break and indentation after the 7th item. */
|
||||
if (++j == 7) {
|
||||
printf("\n ");
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
dump_info(uint8_t bus, uint8_t dev, uint8_t func)
|
||||
{
|
||||
char *temp;
|
||||
int i;
|
||||
uint8_t header_type, subsys_reg, num_bars;
|
||||
multi_t reg_val;
|
||||
|
||||
/* Print banner message. */
|
||||
printf("Reading from PCI bus %02X device %02X function %d registers [%02X:%02X]\n",
|
||||
bus, dev, func, reg | 3, reg & 0xfc);
|
||||
printf("Displaying information for PCI bus %02X device %02X function %d\n",
|
||||
bus, dev, func);
|
||||
|
||||
/* Read dword value from register. */
|
||||
/* Read vendor/device ID, and stop if it's invalid. */
|
||||
#ifdef DEBUG
|
||||
reg_val.u32 = pci_cf8(bus, dev, func, reg);
|
||||
reg_val.u32 = 0x05711106;
|
||||
#else
|
||||
reg_val.u32 = pci_readl(bus, dev, func, reg);
|
||||
reg_val.u32 = pci_readl(bus, dev, func, 0x00);
|
||||
if (!reg_val.u32 || (reg_val.u32 == 0xffffffff)) {
|
||||
printf("\nNo device appears to exist here. (vendor:device %04X:%04X)",
|
||||
reg_val.u16[0], reg_val.u16[1]);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Print value as a dword and bytes. */
|
||||
printf("Value: %04X%04X / %04X %04X / %02X %02X %02X %02X\n",
|
||||
reg_val.u16[1], reg_val.u16[0],
|
||||
reg_val.u16[0], reg_val.u16[1],
|
||||
reg_val.u8[0], reg_val.u8[1], reg_val.u8[2], reg_val.u8[3]);
|
||||
/* Print vendor ID. */
|
||||
printf("\nVendor: [%04X] ", reg_val.u16[0]);
|
||||
|
||||
/* Print vendor name if found. */
|
||||
temp = pciids_get_vendor(reg_val.u16[0]);
|
||||
if (temp) {
|
||||
printf(temp);
|
||||
free(temp);
|
||||
} else {
|
||||
printf("[Unknown]");
|
||||
}
|
||||
|
||||
/* Print device ID. */
|
||||
printf("\nDevice: [%04X] ", reg_val.u16[1]);
|
||||
|
||||
/* Print device name if found. */
|
||||
temp = pciids_get_device(reg_val.u16[1]);
|
||||
if (temp) {
|
||||
printf(temp);
|
||||
free(temp);
|
||||
} else {
|
||||
printf("[Unknown]");
|
||||
}
|
||||
|
||||
/* Read header type. We'll be using it a lot. */
|
||||
header_type = pci_readb(bus, dev, func, 0x0e);
|
||||
|
||||
/* Determine the locations of common registers for this header type. */
|
||||
switch (header_type & 0x7f) {
|
||||
case 0x00: /* standard */
|
||||
subsys_reg = 0x2c;
|
||||
num_bars = 6;
|
||||
break;
|
||||
|
||||
case 0x02: /* CardBus bridge */
|
||||
subsys_reg = 0x40;
|
||||
num_bars = 0;
|
||||
break;
|
||||
|
||||
case 0x03: /* PCI bridge and others */
|
||||
subsys_reg = 0xff;
|
||||
num_bars = 2;
|
||||
break;
|
||||
|
||||
default: /* others */
|
||||
subsys_reg = 0xff;
|
||||
num_bars = 0;
|
||||
break;
|
||||
}
|
||||
if (subsys_reg != 0xff) {
|
||||
/* Read subsystem ID and print it if valid. */
|
||||
reg_val.u32 = pci_readl(bus, dev, func, subsys_reg);
|
||||
if (reg_val.u32 && (reg_val.u32 != 0xffffffff)) {
|
||||
/* Print subvendor ID. */
|
||||
printf("\nSubvendor: [%04X] ", reg_val.u16[0]);
|
||||
|
||||
/* Print subvendor name if found. */
|
||||
temp = pciids_get_vendor(reg_val.u16[0]);
|
||||
if (temp) {
|
||||
printf(temp);
|
||||
free(temp);
|
||||
} else {
|
||||
printf("[Unknown]");
|
||||
}
|
||||
|
||||
/* Print subdevice ID. */
|
||||
printf("\nSubdevice: [%04X] ", reg_val.u16[1]);
|
||||
|
||||
/* Print subdevice ID if found. */
|
||||
temp = pciids_get_subdevice(reg_val.u16[0], reg_val.u16[1]);
|
||||
if (temp) {
|
||||
printf(temp);
|
||||
free(temp);
|
||||
} else {
|
||||
printf("[Unknown]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Read command and status. */
|
||||
reg_val.u32 = pci_readl(bus, dev, func, 0x04);
|
||||
|
||||
/* Print command and status flags. */
|
||||
printf("\n\nCommand:");
|
||||
info_flags_helper(reg_val.u16[0], command_flags);
|
||||
printf("\n Status:");
|
||||
info_flags_helper(reg_val.u16[1], status_flags);
|
||||
printf(" DEVSEL[%s]", devsel[(reg_val.u16[1] >> 9) & 3]);
|
||||
|
||||
/* Read revision and class ID. */
|
||||
reg_val.u32 = pci_readl(bus, dev, func, 0x08);
|
||||
|
||||
/* Print revision. */
|
||||
printf("\n\nRevision: %02X", reg_val.u8[0]);
|
||||
|
||||
/* Print class ID. */
|
||||
printf("\n\nClass: [%02X] ", reg_val.u8[3]);
|
||||
|
||||
/* Print class name if found. */
|
||||
temp = pciids_get_class(reg_val.u8[3]);
|
||||
if (temp) {
|
||||
printf(temp);
|
||||
free(temp);
|
||||
} else {
|
||||
printf("[Unknown]");
|
||||
}
|
||||
|
||||
/* Print subclass ID. */
|
||||
printf("\n [%02X] ");
|
||||
|
||||
/* Print subclass name if found. */
|
||||
temp = pciids_get_subclass(reg_val.u8[3], reg_val.u8[2]);
|
||||
if (temp) {
|
||||
printf(temp);
|
||||
free(temp);
|
||||
} else {
|
||||
printf("[Unknown]");
|
||||
}
|
||||
|
||||
/* Print programming interface ID. */
|
||||
printf("\n [%02X] ");
|
||||
|
||||
/* Print programming interface name if found. */
|
||||
temp = pciids_get_progif(reg_val.u8[3], reg_val.u8[2], reg_val.u8[1]);
|
||||
if (temp) {
|
||||
printf(temp);
|
||||
free(temp);
|
||||
} else {
|
||||
printf("[Unknown]");
|
||||
}
|
||||
|
||||
/* Read and print BARs. */
|
||||
for (i = 0; i < num_bars; i++) {
|
||||
if (i == 0)
|
||||
putchar('\n');
|
||||
|
||||
/* Read BAR. */
|
||||
reg_val.u32 = pci_readl(bus, dev, func, 0x10 + (i << 2));
|
||||
|
||||
/* Move on to the next BAR if this one doesn't appear to be valid. */
|
||||
if (!reg_val.u32 || (reg_val.u32 == 0xffffffff))
|
||||
continue;
|
||||
|
||||
/* Print BAR index. */
|
||||
printf("\nBAR %d: ", i);
|
||||
|
||||
/* Print BAR type and address. */
|
||||
if (i & 1)
|
||||
printf("I/O at %04X", reg_val.u16[0] & 0xfffc);
|
||||
else
|
||||
printf("Memory at %04X%04X", reg_val.u16[1], reg_val.u16[0] & 0xfff0);
|
||||
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
comp_ui8(const void *elem1, const void *elem2)
|
||||
{
|
||||
uint8_t a = *((uint8_t *) elem1);
|
||||
uint8_t b = *((uint8_t *) elem2);
|
||||
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
static int
|
||||
comp_irq_routing_entry(const void *elem1, const void *elem2)
|
||||
{
|
||||
irq_routing_entry_t *a = (irq_routing_entry_t *) elem1;
|
||||
@@ -771,8 +1190,8 @@ comp_irq_routing_entry(const void *elem1, const void *elem2)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
show_steering_table(char mode)
|
||||
static int
|
||||
dump_steering_table(char mode)
|
||||
{
|
||||
int i, j, entries;
|
||||
uint8_t irq_bitmap[256], temp[4];
|
||||
@@ -997,7 +1416,33 @@ next_entry:
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
static int
|
||||
read_reg(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg)
|
||||
{
|
||||
multi_t reg_val;
|
||||
|
||||
/* Print banner message. */
|
||||
printf("Reading from PCI bus %02X device %02X function %d registers [%02X:%02X]\n",
|
||||
bus, dev, func, reg | 3, reg & 0xfc);
|
||||
|
||||
/* Read dword value from register. */
|
||||
#ifdef DEBUG
|
||||
reg_val.u32 = pci_cf8(bus, dev, func, reg);
|
||||
#else
|
||||
reg_val.u32 = pci_readl(bus, dev, func, reg);
|
||||
#endif
|
||||
|
||||
/* Print value as a dword and bytes. */
|
||||
printf("Value: %04X%04X / %04X %04X / %02X %02X %02X %02X\n",
|
||||
reg_val.u16[1], reg_val.u16[0],
|
||||
reg_val.u16[0], reg_val.u16[1],
|
||||
reg_val.u8[0], reg_val.u8[1], reg_val.u8[2], reg_val.u8[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_reg(uint8_t bus, uint8_t dev, uint8_t func, uint8_t reg, char *val)
|
||||
{
|
||||
uint16_t data_port;
|
||||
@@ -1111,6 +1556,9 @@ usage:
|
||||
printf("PCIREG -t [-8]\n");
|
||||
printf("∟ Display BIOS IRQ steering table. Specify -8 to display as 86Box code.\n");
|
||||
printf("\n");
|
||||
printf("PCIREG -i [bus] device [function]\n");
|
||||
printf("∟ Show information about the specified device.\n");
|
||||
printf("\n");
|
||||
printf("PCIREG -r [bus] device [function] register\n");
|
||||
printf("∟ Read the specified register.\n");
|
||||
printf("\n");
|
||||
@@ -1155,9 +1603,9 @@ usage:
|
||||
} else if (argv[1][1] == 't') {
|
||||
/* Steering table display only requires a single optional parameter. */
|
||||
if ((argc >= 3) && (strlen(argv[2]) > 1))
|
||||
return show_steering_table(argv[2][1]);
|
||||
return dump_steering_table(argv[2][1]);
|
||||
else
|
||||
return show_steering_table('\0');
|
||||
return dump_steering_table('\0');
|
||||
} else if ((argc >= 3) && (strlen(argv[1]) > 1)) {
|
||||
/* Read second parameter as a dword. */
|
||||
nonhex = 0;
|
||||
@@ -1186,10 +1634,13 @@ usage:
|
||||
goto usage;
|
||||
}
|
||||
|
||||
if (argv[1][1] == 'd') {
|
||||
/* Process parameters for a register dump. */
|
||||
if ((argv[1][1] == 'd') || (argv[1][1] == 'i')) {
|
||||
/* Process parameters for a register or information dump. */
|
||||
switch (hexargc) {
|
||||
case 4:
|
||||
/* Specifying a register is not valid on an information dump. */
|
||||
if (argv[1][1] == 'i')
|
||||
goto usage;
|
||||
reg = hexargv[3];
|
||||
/* fall-through */
|
||||
|
||||
@@ -1215,7 +1666,15 @@ usage:
|
||||
}
|
||||
|
||||
/* Start the operation. */
|
||||
return dump_regs(bus, dev, func, reg, argv[1][2]);
|
||||
switch (argv[1][1]) {
|
||||
case 'd':
|
||||
/* Start register dump. */
|
||||
return dump_regs(bus, dev, func, reg, argv[1][2]);
|
||||
|
||||
case 'i':
|
||||
/* Start information dump. */
|
||||
return dump_info(bus, dev, func);
|
||||
}
|
||||
} else {
|
||||
/* Subtract value parameter from a write operation. */
|
||||
if (argv[1][1] == 'w')
|
||||
|
||||
@@ -18,17 +18,15 @@
|
||||
import re, urllib.request
|
||||
|
||||
clean_device_abbr = [
|
||||
('100Base-T', 'FE'),
|
||||
('100Base-TX', 'FE'),
|
||||
('100Base-TX?', 'FE'),
|
||||
('1000Base-T', 'GbE'),
|
||||
('Acceleration', 'Accel.'),
|
||||
('Accelerator', 'Accel.'),
|
||||
('Accelerat(?:ion|or)', 'Accel.'),
|
||||
('Alert on LAN', 'AoL'),
|
||||
('Chipset Family', 'Chipset'),
|
||||
('Chipset Graphics', 'iGPU'),
|
||||
('Connection', 'Conn.'),
|
||||
('DECchip', ''),
|
||||
('Dual Port', '2-port'),
|
||||
('Dual (Lane|Port)', '2-\\2'),
|
||||
('Fast Ethernet', 'FE'),
|
||||
('Fibre Channel', 'FC'),
|
||||
('Function', 'Func.'),
|
||||
@@ -42,25 +40,21 @@ clean_device_abbr = [
|
||||
('Input/Output', 'I/O'),
|
||||
('Integrated ([^\s]+) Graphics', '\\2 iGPU'), # VIA CLE266
|
||||
('Integrated Graphics', 'iGPU'),
|
||||
('([0-9]) lane', '\\2-lane'),
|
||||
('([0-9]) (lane|port)', '\\2-\\3'),
|
||||
('Local Area Network', 'LAN'),
|
||||
('Low Pin Count', 'LPC'),
|
||||
('Memory Controller Hub', 'MCH'),
|
||||
('Network Adapter', 'NIC'),
|
||||
('Network (?:Interface )?Card', 'NIC'),
|
||||
('Network (?:Interface )?Controller', 'NIC'),
|
||||
('Network (?:Interface )?(?:Adapter|Card|Controller)', 'NIC'),
|
||||
('NVM Express', 'NVMe'),
|
||||
('Parallel ATA', 'PATA'),
|
||||
('PCI-E', 'PCIe'),
|
||||
('PCI Express', 'PCIe'),
|
||||
('PCI[- ]to[- ]PCI', 'PCI-PCI'),
|
||||
('PCI(?:-E| Express)', 'PCIe'),
|
||||
('([^- ]+)[- ]to[- ]([^- ]+)', '\\2-\\3'),
|
||||
('Platform Controller Hub', 'PCH'),
|
||||
('([0-9]) port', '\\2-port'),
|
||||
('Processor Graphics', 'iGPU'),
|
||||
('Quad Port', '4-port'),
|
||||
('Quad (Lane|Port)', '4-\\2'),
|
||||
('Serial ATA', 'SATA'),
|
||||
('Serial Attached SCSI', 'SAS'),
|
||||
('Single Port', '1-port'),
|
||||
('Single (Lane|Port)', '1-\\2'),
|
||||
('USB ?([0-9])\\.0', 'USB\\2'),
|
||||
('USB ?([0-9])\\.[0-9] ?Gen([0-9x]+)', 'USB\\2.\\3'),
|
||||
('USB ?([0-9]\\.[0-9])', 'USB\\2'),
|
||||
@@ -69,7 +63,7 @@ clean_device_abbr = [
|
||||
('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_doubleabbr_pattern = re.compile('''( |^|\(|\[|\{|/)([^ \(\[\{/]+) (?: |\(|\[|\{|/)\\2(?: |\)|\]|\})( |$|\)|\]|\})''')
|
||||
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|AB|AG|SA|(?:\(|\[|\{).*)$''', re.I)
|
||||
@@ -92,6 +86,7 @@ clean_vendor_final = {
|
||||
_clean_device_abbr_cache = []
|
||||
_pci_vendors = {}
|
||||
_pci_devices = {}
|
||||
_pci_subdevices = {}
|
||||
_pci_classes = {}
|
||||
_pci_subclasses = {}
|
||||
_pci_progifs = {}
|
||||
@@ -103,14 +98,15 @@ def clean_device(device, vendor=None):
|
||||
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))) + '>',
|
||||
re.compile('''(?P<prefix> |^|\(|\[|\{|/)''' + pattern + '''(?P<suffix> |$|\)|\]|\})''', re.I),
|
||||
'\\g<prefix>' + replace + '\\g<suffix>',
|
||||
))
|
||||
|
||||
# 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_doubleabbr_pattern.sub('\\1\\2\\3', device)
|
||||
device = clean_device_suffix_pattern.sub('\\1', device)
|
||||
|
||||
# Remove duplicate vendor ID.
|
||||
@@ -193,6 +189,11 @@ def load_pci_db():
|
||||
elif line[1] != 9: # device
|
||||
device = (vendor << 16) | int(line[1:5], 16)
|
||||
_pci_devices[device] = line[7:-1].decode('utf8', 'ignore')
|
||||
else: # subdevice
|
||||
subdevice = (int(line[2:6], 16) << 16) | int(line[7:11], 16)
|
||||
if device not in _pci_subdevices:
|
||||
_pci_subdevices[device] = {}
|
||||
_pci_subdevices[device][subdevice] = line[13:-1].decode('utf8', 'ignore')
|
||||
|
||||
f.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user