Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Axi bus behind the DMA engine #1878

Open
wants to merge 7 commits into
base: main-2.x
Choose a base branch
from
Open

Add Axi bus behind the DMA engine #1878

wants to merge 7 commits into from

Conversation

ArthurHeymans
Copy link
Contributor

This rewrites the DMA engine to operate on the Axi bus which is a 64bit bus.
The recovery register interface is placed on that bus.
An Axi address offset is placed in soc_ifc.


/// Represents an abstract AXI memory bus. Used to read and write from RAM and
/// peripheral addresses.
pub trait AxiBus {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I absolutely hate this copy-paste. Why didn't we just increase the address size to 64-bit everywhere?

Copy link
Collaborator

@korran korran Jan 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(assuming the only reason for this change is the increased word size): my preference:

  1. Use 64-bit addresses and data in Bus trait everywhere; the 32-bit parts could ignore the high bits and error when size is 64-bit.
  2. If that's not workable for some reason we could add associated types to the existing bus trait:
trait Bus {
  type Addr: num_traits::PrimInt + num_traits::Unsigned + From<u32>;
  type Data: num_traits::PrimInt + num_traits::Unsigned + From<u32>;

  fn read(&mut self, addr: Self::Addr) -> Result<Self::Data, ()>;
  // ...
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

poll and reset() could be moved to their own separate trait if necessary.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree I don't love the copy-pasta, especially for the derive macros and the register types.

I like the idea of 64-bit everywhere, maybe either with a type parameter or a function that specifies whether 64-bit is allowed.

Another idea that I think would be okay: keep the separate AxiBus trait for read64/write64, but don't support derive. Instead, use autogeneration to automatically create the AxiBus implementation. (This is the approach we are mostly using in the MCU, for example: /~https://github.com/chipsalliance/caliptra-mcu-sw/blob/main/registers/generated-emulator/src/root_bus.rs).

Or only support the dynamic bus.

Since the AXI bus doesn't need to be quite as flexible as the main bus, I think it might be okay to go the autogenerated route.

Copy link
Contributor Author

@ArthurHeymans ArthurHeymans Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@korran both these approaches require a lot of code changes all across the emulator code.

I think the simplest things is to implement the toplevel axi_root_bus by hand, which dispatches to Bus. This removes the possibility to do 64bit load/store, but I don't think those are needed.

@ArthurHeymans ArthurHeymans force-pushed the AxiBus branch 3 times, most recently from 25a9e87 to ba108e4 Compare January 8, 2025 17:09
Copy link
Contributor

@swenson swenson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to keep the I3C RDL and autogenerated code. I have a PR I am working on that adapts the DMA driver to implement the ureg::Mmio and ureg::MmioMut interfaces, so that we can use the autogenerated I3C code and not write everything manually.

match addr {
Self::TEST_REG_OFFSET => return Register::read(&self.reg, size),
Self::RECOVERY_REGISTER_INTERFACE_OFFSET..=Self::RECOVERY_REGISTER_INTERFACE_END => {
let addr = (addr - Self::RECOVERY_REGISTER_INTERFACE_OFFSET) as RvAddr;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the address subtracted from Self::RECOVERY_REGISTER_INTERFACE_OFFSET?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's how busses work in the sw-emulator: All peripherals gets load and stores values that are relative to their own base.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw derive Bus macro results in very similar code.

Copy link
Collaborator

@mhatrevi mhatrevi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see the feedback.

@ArthurHeymans ArthurHeymans force-pushed the AxiBus branch 2 times, most recently from 1707e05 to 0879541 Compare January 15, 2025 09:14
@ArthurHeymans ArthurHeymans force-pushed the AxiBus branch 2 times, most recently from 13b95e9 to 5ea6b54 Compare January 15, 2025 09:20
There was confusion on how that the dma engine operated on a axi bus
that replaced the apb bus. This is not true. AXI is a completely
separate bus and the DMA widget is a bridge to it.

Signed-off-by: Arthur Heymans <arthur.heymans@9elements.com>
DMA operates on a separate bus and not the root bus so remove it.

Signed-off-by: Arthur Heymans <arthur.heymans@9elements.com>
This rewrites the dma widget to work with a separate axi_root_bus bus.

Signed-off-by: Arthur Heymans <arthur.heymans@9elements.com>
This also adds the offset in the soc_ifc registers.

Signed-off-by: Arthur Heymans <arthur.heymans@9elements.com>
Reading the production debug fuses needs this.

Signed-off-by: Arthur Heymans <arthur.heymans@9elements.com>
Signed-off-by: Arthur Heymans <arthur.heymans@9elements.com>
Don't use memcpy as this results in unaligned reads on the DMA FIFO
read/write registers.

Signed-off-by: Arthur Heymans <arthur.heymans@9elements.com>
@ArthurHeymans
Copy link
Contributor Author

I would like to keep the I3C RDL and autogenerated code. I have a PR I am working on that adapts the DMA driver to implement the ureg::Mmio and ureg::MmioMut interfaces, so that we can use the autogenerated I3C code and not write everything manually.

Done

@ArthurHeymans
Copy link
Contributor Author

Please see the feedback.

Addressed it all.

I also added some driver and other fixes that should make your test branch get further.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Caliptra v2.0 Items to be considered for v2.0 Release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants