-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Feature request: Plugin-friendly API for initiating bus transactions from abstract_device_t implementations
Hi,
We're building a plugin that implements a device using the abstract_device_t interface. The device receives MMIO callbacks as expected. However, the device is also a bus master and needs to initiate its own bus transactions — e.g. write to DRAM, read/write to other MMIO devices, and perform DMA-like operations — rather than only respond to accesses initiated by the core.
Current situation
Inside an abstract_device_t, the only API we directly receive is:
virtual bool load(reg_t addr, size_t len, uint8_t* bytes) = 0;
virtual bool store(reg_t addr, size_t len, const uint8_t* bytes) = 0;These correctly handle inbound MMIO transactions targeting our device.
But there is no exposed mechanism for issuing outbound transactions from the device back into the system.
The only internally available path appears to be using sim_t::debug_mmu to manually perform physical loads and stores. In practice this works, but it has important drawbacks:
• debug_mmu is a debug facility, not intended for device-level data movement.
• Its code path includes TLB/MMU/debug logic that has nothing to do with simple bus routing.
• Depending on it couples plugins to Spike’s internal debug/MMU implementation details, which makes long-term maintenance fragile.
Spike already has the correct abstractions — bus_t, mmio_load, mmio_store — but they are currently internal.
Why devices need outbound bus access
Device-initiated memory operations are common in hardware models. Some examples:
• DMA engines: A device may need to transfer buffers between memories.
• Inter-device communication: One device may need to update registers in another device (e.g. mailbox, status registers, interrupt controllers).
These are conceptually simple bus transactions: “read/write N bytes at physical address P through the simulator’s bus.”
Request / proposal
Would it be possible to expose a stable, plugin-facing API for device-initiated bus accesses?
For example, one of the following would be extremely useful:
- Expose
sim_t::mmio_load/sim_t::mmio_store(or a newbus_load/bus_store) as public functions, callable fromabstract_device_timplementations:
bool bus_load(reg_t paddr, size_t len, uint8_t* bytes);
bool bus_store(reg_t paddr, size_t len, const uint8_t* bytes);These would route through the same bus_t and device map that Spike already uses internally.
- Provide a supported way for devices to obtain a reference to a dedicated “bus accessor” object, so that a plugin device can simply do:
accessor->bus_store(phys_addr, len, data);The main goal is to avoid relying on debug_mmu for what is fundamentally neither a debug operation nor an MMU operation.
Questions
- Is there an existing recommended mechanism for device-initiated physical memory accesses that I may have missed?
- If not, would exposing a small, stable API for bus transactions from plugins be something the maintainers would consider?
- If there is a preferred design direction (e.g., exposing via
sim_tor via a new “bus” handle), I would be happy to prototype a patch accordingly.
Thanks for Spike and for considering this.