void PCIDriverManager::Probe(int bus) { // for each slot for (int slot = 0; slot < 32; slot++) { unsigned short vendor,device; /* try and read the first configuration register. Since there are no */ /* vendors that == 0xFFFF, it must be a non-existent device. */ vendor = pciConfigReadWord(bus,slot,0,0); if (vendor == 0xffff || vendor == 0x0000) continue; device = pciConfigReadWord(bus,slot,0,2); printf("Found PCI Device: %4x:%4x in slot %d\n", (int)vendor, (int)device, slot); if (device == 0xbeef || device == 0xcafe) { for (int l = 0; l <= 0x3c; l+= 4) { int data = pciConfigReadDword(bus, slot, 0, l); if (l >= 0x10 && l <= 0x24) { printf("\tBAR%d: %8x -> ", (l - 0x10) / 4, data); pciConfigWriteDword(bus, slot, 0, l, ~0); uint32_t sz = pciConfigReadDword(bus, slot, 0, l); pciConfigWriteDword(bus, slot, 0, l, data); if (data & PCI_BASE_ADDRESS_SPACE) printf("%8x (%x)\n", sz, pci_size(data, sz, PCI_BASE_ADDRESS_IO_MASK & 0xffff)); else printf("%8x (%x)\n", sz, pci_size(data, sz, (uint32_t)PCI_BASE_ADDRESS_MEM_MASK)); } else if (data) printf("\t%2x: %8x\n", l, data); } } } }
void PCI_Device::probe_resources() noexcept { //Find resources on this PCI device (scan the BAR's) uint32_t value {PCI::WTF}; uint32_t reg {0}; uint32_t len {0}; for(int bar {0}; bar < 6; ++bar) { //Read the current BAR register reg = PCI::CONFIG_BASE_ADDR_0 + (bar << 2); value = read_dword(reg); if (!value) continue; //Write all 1's to the register, to get the length value (osdev) write_dword(reg, 0xFFFFFFFF); len = read_dword(reg); //Put the value back write_dword(reg, value); uint32_t unmasked_val {0}; uint32_t pci__size {0}; if (value & 1) { // Resource type IO unmasked_val = value & PCI::BASE_ADDRESS_IO_MASK; pci__size = pci_size(len, PCI::BASE_ADDRESS_IO_MASK & 0xFFFF); // Add it to resource list add_resource(new Resource(unmasked_val, pci__size), res_io_); assert(res_io_ != nullptr); } else { //Resource type Mem unmasked_val = value & PCI::BASE_ADDRESS_MEM_MASK; pci__size = pci_size(len, PCI::BASE_ADDRESS_MEM_MASK); //Add it to resource list add_resource(new Resource(unmasked_val, pci__size), res_mem_); assert(res_mem_ != nullptr); } INFO2(""); INFO2("[ Resource @ BAR %i ]", bar); INFO2(" Address: 0x%x Size: 0x%x", unmasked_val, pci__size); INFO2(" Type: %s", value & 1 ? "IO Resource" : "Memory Resource"); } INFO2(""); }
uint32 ATIRadeon::get_pci_memory_size(int nFd, PCI_Info_s *pcPCIInfo, int nResource) { int nBus = pcPCIInfo->nBus; int nDev = pcPCIInfo->nDevice; int nFnc = pcPCIInfo->nFunction; int nOffset = PCI_BASE_REGISTERS + nResource * 4; uint32 nBase = pci_gfx_read_config(nFd, nBus, nDev, nFnc, nOffset, 4); pci_gfx_write_config(nFd, nBus, nDev, nFnc, nOffset, 4, ~0); uint32 nSize = pci_gfx_read_config(nFd, nBus, nDev, nFnc, nOffset, 4); pci_gfx_write_config(nFd, nBus, nDev, nFnc, nOffset, 4, nBase); if (!nSize || nSize == 0xffffffff) return 0; if (nBase == 0xffffffff) nBase = 0; if (!(nSize & PCI_ADDRESS_SPACE)) { return pci_size(nSize, PCI_ADDRESS_MEMORY_32_MASK); } else { return pci_size(nSize, PCI_ADDRESS_IO_MASK & 0xffff); } }
void PCI_Device::probe_resources() noexcept { //Find resources on this PCI device (scan the BAR's) for (int bar = 0; bar < 6; ++bar) { //Read the current BAR register uint32_t reg = PCI::CONFIG_BASE_ADDR_0 + (bar << 2); uint32_t value = read_dword(reg); if (!value) continue; //Write all 1's to the register, to get the length value (osdev) write_dword(reg, 0xFFFFFFFF); uint32_t len = read_dword(reg); //Put the value back write_dword(reg, value); uint32_t unmasked_val {0}; uint32_t pci__size {0}; if (value & 1) { // Resource type IO unmasked_val = value & PCI::BASE_ADDRESS_IO_MASK; pci__size = pci_size(len, PCI::BASE_ADDRESS_IO_MASK & 0xFFFF); resources.emplace_back(PCI::RES_IO, unmasked_val, pci__size); } else { // Resource type Mem unmasked_val = value & PCI::BASE_ADDRESS_MEM_MASK; pci__size = pci_size(len, PCI::BASE_ADDRESS_MEM_MASK); resources.emplace_back(PCI::RES_MEM, unmasked_val, pci__size); } INFO2("| |- BAR %s @ 0x%x, size %i ", value & 1 ? "I/O" : "Mem", unmasked_val, pci__size); } }
uint32 ATIRadeon::get_pci_rom_memory_size(int nFd, PCI_Info_s *pcPCIInfo) { int nBus = pcPCIInfo->nBus; int nDev = pcPCIInfo->nDevice; int nFnc = pcPCIInfo->nFunction; int nOffset = PCI_ROM_BASE; uint32 nBase = pci_gfx_read_config(nFd, nBus, nDev, nFnc, nOffset, 4); pci_gfx_write_config(nFd, nBus, nDev, nFnc, nOffset, 4, ~0); uint32 nSize = pci_gfx_read_config(nFd, nBus, nDev, nFnc, nOffset, 4); pci_gfx_write_config(nFd, nBus, nDev, nFnc, nOffset, 4, nBase); if (!nSize || nSize == 0xffffffff) return 0; if (nBase == 0xffffffff) nBase = 0; return pci_size(nSize, PCI_ROM_ADDRESS_MASK); }