commit 7c09a754504b84d0c556b28252cdbcfa0402d606
parent e7fb13927a7c6c75b13ef27d11392160f9d2ac96
Author: Matsuda Kenji <info@mtkn.jp>
Date: Thu, 11 Apr 2024 12:49:11 +0900
scan pci
Diffstat:
4 files changed, 88 insertions(+), 9 deletions(-)
diff --git a/sys/include/libc.h b/sys/include/libc.h
@@ -35,7 +35,7 @@ void *memset(void *s, int c, uintptr n);
/*
typedef char *va_list;
-// ABI is different with plan9.
+// ABI is different from plan9.
#define va_start(list, start) list = (char *)((int64 *)&(start)+1)
// list += 8 on a 64-bit machine.
#define va_arg(list, mode) \
diff --git a/sys/src/kernel/amd64/pci.c b/sys/src/kernel/amd64/pci.c
@@ -3,6 +3,8 @@
const uint16 pci_config_address = 0xcf8;
const uint16 pci_config_data = 0xcfc;
+PCIDev pci_dev[MaxPCIDev];
+int num_pci_dev;
uint16
pci_config_read16(uint8 bus, uint8 dev, uint8 func, uint8 offset)
@@ -35,3 +37,65 @@ pci_config_read_vendor_id(uint8 bus, uint8 dev, uint8 func)
{
return pci_config_read16(bus, dev, func, 0x0);
}
+
+int
+pci_scan_all_bus(void)
+{
+ int func;
+ num_pci_dev = 0;
+ for (func = 0; func < 8; func++) {
+ if (pci_config_read_vendor_id(0, 0, func) == 0xffff) {
+ continue;
+ }
+ if (pci_scan_bus(func) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
+pci_scan_bus(uint8 bus)
+{
+ int dev;
+ for (dev = 0; dev < 32; dev++) {
+ if (pci_config_read_vendor_id(bus, dev, 0) == 0xffff) {
+ continue;
+ }
+ if (pci_scan_dev(bus, dev) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
+pci_scan_dev(uint8 bus, uint8 dev)
+{
+ int func;
+ for (func = 0; func < 8; func++) {
+ if (pci_config_read_vendor_id(bus, dev, func) == 0xffff) {
+ continue;
+ }
+ if (pci_scan_func(bus, dev, func) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+int
+pci_scan_func(uint8 bus, uint8 dev, uint8 func)
+{
+ if (num_pci_dev >= MaxPCIDev) {
+ return -1;
+ }
+ pci_dev[num_pci_dev].vendor_id = pci_config_read16(bus, dev, func, 0x0);
+ pci_dev[num_pci_dev].device_id = pci_config_read16(bus, dev, func, 0x2);
+ pci_dev[num_pci_dev].base_class = pci_config_read16(bus, dev, func, 0xa) >> 8;
+ pci_dev[num_pci_dev].sub_class = pci_config_read16(bus, dev, func, 0xa);
+ pci_dev[num_pci_dev].prog = pci_config_read16(bus, dev, func, 0x8) >> 8;
+ num_pci_dev++;
+
+ return 0;
+}
+\ No newline at end of file
diff --git a/sys/src/kernel/amd64/pci.h b/sys/src/kernel/amd64/pci.h
@@ -1,7 +1,18 @@
// #include <libc.h>
+typedef struct PCIDev {
+ uint16 vendor_id;
+ uint16 device_id;
+ uint8 base_class;
+ uint8 sub_class;
+ uint8 prog;
+} PCIDev;
+#define MaxPCIDev 32
+
extern const uint16 pci_config_address;
extern const uint16 pci_config_data;
+extern PCIDev pci_dev[MaxPCIDev];
+extern int num_pci_dev;
void io_out32(uint16 addr, uint32 data);
uint32 io_in32(uint16 addr);
@@ -11,3 +22,7 @@ uint32 io_in32(uint16 addr);
uint16 pci_config_read16(uint8 bus, uint8 dev, uint8 func, uint8 offset);
uint32 pci_config_read32(uint8 bus, uint8 dev, uint8 func, uint8 offset);
uint16 pci_config_read_vendor_id(uint8 bus, uint8 dev, uint8 func);
+int pci_scan_all_bus(void);
+int pci_scan_bus(uint8 bus);
+int pci_scan_dev(uint8 bus, uint8 dev);
+int pci_scan_func(uint8 bus, uint8 dev, uint8 func);
+\ No newline at end of file
diff --git a/sys/src/kernel/main.c b/sys/src/kernel/main.c
@@ -51,14 +51,12 @@ kernel_main(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop)
draw_mouse(&root_window, &m);
cons_printf(&con0, "hello world!\n");
cons_printf(&con0, "pixel at {%d, %d}: %x\n", p.x, p.y, get_pixel(&root_window, p));
- for (int dev = 0; dev < 32; dev++) {
- uint16 vendor_id, device_id;
- vendor_id = pci_config_read_vendor_id(0, dev, 0);
- if (vendor_id == 0xffff) {
- continue;
- }
- device_id = pci_config_read16(0, dev, 0, 2);
- cons_printf(&con0, "dev %d: %x, %x\n", dev, vendor_id, device_id);
+ pci_scan_all_bus();
+ for (int i = 0; i < num_pci_dev; i++) {
+ cons_printf(&con0, "%d: %x\t%x\t%x\t%x\t%x\n", i,
+ pci_dev[i].vendor_id, pci_dev[i].device_id,
+ pci_dev[i].base_class, pci_dev[i].sub_class,
+ pci_dev[i].prog);
}
halt: