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