Some functions and read-write access for config space

This commit is contained in:
Antoine Cure 2020-02-12 23:55:54 +01:00
parent 4dd9db33d5
commit a77637cde0
No known key found for this signature in database
GPG Key ID: DCA412F83BD81F24
3 changed files with 74 additions and 11 deletions

View File

@ -35,31 +35,46 @@
// //
// Device registers offsets // Device registers offsets
// //
#define PCI_REG_VENDOR 0 #define PCI_REG_VENDOR 0
#define PCI_REG_DEVICE 2 #define PCI_REG_DEVICE 2
#define PCI_REG_COMMAND 4 #define PCI_REG_COMMAND 4
#define PCI_REG_STATUS 6 #define PCI_REG_STATUS 6
//.. //..
#define PCI_REG_BAR0 0x10 #define PCI_REG_BAR0 0x10
#define PCI_REG_BAR1 0x14 #define PCI_REG_BAR1 0x14
#define PCI_REG_BAR2 0x18
#define PCI_REG_BAR3 0x1C
#define PCI_REG_BAR4 0x20
#define PCI_REG_BAR5 0x24
//..
#define PCI_REG_INTERRUPT_LINE 0x3C
//.. //..
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
typedef struct { struct PciDev_t {
ushort vendorID; ushort vendorID;
ushort deviceID; ushort deviceID;
void* configAddr; void* configAddr;
} pciDev_t; };
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
void IoInitPCI(); void IoInitPCI();
void IoPciEnumerate(); void IoPciEnumerate();
pciDev_t *IoPciGetDevice(ushort vendorID, ushort deviceID); PciDev_t *IoPciGetDevice(ushort vendorID, ushort deviceID);
uchar IoPciReadConfigByte(PciDev_t *device, ushort offset);
ushort IoPciReadConfigWord(PciDev_t *device, ushort offset);
uint IoPciReadConfigDWord(PciDev_t *device, ushort offset);
void IoPciWriteConfigByte(PciDev_t *device, ushort offset, uchar data);
void IoPciWriteConfigWord(PciDev_t *device, ushort offset, ushort data);
void IoPciWriteConfigDWord(PciDev_t *device, ushort offset, uint data);
#endif #endif

View File

@ -67,6 +67,8 @@ typedef struct GdtPtr_t GdtPtr_t;
typedef struct Tss_t Tss_t; typedef struct Tss_t Tss_t;
typedef struct TssDescriptor_t TssDescriptor_t; typedef struct TssDescriptor_t TssDescriptor_t;
typedef struct PciDev_t PciDev_t;
//----------------------------------------------------------------------------// //----------------------------------------------------------------------------//
// //

View File

@ -68,6 +68,44 @@ static inline uint pciReadConfigDWord(uchar bus, uchar device,
return *((uint*)(pciGetConfigAddr(bus, device, function, offset))); return *((uint*)(pciGetConfigAddr(bus, device, function, offset)));
} }
//----------------------------------------------------------------------------//
uchar IoPciReadConfigByte(PciDev_t *device, ushort offset)
{
return *((uchar *)((ulong)device->configAddr + offset));
}
ushort IoPciReadConfigWord(PciDev_t *device, ushort offset)
{
return *((ushort *)((ulong)device->configAddr + offset));
}
uint IoPciReadConfigDWord(PciDev_t *device, ushort offset)
{
return *((uint *)((ulong)device->configAddr + offset));
}
void IoPciWriteConfigByte(PciDev_t *device, ushort offset, uchar data)
{
memmove((void *)((ulong)device->configAddr + offset), &data, 1);
}
void IoPciWriteConfigWord(PciDev_t *device, ushort offset, ushort data)
{
memmove((void *)((ulong)device->configAddr + offset), &data, 2);
}
void IoPciWriteConfigDWord(PciDev_t *device, ushort offset, uint data)
{
memmove((void *)((ulong)device->configAddr + offset), &data, 4);
}
void IoPciEnumerate() void IoPciEnumerate()
{ {
if(pciConfigBaseAddress == NULL) { if(pciConfigBaseAddress == NULL) {
@ -89,7 +127,7 @@ void IoPciEnumerate()
} }
} }
pciDev_t *IoPciGetDevice(ushort vendorID, ushort deviceID) PciDev_t *IoPciGetDevice(ushort vendorID, ushort deviceID)
{ {
if(pciConfigBaseAddress == NULL) { if(pciConfigBaseAddress == NULL) {
KernLog("Unable to access PCI configuration : MCFG table not reachable\n"); KernLog("Unable to access PCI configuration : MCFG table not reachable\n");
@ -101,7 +139,7 @@ pciDev_t *IoPciGetDevice(ushort vendorID, ushort deviceID)
for(uchar function = 0; function < 8; function++) { for(uchar function = 0; function < 8; function++) {
if(vendorID == pciReadConfigWord((uchar)bus, device, function, PCI_REG_VENDOR) if(vendorID == pciReadConfigWord((uchar)bus, device, function, PCI_REG_VENDOR)
&& deviceID == pciReadConfigWord((uchar)bus, device, function, PCI_REG_DEVICE)) { && deviceID == pciReadConfigWord((uchar)bus, device, function, PCI_REG_DEVICE)) {
pciDev_t *pciDevicePtr = (pciDev_t *)malloc(sizeof(pciDev_t)); PciDev_t *pciDevicePtr = (PciDev_t *)malloc(sizeof(PciDev_t));
pciDevicePtr->vendorID = vendorID; pciDevicePtr->vendorID = vendorID;
pciDevicePtr->deviceID = deviceID; pciDevicePtr->deviceID = deviceID;
pciDevicePtr->configAddr = pciGetConfigAddr((uchar)bus, device, function, 0); pciDevicePtr->configAddr = pciGetConfigAddr((uchar)bus, device, function, 0);
@ -123,6 +161,14 @@ void IoInitPCI()
DebugLog("PCI Config Base address = 0x%p\n", pciConfigBaseAddress); DebugLog("PCI Config Base address = 0x%p\n", pciConfigBaseAddress);
IoPciEnumerate(); IoPciEnumerate();
// Give R/W access to the configuration space
for(int i=0; i < 65536; i++) // 65536 = 256 * 32 * 8
{
// 4096 for page size TODO: use of KPAGESIZE
MmMapPage((void *)((ulong)pciConfigBaseAddress + i * 4096),
(void *)((ulong)pciConfigBaseAddress + i * 4096), PRESENT | READWRITE);
}
} }