Closed alexisvl closed 6 years ago
What is the get_w function supposed to do? Is that supposed to be get_f for 'get function' or something else?
What are the set(*) functions setting? The one with uint32_t seems like it would set the b/d/f/, but what about the others?
_b
, _w
, and _d
are byte/word/dword matching the naming used in portio, since different width accesses to config space are possible - I couldn't find anywhere else that had to make that distinction so I kept that naming. set
writes to config space just like get_*
reads from it.
(Of couse the naming in portio comes from the x86 portio instructions so maybe it's not the best example to follow, but I wanted to match what was already there as well as I could. Let me know if I missed a more obvious example to follow.)
After chatting with Rian, the plan for PCI is to try to use a "virt half" "phys half" design. I thought the phys part was going to be like the other intrinsics, but for now we have settled on using classes.
The role of the physical half will still be to talk to the real PCI devices, but with a class interface similar to the ones on my interrupt-manager branch instead. If you look at my interrupt-manager branch of the extended APIs, under vic you'll see 'phys_lapic', 'phys_x2apic', 'virt_lapic', and 'virt_x2apic'.
The lapic classes are abstract base classes; phys_lapic is designed for reading and writing to a physical lapic, whereas the virt_lapic will (soon) provide an interface for registering handlers for a given interrupt vector, as well as reading and writing to a virtual apic.
If this design seems reasonable to you for PCI (Rian and I think it should be ok), please rewrite the RFC for a 'physpci' (name it whatever, but use phys for the physical prefix, virt_ for virtual prefix). Feel free to look at my interrupt-manager branch, as that will give you an idea of the design we're looking for.
Currently, the interrupt_manager has a phys_x2apic and a virt_x2apic, which are concrete implementations for talking to a phys,virt x2apic. the manager also registers the relevant exit handlers for guest apic accesses.
The PCI doesn't have to follow the interrupt design exactly, but there will have to be something that manages virtual pci devices and guest port I/O accesses to them, and those accesses need to be coordinated with physical PCI accesses.
We had this discussion late this afternoon and I know there is a lot, so if you have questions or concerns let me know. For now I would still focus on configuration of physical PCI devices using a class rather than namespaces
I've updated the RFC. I don't think what I had was all that far from what you're describing, and from what I see in the interrupt manager code. The original lower-level API was just to provide a wrapper around the architecture-specific ways of accessing PCI, so the part that provides clean register access can be architecture-independent - I still think that layer is needed, but I pulled it into the class as a set of static methods.
Looks good! This is exactly what I was hoping for. For now lets just put it in hve - EXPORT_EAPIS_HVE.
Got it, wasn't sure how that was structured. Thanks :+1:
+1, LGTM
While I'm still making occasional minor tweaks, this was effectively closed by Bareflank/extended_apis#66
This RFC proposes an simple API for accessing physical PCI configuration space, to be added to extended_apis and to provide a foundation for more advanced PCI functionality.
The class suggested below provides register access by offset, as well as a set of methods to access named registers. This API will be simple to extend in the future to support the extended configuration space for PCIe, once we have the necessary tools to locate and map the physical memory region used for ECAM.
API is architecture-independent as PCI is not specific to x64; ARM should eventually have an implementation too.
phys_pci
class definition