mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
pci: msi stuff
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user