//----------------------------------------------------------------------------// // GNU GPL OS/K // // // // Desc: PCI driver // // // // // // Copyright © 2018-2020 The OS/K Team // // // // This file is part of OS/K. // // // // OS/K is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // any later version. // // // // OS/K is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY//without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// #include #include #include void* pciConfigBaseAddress = NULL; static inline void* pciGetConfigAddr(uchar bus, uchar device, uchar function, ushort offset) { if(device > 32) { KernLog("pciGetConfigAddr(): bad device ID\n"); return 0; } if(function > 8) { KernLog("pciGetConfigAddr(): bad function ID\n"); return 0; } if(offset > 4096) { KernLog("pciGetConfigAddr(): bad register offset\n"); return 0; } ulong addr = bus*32*8*4096 + device*8*4096 + function*4096 + offset + (ulong)pciConfigBaseAddress; // DEBUG KernLog("bus: %u\n", bus); KernLog("device: %u\n", device); KernLog("function: %u\n", function); KernLog("offset: %u\n", offset); KernLog("ADDR: %lx\n", addr); KernLog("ADDR: %p\n", (void*)addr); return (void*)addr; } uchar pciReadConfigByte(uchar bus, uchar device, uchar function, ushort offset) { uchar *ptr = (uchar*)(pciGetConfigAddr(bus, device, function, offset)); KernLog("ADDR_uchar*: %p\n", ptr); uchar value = *ptr; //KernLog("VALUE: %u\n\n", value); return *ptr; } ushort pciReadConfigWord(uchar bus, uchar device, uchar function, ushort offset) { return *((ushort*)(pciGetConfigAddr(bus, device, function, offset))); } uint pciReadConfigDWord(uchar bus, uchar device, uchar function, ushort offset) { return *((uint*)(pciGetConfigAddr(bus, device, function, offset))); } void pciScanAll() { if(pciConfigBaseAddress == NULL) { KernLog("Unable to access PCI configuration : MCFG table not reachable\n"); return; } //KernLog("%x", pciReadConfigByte(0, 0, 0, 0)); uchar byte = pciReadConfigByte(0, 0, 0, 0); /* for(uchar bus = 0; bus < 256; bus++) { for(uchar device = 0; device < 32; device++) { for(uchar function = 0; function < 8; function++) { ushort vendor = pciReadWord(bus, device, function, PCI_REG_VENDOR); if(vendor == 0xffff) continue; KernLog("PCI device found ! vendor: %x, device: %x\n", vendor, pciReadWord(bus, device, function, PCI_REG_DEVICE)); } } } */ } void IoInitPCI() { struct SDT_MCFG_t *MCFG_table = (struct SDT_MCFG_t*)IoGetAcpiTable(SDT_MCFG); if(MCFG_table == NULL) { KernLog("Unable to access PCI configuration : MCFG table not reachable\n"); } pciConfigBaseAddress = MCFG_table->pciConfigBaseAddress; DebugLog("PCI Config Base address = 0x%p\n", pciConfigBaseAddress); // 0x ff00 0000 0000 0000 MmMapPage(pciConfigBaseAddress, pciConfigBaseAddress + 256*1024*1024, PRESENT | READWRITE); pciScanAll(); }