From bee583765f5d208bd46917825c4e1a81e09e6799 Mon Sep 17 00:00:00 2001 From: Abdur-Rahman Mansoor Date: Fri, 26 Jul 2024 14:42:46 -0400 Subject: [PATCH] disable MSI interrupts if present --- drivers/nvme/nvme.asm | 40 +++++++++++++++++++++++++++++++++++++++- drivers/nvme/nvme.inc | 5 +++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/nvme.asm b/drivers/nvme/nvme.asm index d66c198..c3a9aac 100644 --- a/drivers/nvme/nvme.asm +++ b/drivers/nvme/nvme.asm @@ -882,8 +882,46 @@ proc nvme_init stdcall, pci:dword and eax, not (1 shl 10) invoke PciWrite16, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], PCI_header00.command, eax - mov edi, dword [esi + pcidev.io_addr] + ; Check if the device has a pointer to the capabilities list (status register bit 4 set to 1) + ; though this check is probably unnecessary since all PCIe devices should have this bit set to 1 + invoke PciRead16, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], PCI_header00.status + test ax, (1 shl 4) + jz .exit_fail + invoke PciRead8, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], PCI_header00.cap_ptr + and eax, 0xfc ; bottom two bits are reserved, so mask them before we access the configuration space + mov edi, eax + DEBUGF DBG_INFO, "nvme%u: Checking capabilities: %x\n", [esi + pcidev.num], edi + +; We need to check if there are any MSI/MSI-X capabilities, and if so, make sure they're disabled since +; we're using old fashioned pin-based interrupts (for now) +.read_cap: + invoke PciRead32, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], edi + add edi, 2 + cmp al, MSICAP_CID + je .got_msi_cap + cmp al, MSIXCAP_CID + je .got_msix_cap + movzx edi, ah + test edi, edi + jnz .read_cap + jmp .end_cap_parse + +.got_msi_cap: + DEBUGF DBG_INFO, "nvme%u: Found MSI capability\n", [esi + pcidev.num] + invoke PciRead32, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], edi + and eax, not MSICAP_MSIE + invoke PciWrite32, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], edi + jmp .end_cap_parse + +.got_msix_cap: + DEBUGF DBG_INFO, "nvme%u: Found MSI-X capability\n", [esi + pcidev.num] + invoke PciRead32, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], edi + and eax, not MSIXCAP_MXE + invoke PciWrite32, dword [esi + pcidev.bus], dword [esi + pcidev.devfn], edi + +.end_cap_parse: + mov edi, dword [esi + pcidev.io_addr] if 0 mov eax, dword [edi + NVME_MMIO.CAP] DEBUGF DBG_INFO, "(NVMe) CAP (0-31): 0x%x\n", eax diff --git a/drivers/nvme/nvme.inc b/drivers/nvme/nvme.inc index f5b15e3..f39b56c 100644 --- a/drivers/nvme/nvme.inc +++ b/drivers/nvme/nvme.inc @@ -26,6 +26,11 @@ CQ_ENTRIES = NVM_ACQS ; I/O and Admin Completion Queue Size PAGE_SIZE = 4096 shl NVM_MPS SUPPORTED_LBADS = 9 ; KolibriOS only supports LBADS of 512, later on we may remove this restriction +MSIXCAP_CID = 0x11 +MSIXCAP_MXE = 1 shl 15 ; MSI-X Enable bit +MSICAP_CID = 0x05 +MSICAP_MSIE = 1 ; MSI Enable bit + ADMIN_QUEUE = 0 ; Admin Queue ID IEN_ON = 2