commit 7ee064595a66f8f7e231ee9cf8fac8f399200205
parent 3ee4942be1e38e80f308ac241e0a009c0364446b
Author: Matsuda Kenji <info@mtkn.jp>
Date: Thu, 18 Apr 2024 13:29:14 +0900
enable and read MSI/MSI-X
Diffstat:
3 files changed, 68 insertions(+), 9 deletions(-)
diff --git a/sys/include/pci.h b/sys/include/pci.h
@@ -60,6 +60,33 @@ typedef struct PCIDev {
} PCIDev;
#define MaxPCIDev 128
+typedef struct PCICap {
+ uint8 capability_id;
+ uint8 next_pointer;
+} PCICap;
+
+typedef struct MSICap {
+ uint8 capability_id;
+ uint8 next_pointer;
+ uint16 message_control;
+ uint32 message_address;
+ uint32 meesage_upper_address; // TODO: assume 64-bit machine.
+ uint16 message_data;
+} MSICap;
+
+typedef struct MSIXCap {
+ uint8 capability_id;
+ uint8 next_pointer;
+ uint16 message_control;
+ uint32 table_offset;
+ uint32 pba_offset;
+} MSIXCap;
+
+typedef struct MSIXTab {
+} MSIXTab;
+typedef struct MSIXPBA {
+} MSIXPBA;
+
extern PCIDev pci_dev[MaxPCIDev];
extern int num_pci_dev;
diff --git a/sys/include/xhc.h b/sys/include/xhc.h
@@ -1,12 +1,21 @@
// #include <libc.h>
+typedef struct xhc_capability_registers xhc_capability_registers;
+typedef struct xhc_operational_registers xhc_operational_registers;
+typedef struct xhc_runtime_registers xhc_runtime_registers;
+typedef struct xhc_doorbell_registers xhc_doorbell_registers;
+
typedef struct Xhc {
- uintptr Base;
+ uintptr base;
+ xhc_capability_registers *cap;
+ xhc_operational_registers *op;
+ xhc_runtime_registers *runtime;
+ xhc_doorbell_registers *doorbell;
} Xhc;
extern Xhc xhc;
-typedef struct xhc_capability_registers {
+struct xhc_capability_registers {
uint8 CAPLENGTH;
uint8 Rsvd0;
uint16 HCIVERSION;
@@ -17,9 +26,9 @@ typedef struct xhc_capability_registers {
uint32 DBOFF;
uint32 RTSOFF;
uint32 HCCPARAMS2;
-} xhc_capability_registers;
+};
-typedef struct xhc_operational_registers {
+struct xhc_operational_registers {
uint32 USBCMD;
uint32 USBSTS;
uint32 PAGESIZE;
@@ -29,9 +38,9 @@ typedef struct xhc_operational_registers {
uint8 RsvdZ1[16];
uint64 DCBAAP;
uint32 CONFIG;
-} xhc_operational_registers;
+};
-typedef struct xhc_runtime_registers {
+struct xhc_runtime_registers {
uint32 MFINDEX;
uint8 RsvdZ[28];
struct interrupt_register_set {
@@ -42,8 +51,8 @@ typedef struct xhc_runtime_registers {
uint64 ERSTBA;
uint64 ERDP;
} IR[1024];
-} xhc_runtime_registers;
+};
-typedef struct xhc_doorbell_registers {
+struct xhc_doorbell_registers {
// TODO: implement.
-} xhc_doorbell_registers;
+};
diff --git a/sys/src/kernel/main.c b/sys/src/kernel/main.c
@@ -60,6 +60,29 @@ kernel_main(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop)
for (int i = 0; i < num_pci_dev; i++) {
if (pci_dev[i].base_class == 0xc && pci_dev[i].sub_class == 0x3 &&
pci_dev[i].prog == 0x30) {
+ uintptr pci_config_base = &pci_dev[i];
+ PCICap *cap = (PCICap *) (pci_config_base + pci_dev[i].capabilities_pointer);
+ for (;; cap = (PCICap *) (pci_config_base + cap->next_pointer)) {
+ switch (cap->capability_id) {
+ case 0x5:
+ ((MSICap *)cap)->message_control =
+ ((MSICap *)cap)->message_control | 1;
+ cons_printf(&con0, "MSI: %x\n", ((MSICap *)cap)->message_control);
+ break;
+ case 0x11:
+ ((MSIXCap *)cap)->message_control =
+ ((MSIXCap *)cap)->message_control | 1 << 15;
+ cons_printf(&con0, "MSI-X: %x\n", ((MSIXCap *)cap)->message_control);
+ break;
+ default:
+ cons_printf(&con0, "unsupported capability: 0x%x\n",
+ cap->capability_id);
+ break;
+ }
+ if (cap->next_pointer == 0) {
+ break;
+ }
+ }
uintptr xhc_base = ((uintptr) pci_dev[i].t0.base_address_register[1]) << 32 | pci_dev[i].t0.base_address_register[0]&0xfffffff0;
cons_printf(&con0, "xhc_base: %x\n", xhc_base);
xhc_capability_registers *xhccr = (xhc_capability_registers *) xhc_base;