pci: msi stuff

This commit is contained in:
Matheus
2022-11-24 19:16:37 -03:00
parent 8e481f5d91
commit 9fc62579ea
3 changed files with 89 additions and 1 deletions
+6
View File
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#define PCI_DEV_HEADER 0
#define PCI_BRIDGE_HEADER 1
@@ -85,6 +86,11 @@ static inline void* getbarmemaddr(pci_deviceheader* e, int bar){
#define PCI_COMMAND_MEMORY 2
#define PCI_COMMAND_MASTER 4
bool pci_msisupport(pci_enumeration* e);
void pci_msienable(pci_enumeration* e, bool enable);
void pci_msimask(pci_enumeration* e, int which, int val);
void pci_msimaskall(pci_enumeration* e, int val);
void pci_setcommand(pci_enumeration* e, int which, int val);
pci_enumeration* pci_getdevicecs(int class, int subclass, int n);
pci_enumeration* pci_getdevicecsp(int class, int subclass, int progif, int n);
+74
View File
@@ -10,6 +10,7 @@ pci_enumeration* enumerations;
#define CONFIG_DATA 0xCFC
#define COMMAND_REG 1
#define CAP_MSI 5
pci_enumeration* pci_getdevicecs(int class, int subclass, int n){
@@ -178,6 +179,79 @@ static size_t legacy_getcapabilityoffset(size_t id, pci_enumeration* enumeration
}
bool pci_msisupport(pci_enumeration* e){
if(!legacy_getcapabilityoffset(CAP_MSI, e))
return false;
return true;
}
void pci_msienable(pci_enumeration* e, bool enable){
int offset = legacy_getcapabilityoffset(CAP_MSI, e);
if(!offset)
return;
uint32_t currval = legacy_readdata(e->bus, e->device, e->function, offset);
if((currval & 1 << 23) == 0)
_panic("32 bit MSI not supported!");
if(enable){
currval |= 1 << 16;
}
else{
currval &= ~(1 << 16);
}
legacy_writedata(e->bus, e->device, e->function, offset, currval);
}
void pci_msimask(pci_enumeration* e, int which, int val){
int offset = legacy_getcapabilityoffset(CAP_MSI, e);
if(!offset)
return;
offset += 2;
uint32_t currval = legacy_readdata(e->bus, e->device, e->function, offset);
if(val){
currval |= 1 << which;
}
else{
currval &= ~(1 << which);
}
legacy_writedata(e->bus, e->device, e->function, offset, currval);
}
void pci_msimaskall(pci_enumeration* e, int val){
int offset = legacy_getcapabilityoffset(CAP_MSI, e);
if(!offset)
return;
offset += 2;
uint32_t currval = legacy_readdata(e->bus, e->device, e->function, offset);
if(val){
currval = 0xFFFFFFFF;
}
else{
currval = 0;
}
legacy_writedata(e->bus, e->device, e->function, offset, currval);
}
static void legacy_enumeratedevice(int bus, int device){
// if the device is multifunction, scan and enumerate all 8. else, only one
+9 -1
View File
@@ -99,7 +99,15 @@ void nvme_initctlr(pci_enumeration* pci){
printf("Controller minimum page size is bigger than the system page size\n");
return;
}
// set relevant command stuff in the pci config space
pci_setcommand(pci, PCI_COMMAND_MEMORY, 1);
pci_setcommand(pci, PCI_COMMAND_MASTER, 1);
pci_msienable(pci, true); // msi is always supported by nvme
pci_msimaskall(pci, 1);
// reset controller
uint32_t cc = bar0->cc;
@@ -126,7 +134,7 @@ void nvme_initctlr(pci_enumeration* pci){
bar0->cc = cc;
// enable
bar0->cc |= 1;
while((bar0->csts & 3) == 0);