diff --git a/include/io/pci.h b/include/io/pci.h index 40470d1..239fead 100644 --- a/include/io/pci.h +++ b/include/io/pci.h @@ -35,31 +35,46 @@ // // Device registers offsets // -#define PCI_REG_VENDOR 0 -#define PCI_REG_DEVICE 2 -#define PCI_REG_COMMAND 4 -#define PCI_REG_STATUS 6 +#define PCI_REG_VENDOR 0 +#define PCI_REG_DEVICE 2 +#define PCI_REG_COMMAND 4 +#define PCI_REG_STATUS 6 //.. -#define PCI_REG_BAR0 0x10 -#define PCI_REG_BAR1 0x14 +#define PCI_REG_BAR0 0x10 +#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 deviceID; void* configAddr; -} pciDev_t; +}; //----------------------------------------------------------------------------// void IoInitPCI(); 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 diff --git a/include/kernel.h b/include/kernel.h index 23c90a2..09084d9 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -67,6 +67,8 @@ typedef struct GdtPtr_t GdtPtr_t; typedef struct Tss_t Tss_t; typedef struct TssDescriptor_t TssDescriptor_t; +typedef struct PciDev_t PciDev_t; + //----------------------------------------------------------------------------// // diff --git a/kaleid/kernel/io/pci.c b/kaleid/kernel/io/pci.c index 955e818..6e05afd 100644 --- a/kaleid/kernel/io/pci.c +++ b/kaleid/kernel/io/pci.c @@ -68,6 +68,44 @@ static inline uint pciReadConfigDWord(uchar bus, uchar device, 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() { 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) { 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++) { if(vendorID == pciReadConfigWord((uchar)bus, device, function, PCI_REG_VENDOR) && 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->deviceID = deviceID; pciDevicePtr->configAddr = pciGetConfigAddr((uchar)bus, device, function, 0); @@ -123,6 +161,14 @@ void IoInitPCI() DebugLog("PCI Config Base address = 0x%p\n", pciConfigBaseAddress); 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); + } }