Browse Source

kernel: move PCI device names out of kernel, into lspci

K. Lange 1 year ago
parent
commit
1ff5347405
5 changed files with 112 additions and 106 deletions
  1. 109 38
      apps/lspci.c
  2. 0 2
      base/usr/include/kernel/pci.h
  3. 0 59
      kernel/devices/pci.c
  4. 1 3
      modules/debug_sh.c
  5. 2 4
      modules/procfs.c

+ 109 - 38
apps/lspci.c

@@ -12,28 +12,97 @@
 #include <string.h>
 
 struct device_class {
-	char * code;
+	uint16_t id;
 	char * name;
-} device_classes[] = {
-	{"0101", "IDE interface"},
-	{"0102", "Floppy disk controller"},
-	{"0105", "ATA controller"},
-	{"0106", "SATA controller"},
-	{"0200", "Ethernet controller"},
-	{"0280", "Network controller"},
-	{"0300", "VGA compatible controller"},
-	{"0380", "Display controller"},
-	{"0401", "Multimedia audio controller"},
-	{"0403", "Audio device"},
-	{"0480", "Multimedia controller"},
-	{"0600", "Host bridge"},
-	{"0601", "ISA bridge"},
-	{"0604", "PCI bridge"},
-	{"0680", "Bridge"},
-	{"0880", "System peripheral"},
-	{NULL, NULL},
+} _pci_classes[] = {
+	{0x0101, "IDE interface"},
+	{0x0102, "Floppy disk controller"},
+	{0x0105, "ATA controller"},
+	{0x0106, "SATA controller"},
+	{0x0200, "Ethernet controller"},
+	{0x0280, "Network controller"},
+	{0x0300, "VGA compatible controller"},
+	{0x0380, "Display controller"},
+	{0x0401, "Multimedia audio controller"},
+	{0x0403, "Audio device"},
+	{0x0480, "Multimedia controller"},
+	{0x0600, "Host bridge"},
+	{0x0601, "ISA bridge"},
+	{0x0604, "PCI bridge"},
+	{0x0680, "Bridge"},
+	{0x0880, "System peripheral"},
 };
 
+struct {
+	uint16_t id;
+	const char * name;
+} _pci_vendors[] = {
+	{0x1013, "Cirrus Logic"},
+	{0x1022, "AMD"},
+	{0x106b, "Apple, Inc."},
+	{0x1234, "Bochs/QEMU"},
+	{0x1274, "Ensoniq"},
+	{0x15ad, "VMWare"},
+	{0x8086, "Intel Corporation"},
+	{0x80EE, "VirtualBox"},
+};
+
+struct {
+	uint16_t ven_id;
+	uint16_t dev_id;
+	const char * name;
+} _pci_devices[] = {
+	{0x1013, 0x00b8, "CLGD 54xx VGA Adapter"},
+	{0x1022, 0x2000, "PCNet Ethernet Controller (pcnet)"},
+	{0x106b, 0x003f, "OHCI Controller"},
+	{0x1234, 0x1111, "VGA BIOS Graphics Extensions"},
+	{0x1274, 0x1371, "Creative Labs CT2518 (ensoniq audio)"},
+	{0x15ad, 0x0740, "VM Communication Interface"},
+	{0x15ad, 0x0405, "SVGA II Adapter"},
+	{0x15ad, 0x0790, "PCI bridge"},
+	{0x15ad, 0x07a0, "PCI Express Root Port"},
+	{0x8086, 0x100e, "Gigabit Ethernet Controller (e1000)"},
+	{0x8086, 0x100f, "Gigabit Ethernet Controller (e1000)"},
+	{0x8086, 0x1237, "PCI & Memory"},
+	{0x8086, 0x2415, "AC'97 Audio Chipset"},
+	{0x8086, 0x7000, "PCI-to-ISA Bridge"},
+	{0x8086, 0x7010, "IDE Interface"},
+	{0x8086, 0x7110, "PIIX4 ISA"},
+	{0x8086, 0x7111, "PIIX4 IDE"},
+	{0x8086, 0x7113, "Power Management Controller"},
+	{0x8086, 0x7190, "Host Bridge"},
+	{0x8086, 0x7191, "AGP Bridge"},
+	{0x80EE, 0xBEEF, "Bochs/QEMU-compatible Graphics Adapter"},
+	{0x80EE, 0xCAFE, "Guest Additions Device"},
+};
+
+const char * pci_class_lookup(unsigned short class_id) {
+	for (unsigned int i = 0; i < sizeof(_pci_classes)/sizeof(_pci_classes[0]); ++i) {
+		if (_pci_classes[i].id == class_id) {
+			return _pci_classes[i].name;
+		}
+	}
+	return "(unknown)";
+}
+
+const char * pci_vendor_lookup(unsigned short vendor_id) {
+	for (unsigned int i = 0; i < sizeof(_pci_vendors)/sizeof(_pci_vendors[0]); ++i) {
+		if (_pci_vendors[i].id == vendor_id) {
+			return _pci_vendors[i].name;
+		}
+	}
+	return NULL;
+}
+
+const char * pci_device_lookup(unsigned short vendor_id, unsigned short device_id) {
+	for (unsigned int i = 0; i < sizeof(_pci_devices)/sizeof(_pci_devices[0]); ++i) {
+		if (_pci_devices[i].ven_id == vendor_id && _pci_devices[i].dev_id == device_id) {
+			return _pci_devices[i].name;
+		}
+	}
+	return NULL;
+}
+
 static void show_usage(char * argv[]) {
 	fprintf(stderr,
 			"lspci - show information about PCI devices\n"
@@ -78,7 +147,7 @@ int main(int argc, char * argv[]) {
 		/* Read device class */
 		char * device_class = strstr(line," (");
 		if (!device_class) {
-			fprintf(stderr, "%s: parse error\n", argv[0]);
+			fprintf(stderr, "%s: parse error - expected (\n", argv[0]);
 			return 1;
 		}
 		*device_class = '\0';
@@ -87,7 +156,7 @@ int main(int argc, char * argv[]) {
 
 		char * device_vendor = strstr(device_class, ", ");
 		if (!device_vendor) {
-			fprintf(stderr, "%s: parse error\n", argv[0]);
+			fprintf(stderr, "%s: parse error - expected ,\n", argv[0]);
 			return 1;
 		}
 		*device_vendor = '\0';
@@ -96,35 +165,37 @@ int main(int argc, char * argv[]) {
 
 		char * device_code = strstr(device_vendor, ":");
 		if (!device_code) {
-			fprintf(stderr, "%s: parse error\n", argv[0]);
+			fprintf(stderr, "%s: parse error - expected :\n", argv[0]);
 			return 1;
 		}
 		*device_code = '\0';
 		device_code++; /* colon */
 
-		char * device_name = strstr(device_code, ") ");
-		if (!device_name) {
-			fprintf(stderr, "%s: parse error\n", argv[0]);
+		char * last_paren = strstr(device_code, ")");
+		if (!last_paren) {
+			fprintf(stderr, "%s: parse error - expected )\n", argv[0]);
 			return 1;
 		}
-		*device_name = '\0';
-		device_name++; /* ) */
-		device_name++; /* space */
-
-		char * linefeed = strstr(device_name, "\n");
-		if (linefeed) *linefeed = '\0';
+		*last_paren = '\0';
 
 		if (numeric) {
 			fprintf(stdout, "%s %s: %s:%s\n", device_bus, device_class, device_vendor, device_code);
 		} else {
-			for (struct device_class * c = device_classes; c->code; ++c) {
-				if (!strcmp(device_class, c->code)) {
-					device_class = c->name;
-					break;
-				}
+			unsigned short class_id  = strtoul(device_class, NULL, 16);
+			unsigned short vendor_id = strtoul(device_vendor, NULL, 16);
+			unsigned short device_id = strtoul(device_code,   NULL, 16);
+			const char * class_name  = pci_class_lookup(class_id);
+			const char * vendor_name = pci_vendor_lookup(vendor_id);
+			const char * device_name = pci_device_lookup(vendor_id, device_id);
+			if (!vendor_name && !device_name) {
+				fprintf(stdout, "%s %s: %s:%s\n", device_bus, class_name, device_vendor, device_code);
+			} else if (!vendor_name) {
+				fprintf(stdout, "%s %s: %s %s\n", device_bus, class_name, device_vendor, device_name);
+			} else if (!device_name) {
+				fprintf(stdout, "%s %s: %s %s\n", device_bus, class_name, vendor_name, device_code);
+			} else {
+				fprintf(stdout, "%s %s: %s %s\n", device_bus, class_name, vendor_name, device_name);
 			}
-			/* TODO: We should also look up vendor + device names ourselves and possibly remove them from the kernel */
-			fprintf(stdout, "%s %s: %s\n", device_bus, device_class, device_name);
 		}
 	}
 

+ 0 - 2
base/usr/include/kernel/pci.h

@@ -59,8 +59,6 @@ static inline uint32_t pci_box_device(int bus, int slot, int func) {
 uint32_t pci_read_field(uint32_t device, int field, int size);
 void pci_write_field(uint32_t device, int field, int size, uint32_t value);
 uint16_t pci_find_type(uint32_t dev);
-const char * pci_vendor_lookup(unsigned short vendor_id);
-const char * pci_device_lookup(unsigned short vendor_id, unsigned short device_id);
 void pci_scan_hit(pci_func_t f, uint32_t dev, void * extra);
 void pci_scan_func(pci_func_t f, int type, int bus, int slot, int func, void * extra);
 void pci_scan_slot(pci_func_t f, int type, int bus, int slot, void * extra);

+ 0 - 59
kernel/devices/pci.c

@@ -35,65 +35,6 @@ uint16_t pci_find_type(uint32_t dev) {
 	return (pci_read_field(dev, PCI_CLASS, 1) << 8) | pci_read_field(dev, PCI_SUBCLASS, 1);
 }
 
-struct {
-	uint16_t id;
-	const char * name;
-} _pci_vendors[] = {
-	{0x1022, "AMD"},
-	{0x106b, "Apple, Inc."},
-	{0x1234, "Bochs/QEMU"},
-	{0x1274, "Ensoniq"},
-	{0x15ad, "VMWare"},
-	{0x8086, "Intel Corporation"},
-	{0x80EE, "VirtualBox"},
-};
-
-struct {
-	uint16_t ven_id;
-	uint16_t dev_id;
-	const char * name;
-} _pci_devices[] = {
-	{0x1022, 0x2000, "PCNet Ethernet Controller (pcnet)"},
-	{0x106b, 0x003f, "OHCI Controller"},
-	{0x1234, 0x1111, "VGA BIOS Graphics Extensions"},
-	{0x1274, 0x1371, "Creative Labs CT2518 (ensoniq audio)"},
-	{0x15ad, 0x0740, "VM Communication Interface"},
-	{0x15ad, 0x0405, "SVGA II Adapter"},
-	{0x15ad, 0x0790, "PCI bridge"},
-	{0x15ad, 0x07a0, "PCI Express Root Port"},
-	{0x8086, 0x100e, "Gigabit Ethernet Controller (e1000)"},
-	{0x8086, 0x100f, "Gigabit Ethernet Controller (e1000)"},
-	{0x8086, 0x1237, "PCI & Memory"},
-	{0x8086, 0x2415, "AC'97 Audio Chipset"},
-	{0x8086, 0x7000, "PCI-to-ISA Bridge"},
-	{0x8086, 0x7010, "IDE Interface"},
-	{0x8086, 0x7110, "PIIX4 ISA"},
-	{0x8086, 0x7111, "PIIX4 IDE"},
-	{0x8086, 0x7113, "Power Management Controller"},
-	{0x8086, 0x7190, "Host Bridge"},
-	{0x8086, 0x7191, "AGP Bridge"},
-	{0x80EE, 0xBEEF, "Bochs/QEMU-compatible Graphics Adapter"},
-	{0x80EE, 0xCAFE, "Guest Additions Device"},
-};
-
-
-const char * pci_vendor_lookup(unsigned short vendor_id) {
-	for (unsigned int i = 0; i < sizeof(_pci_vendors)/sizeof(_pci_vendors[0]); ++i) {
-		if (_pci_vendors[i].id == vendor_id) {
-			return _pci_vendors[i].name;
-		}
-	}
-	return "";
-}
-
-const char * pci_device_lookup(unsigned short vendor_id, unsigned short device_id) {
-	for (unsigned int i = 0; i < sizeof(_pci_devices)/sizeof(_pci_devices[0]); ++i) {
-		if (_pci_devices[i].ven_id == vendor_id && _pci_devices[i].dev_id == device_id) {
-			return _pci_devices[i].name;
-		}
-	}
-	return "";
-}
 
 void pci_scan_hit(pci_func_t f, uint32_t dev, void * extra) {
 	int dev_vend = (int)pci_read_field(dev, PCI_VENDOR_ID, 2);

+ 1 - 3
modules/debug_sh.c

@@ -245,9 +245,7 @@ static void scan_hit_list(uint32_t device, uint16_t vendorid, uint16_t deviceid,
 			(int)pci_extract_func(device),
 			(int)pci_find_type(device),
 			vendorid,
-			deviceid,
-			pci_vendor_lookup(vendorid),
-			pci_device_lookup(vendorid,deviceid));
+			deviceid);
 
 	fprintf(tty, " BAR0: 0x%8x", pci_read_field(device, PCI_BAR0, 4));
 	fprintf(tty, " BAR1: 0x%8x", pci_read_field(device, PCI_BAR1, 4));

+ 2 - 4
modules/procfs.c

@@ -642,15 +642,13 @@ static void scan_hit_list(uint32_t device, uint16_t vendorid, uint16_t deviceid,
 
 	struct _pci_buf * b = extra;
 
-	b->offset += sprintf(b->buffer + b->offset, "%2x:%2x.%d (%4x, %4x:%4x) %s %s\n",
+	b->offset += sprintf(b->buffer + b->offset, "%2x:%2x.%d (%4x, %4x:%4x)\n",
 			(int)pci_extract_bus(device),
 			(int)pci_extract_slot(device),
 			(int)pci_extract_func(device),
 			(int)pci_find_type(device),
 			vendorid,
-			deviceid,
-			pci_vendor_lookup(vendorid),
-			pci_device_lookup(vendorid,deviceid));
+			deviceid);
 
 	b->offset += sprintf(b->buffer + b->offset, " BAR0: 0x%8x", pci_read_field(device, PCI_BAR0, 4));
 	b->offset += sprintf(b->buffer + b->offset, " BAR1: 0x%8x", pci_read_field(device, PCI_BAR1, 4));