On some platforms, BAR entries are hardcoded and must not be accessed using standard method. Add functionality to identify this situation and configure the bus based on Extended Allocation structure.
Details
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Skipped - Unit
Tests Skipped
Event Timeline
sys/dev/pci/pci.c | ||
---|---|---|
2740 | #2740 and #2741 will be removed. |
sys/dev/pci/pci.c | ||
---|---|---|
4684 | Condition will be extended to "<=" |
Hmmm, my only thought is if we want to do this at a bit of a higher level. That is, I would maybe add a 'cfg_ea' to the dinfo that saves the offset of PCIY_EA, and I would change pci_add_resources() to walk the EA capability instead of calling pci_ata_maps() or the loop around pci_add_map() when EA is present. We should also store the "real" offset of the BAR in struct pci_map. In particular, we want that to supporting writing to BARs when necessary. Note that even with your change we are calling pci_write_bar() in pci_add_map() and it's not writing to the correct place (the raw BAR offset, not the words in the EA entry). Does this make sense? If not I can try to write up some changes, but I have no hardware to test on.
Sounds good, I'll move all the stuff one level up then. As for the EA, please note that it's intention is to indicate that the resource is electrically hardwired to some particular bus addresses. The specification says, that in this case, all "normal" BARs should be written to 0, thus we're prohibited from using them at all - yes, another argument to avoid calling pci_write_bar here. Just for the record, the link to spec: https://pcisig.com/sites/default/files/specification_documents/ECN_Enhanced_Allocation_23_Oct_2014_Final.pdf
I'll do the change and update this patch.
This looks better. Note that the ECN permits EAs to be writable (the 'W' flag) in which case these are relocatable like normal BARs.
The other thing I would like to see for this is support in pciconf -lc for displaying these. I would almost prefer that the first commit actually be adding the new registers to pcireg.h and adding pciconf support followed by a second commit to add the initial kernel use of them.
sys/dev/pci/pci.c | ||
---|---|---|
727 | Actually, we will need to handle bus numbers eventually, but this is so large of a change (now that I've looked at the ECN some) that we will probably have to do this in stages. |
OK, I'll prepare pciconf patch then.
As for W bit, I propose we leave a TODO in the code and for now ignore EA-BARs if they have W bit enabled. I just don't have any hardware to test this, my Thunder only supports read-only EA allocations.
Oh, I certainly agree with not handling writing to EA BARs yet. We can still use the initial mapping in writable EA BAR for now, it's more that we need to ensure that pci_reserve_map() doesn't try to allocate a range if an EA BAR doesn't have firmware-assigned resources (and perhaps put a TODO in place that we could do that if it is writable).
Modified EA to do a following algorithm:
- Try to allocate with EA if entry is enabled
- If allocation failed (invalid range, for example) then disable EA entry
- Disabling of EA might fail, if E bit is hardwired to 1 (means EA-only allocation)
- In pci_reserve_map and PCI/IOV BAR assignment check if EA entry is enabled. If is, do nothing. If is not, perform legacy BAR-based allocation.
Adding Writable allocation for EA should be fairly easy now, I don't expect it takes more than 4-5 lines. However, I don't have any hardware to test it so left a TODO comment.