mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Implement searching for multiple PCI devices matching a pattern.
This commit is contained in:
parent
400eb2238f
commit
50ee8ca323
3 changed files with 28 additions and 17 deletions
|
@ -100,7 +100,7 @@ addr_t DetectBGAFramebuffer()
|
||||||
memset(&pcifind, 255, sizeof(pcifind));
|
memset(&pcifind, 255, sizeof(pcifind));
|
||||||
pcifind.vendorid = 0x1234;
|
pcifind.vendorid = 0x1234;
|
||||||
pcifind.deviceid = 0x1111;
|
pcifind.deviceid = 0x1111;
|
||||||
if ( (devaddr = PCI::SearchForDevice(pcifind)) )
|
if ( (devaddr = PCI::SearchForDevices(pcifind, 0)) )
|
||||||
return ParseDevBar0(devaddr);
|
return ParseDevBar0(devaddr);
|
||||||
|
|
||||||
// Search for a generic VGA compatible device.
|
// Search for a generic VGA compatible device.
|
||||||
|
@ -108,7 +108,7 @@ addr_t DetectBGAFramebuffer()
|
||||||
pcifind.classid = 0x03;
|
pcifind.classid = 0x03;
|
||||||
pcifind.subclassid = 0x00;
|
pcifind.subclassid = 0x00;
|
||||||
pcifind.progif = 0x00;
|
pcifind.progif = 0x00;
|
||||||
if ( (devaddr = PCI::SearchForDevice(pcifind)) )
|
if ( (devaddr = PCI::SearchForDevices(pcifind)) )
|
||||||
return ParseDevBar0(devaddr);
|
return ParseDevBar0(devaddr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -92,7 +92,7 @@ void Write32(uint32_t devaddr, uint8_t off, uint32_t val); // Host endian
|
||||||
void WriteRaw32(uint32_t devaddr, uint8_t off, uint32_t val); // PCI endian
|
void WriteRaw32(uint32_t devaddr, uint8_t off, uint32_t val); // PCI endian
|
||||||
pciid_t GetDeviceId(uint32_t devaddr);
|
pciid_t GetDeviceId(uint32_t devaddr);
|
||||||
pcitype_t GetDeviceType(uint32_t devaddr);
|
pcitype_t GetDeviceType(uint32_t devaddr);
|
||||||
uint32_t SearchForDevice(pcifind_t pcifind);
|
uint32_t SearchForDevices(pcifind_t pcifind, uint32_t last = 0);
|
||||||
pcibar_t GetBAR(uint32_t devaddr, uint8_t bar);
|
pcibar_t GetBAR(uint32_t devaddr, uint8_t bar);
|
||||||
pcibar_t GetExpansionROM(uint32_t devaddr);
|
pcibar_t GetExpansionROM(uint32_t devaddr);
|
||||||
void EnableExpansionROM(uint32_t devaddr);
|
void EnableExpansionROM(uint32_t devaddr);
|
||||||
|
|
|
@ -139,35 +139,46 @@ static bool MatchesSearchCriteria(uint32_t devaddr, pcifind_t pcifind)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t SearchForDeviceOnBus(uint8_t bus, pcifind_t pcifind)
|
// TODO: This iterates the whole PCI device tree on each call!
|
||||||
|
static uint32_t SearchForDevicesOnBus(uint8_t bus, pcifind_t pcifind, uint32_t last = 0)
|
||||||
{
|
{
|
||||||
for ( unsigned slot = 0; slot < 32; slot++ )
|
bool found_any_device = false;
|
||||||
|
uint32_t next_device = 0;
|
||||||
|
|
||||||
|
for ( unsigned int slot = 0; slot < 32; slot++ )
|
||||||
{
|
{
|
||||||
unsigned numfuncs = 1;
|
unsigned int num_functions = 1;
|
||||||
for ( unsigned func = 0; func < numfuncs; func++ )
|
for ( unsigned int function = 0; function < num_functions; function++ )
|
||||||
{
|
{
|
||||||
uint32_t devaddr = MakeDevAddr(bus, slot, func);
|
uint32_t devaddr = MakeDevAddr(bus, slot, function);
|
||||||
if ( MatchesSearchCriteria(devaddr, pcifind) )
|
if ( last < devaddr &&
|
||||||
return devaddr;
|
(!found_any_device || devaddr < next_device) &&
|
||||||
|
MatchesSearchCriteria(devaddr, pcifind) )
|
||||||
|
next_device = devaddr, found_any_device = true;
|
||||||
uint8_t header = Read8(devaddr, 0x0D); // Secondary Bus Number.
|
uint8_t header = Read8(devaddr, 0x0D); // Secondary Bus Number.
|
||||||
if ( header & 0x80 ) // Multi function device.
|
if ( header & 0x80 ) // Multi function device.
|
||||||
numfuncs = 8;
|
num_functions = 8;
|
||||||
if ( (header & 0x7F) == 0x01 ) // PCI to PCI bus.
|
if ( (header & 0x7F) == 0x01 ) // PCI to PCI bus.
|
||||||
{
|
{
|
||||||
uint8_t subbusid = Read8(devaddr, 0x1A);
|
uint8_t subbusid = Read8(devaddr, 0x1A);
|
||||||
uint32_t recret = SearchForDeviceOnBus(subbusid, pcifind);
|
uint32_t recret = SearchForDevicesOnBus(subbusid, pcifind, last);
|
||||||
if ( recret )
|
if ( last < recret &&
|
||||||
return recret;
|
(!found_any_device || recret < next_device) )
|
||||||
|
next_device = recret, found_any_device = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
if ( !found_any_device )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return next_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SearchForDevice(pcifind_t pcifind)
|
uint32_t SearchForDevices(pcifind_t pcifind, uint32_t last)
|
||||||
{
|
{
|
||||||
// Search on bus 0 and recurse on other detected busses.
|
// Search on bus 0 and recurse on other detected busses.
|
||||||
return SearchForDeviceOnBus(0, pcifind);
|
return SearchForDevicesOnBus(0, pcifind, last);
|
||||||
}
|
}
|
||||||
|
|
||||||
pcibar_t GetBAR(uint32_t devaddr, uint8_t bar)
|
pcibar_t GetBAR(uint32_t devaddr, uint8_t bar)
|
||||||
|
|
Loading…
Reference in a new issue