From 1d1e66fe3253a5b478571d2ce1acdfd0e3470a25 Mon Sep 17 00:00:00 2001 From: iretq Date: Sat, 25 Apr 2026 16:37:25 -0300 Subject: [PATCH] pci: implement msi masking Co-authored-by: Matheus --- kernel-src/include/kernel/pci.h | 1 + kernel-src/io/pci.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/kernel-src/include/kernel/pci.h b/kernel-src/include/kernel/pci.h index 8c1a68be..1d03c7a7 100644 --- a/kernel-src/include/kernel/pci.h +++ b/kernel-src/include/kernel/pci.h @@ -92,6 +92,7 @@ void pci_msixsetmask(pcienum_t *e, int v); void pci_msixadd(pcienum_t *e, int msixvec, int vec, int edgetrigger, int deassert); size_t pci_initmsi(pcienum_t *e, int requested); void pci_msisetbase(pcienum_t *e, int base, int edgetrigger, int deassert); +void pci_msisetmask(pcienum_t *e, int vector, int value); void pci_init(); #define PCI_READ32(e, offset) pci_read32(e->bus, e->device, e->function, offset) diff --git a/kernel-src/io/pci.c b/kernel-src/io/pci.c index c0dbab05..a75c62b1 100644 --- a/kernel-src/io/pci.c +++ b/kernel-src/io/pci.c @@ -122,6 +122,7 @@ size_t pci_initmsix(pcienum_t *e) { #define PCI_MSI_ENABLE 1 #define PCI_MSI_MULTIPLE_MESSAGE_SUPPORT_MASK 0x70 #define PCI_MSI_64BIT (1 << 7) +#define PCI_MSI_PER_VECTOR_MASKING (1 << 8) size_t pci_initmsi(pcienum_t *e, int requested) { // TODO maybe initialize mask if applicable? @@ -160,6 +161,23 @@ void pci_msisetbase(pcienum_t *e, int base, int edgetrigger, int deassert) { PCI_WRITE16(e, e->msi.offset + dataoffset, data); } +void pci_msisetmask(pcienum_t *e, int vector, int value) { + uint32_t msgctl = PCI_READ16(e, e->msi.offset + 2); + + if (msgctl & PCI_MSI_PER_VECTOR_MASKING) { + uint32_t maskbits = PCI_READ32(e, e->msi.offset + 16); + + if (value) + maskbits |= 1 << vector; + else + maskbits &= ~(1 << vector); + + PCI_WRITE32(e, e->msi.offset + 16, maskbits); + } else { + printf("pci: tried to mask msi vector without support\n"); + } +} + #define BAR_MAP_FLAGS (ARCH_MMU_FLAGS_WRITE | ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC) void *pci_mapbar(pcibar_t bar) {