Just a sec, I'll look up the specifics.
<gets MindShare book>
"A bit in one of the function's configuration registers defines whether
the package contains one function or more than one."
"From a configuration standpoint, the function contained in a
single-function device must respond as function zero when addressed in a
Type 0 PCI configuration read or write transaction."
"Figure 19-4 on page 372 illustrates the format of the Header Type
register. Bits [6:0] of this one byte register define the format of
dwords 4-through-15 of the device's configuration Header (see Figure
19-1 on page 353). In addition, bit 7 defines the device as a single-
(bit 7 = 0) or multi-function (bit 7 = 1) device."
And from the kernel itself (apologies if the formating is messed up):
"
/*
* The PCI interface treats multi-function devices as independent
* devices. The slot/function address of each device is encoded
* in a single byte as follows:
*
* 7:3 = slot
* 2:0 = function
*/
"
so functions are the lower 3 bits, and...
"
unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
{
unsigned int devfn, pass, max = bus->secondary;
struct pci_dev *dev;
dev_dbg(&bus->dev, "scanning bus\n");
/* Go find them, Rover! */
for (devfn = 0; devfn < 0x100; devfn += 8)
pci_scan_slot(bus, devfn);
"
when scanning a bus the kernel only looks at function 0 initially
(because of the += 8) and...
"
/**
* pci_scan_slot - scan a PCI slot on a bus for devices.
* @bus: PCI bus to scan
* @devfn: slot number to scan (must have zero function.)
*
* Scan a PCI slot on the specified PCI bus for devices, adding
* discovered devices to the @bus->devices list. New devices
* will not have is_added set.
*
* Returns the number of new devices found.
*/
int pci_scan_slot(struct pci_bus *bus, int devfn)
{
unsigned fn, nr = 0;
struct pci_dev *dev;
unsigned (*next_fn)(struct pci_dev *, unsigned) = no_next_fn;
if (only_one_child(bus) && (devfn > 0))
return 0; /* Already scanned the entire slot */
dev = pci_scan_single_device(bus, devfn);
if (!dev)
return 0;
if (!dev->is_added)
nr++;
if (pci_ari_enabled(bus))
next_fn = next_ari_fn;
else if (dev->multifunction)
next_fn = next_trad_fn;
for (fn = next_fn(dev, 0); fn > 0; fn = next_fn(dev, fn)) {
dev = pci_scan_single_device(bus, devfn + fn);
"
where next_trad_fn adds 1 to the function number and no_next_fn returns 0.
So, the kernel will look for all devices with function 0. If it's config
space claims it's multi-function (which the vast majority are not) then
it will look through the other functions for that device. I suspect this
is set up this way to save the OS all the time of scanning empty
functions in empty slots and in devices that only have one function.
I think we're likely doing this correctly in M5, except I don't believe
we have any automatic way of detecting more than one PCI function per
device, ensuring one is function 0, and setting the right bit in the
header. Since multifunction devices are pretty unusual and likely aren't
very important to the vast majority of simulations I don't think the
complexity of doing this automatically is necessarily justified. It can
be done manually, though, I think, because the HeaderType field can be
set to a particular value including setting that bit.
Gabe
On 12/10/10 10:43, nathan binkert wrote:
>> As I mentioned before, I expect that setting func to anything other than 0
>> will effectively hide your device from Linux. If Linux doesn't see it it
>> won't try to configure it and M5 won't crash, but it also isn't very useful.
> Why is that? Linux itself certainly supports multiple functions, is
> it M5 that doesn't do it right?
>
>> M5 isn't going to detect your device, the Linux kernel is going to. You
>> could look for output from your device driver as the kernel boots, or you
>> could use a command like lspci (which you'd have to add to the image, I
>> believe) to list the detected PCI devices.
> _______________________________________________
> m5-users mailing list
> [email protected]
> http://m5sim.org/cgi-bin/mailman/listinfo/m5-users
_______________________________________________
m5-users mailing list
[email protected]
http://m5sim.org/cgi-bin/mailman/listinfo/m5-users