setos

拙OS
Log | Files | Refs | LICENSE

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:
Msys/include/pci.h | 27+++++++++++++++++++++++++++
Msys/include/xhc.h | 27++++++++++++++++++---------
Msys/src/kernel/main.c | 23+++++++++++++++++++++++
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;