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));
|
||||
pcifind.vendorid = 0x1234;
|
||||
pcifind.deviceid = 0x1111;
|
||||
if ( (devaddr = PCI::SearchForDevice(pcifind)) )
|
||||
if ( (devaddr = PCI::SearchForDevices(pcifind, 0)) )
|
||||
return ParseDevBar0(devaddr);
|
||||
|
||||
// Search for a generic VGA compatible device.
|
||||
|
@ -108,7 +108,7 @@ addr_t DetectBGAFramebuffer()
|
|||
pcifind.classid = 0x03;
|
||||
pcifind.subclassid = 0x00;
|
||||
pcifind.progif = 0x00;
|
||||
if ( (devaddr = PCI::SearchForDevice(pcifind)) )
|
||||
if ( (devaddr = PCI::SearchForDevices(pcifind)) )
|
||||
return ParseDevBar0(devaddr);
|
||||
|
||||
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
|
||||
pciid_t GetDeviceId(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 GetExpansionROM(uint32_t devaddr);
|
||||
void EnableExpansionROM(uint32_t devaddr);
|
||||
|
|
|
@ -139,35 +139,46 @@ static bool MatchesSearchCriteria(uint32_t devaddr, pcifind_t pcifind)
|
|||
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;
|
||||
for ( unsigned func = 0; func < numfuncs; func++ )
|
||||
unsigned int num_functions = 1;
|
||||
for ( unsigned int function = 0; function < num_functions; function++ )
|
||||
{
|
||||
uint32_t devaddr = MakeDevAddr(bus, slot, func);
|
||||
if ( MatchesSearchCriteria(devaddr, pcifind) )
|
||||
return devaddr;
|
||||
uint32_t devaddr = MakeDevAddr(bus, slot, function);
|
||||
if ( last < 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.
|
||||
if ( header & 0x80 ) // Multi function device.
|
||||
numfuncs = 8;
|
||||
num_functions = 8;
|
||||
if ( (header & 0x7F) == 0x01 ) // PCI to PCI bus.
|
||||
{
|
||||
uint8_t subbusid = Read8(devaddr, 0x1A);
|
||||
uint32_t recret = SearchForDeviceOnBus(subbusid, pcifind);
|
||||
if ( recret )
|
||||
return recret;
|
||||
uint32_t recret = SearchForDevicesOnBus(subbusid, pcifind, last);
|
||||
if ( last < 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.
|
||||
return SearchForDeviceOnBus(0, pcifind);
|
||||
return SearchForDevicesOnBus(0, pcifind, last);
|
||||
}
|
||||
|
||||
pcibar_t GetBAR(uint32_t devaddr, uint8_t bar)
|
||||
|
|
Loading…
Reference in a new issue