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

Some XIRQ documentation oddities #568

Closed
drgrandios opened this issue Apr 4, 2023 · 7 comments · Fixed by #570
Closed

Some XIRQ documentation oddities #568

drgrandios opened this issue Apr 4, 2023 · 7 comments · Fixed by #570

Comments

@drgrandios
Copy link

  1. I think there is a missing ~ in the description how to reset the pending interrupt (in https://github.com/stnolting/neorv32/blob/main/docs/datasheet/soc_xirq.adoc )

To acknowledge the according interrupt the CPU can write 1 << SCR to IPR.

The IPR register expects a 0 to reset the bit.

  1. I'm not really sure if it's just me or if this sentence is misleading:

In order to clear a pending FIRQ interrupt from the external interrupt controller again, the according [_mip] CSR bit has to be cleared.
Additionally, the XIRQ interrupt has to be acknowledged by writing any value to the interrupt source register SRC.

The CSR_MIP_MEIP flag is read-only. It is implicitly reset when a) the XIRQ pending bits are reset and b) a write access to SRC happened - right?

  1. The SRC register is called IRQ_SRC in the VHDL sources. Within the documentation, it is referenced as "SCR" several times (especially in the register map at the bottom). I suppose this is meant to be "SRC" all the time, right?
@drgrandios
Copy link
Author

drgrandios commented Apr 4, 2023

Okay, I was wrong with 2... XIRQ is connected to FIRQ8. I always thought it would be connected to MEI like the PLIC of other RISCV implementations.

I.e. a full IRQ reset is

  1. reset pending bit in IPR = ~(1<<SRC)
  2. acknowledge interrupt by write to SRC (any value)
  3. reset FIRQ by write (1<<24) to MIP (corresponds to FIRQ8)

@stnolting
Copy link
Owner

Hey @drgrandios!
Thanks for the hints! I think the XIRQ sections needs an overdue makeover 😅
I'll take care of that.

@stnolting stnolting linked a pull request Apr 5, 2023 that will close this issue
@drgrandios
Copy link
Author

Very nice, thank you!

Are there any plans to add a (SiFive) PLIC-based ( https://raw.githubusercontent.com/riscv/riscv-plic-spec/master/riscv-plic-1.0.0.pdf ) interface somewhen in the future? Would make it easier to have NEORV32 compatible code run in QEMU.

Doesn't have to be fully compliant - for 32 IRQs, I guess it would be enough to have the XIRQ registers mapped to

pending: 0xC000000 + 0x1000
enable: 0xC000000 + 0x2000
src: 0xC000000 + 0x200004 (claim+complete)

Pending reset would need to be modified - the PLIC resets a single pending interrupt when reading the claim register. The IRQ itself is acknowledged when writing back the claim register. And of course, the IRQ needs to be connected to MEI instead of FIRQ8...

@stnolting
Copy link
Owner

Are there any plans to add a (SiFive) PLIC-based ( https://raw.githubusercontent.com/riscv/riscv-plic-spec/master/riscv-plic-1.0.0.pdf ) interface somewhen in the future?

I thought about this. But right now I do not see any reason to add this to the processor. The PLIC is quite powerful providing lots and lots of configuration option - which is obvious as it is (also) intended for multi-core systems running rich desktop-like operating systems. Even when constraint to the minimal configuration options a PLIC would still consume a significant amount of logic resources (i.e. it occupies 16MB of address space).

However, the machine external interrupt (MEI) is available as top entity signal for custom purpose. So it would be possible to attach a PLIC externally to the processor 😉

@stnolting
Copy link
Owner

I am doing some reworks of the XIRQ module right now (#570). I am not sure if this would be really helpful, but we could try to make it "more PLIC-compatible"..?! 🤔

@drgrandios
Copy link
Author

drgrandios commented Apr 7, 2023

For me it would be helpful... but I'm not sure if it would help others. I'm using an abused version of QEMU at work anyway and already made it work (at least partly) with your current implementation.

But I think it would help when thinking about (software) cross-platform compatibility. E.g. to allow switching between NEORV32, Pulp or even a NOEL-V without a mess of preprocessor defines everywhere. But this is also an issue with all the other non-standard FIRQs.

I can understand if cross-platform is not your main development goal ;-)

For PLIC "compliance" with the current functionality of the XIRQ module, I don't think it is necessary to occupy the full address space - only the minimum set of registers to configure the 32 IRQs. Ignore the whole PLIC priority configuration (maybe allow r/o access to a static configuration that is similar to the current priorities in XIRQ) and put the existing XIRQ registers at the addresses of e.g. the SiFive PLIC (because this is used in many implementations as well as QEMU).

You could have a look at the external_handler function here to see how PLIC reset works for SiFive:

https://github.com/sifive/plic-baremetal/blob/master/plic-baremetal.c

edit: But maybe this should then be an additional "mini-PLIC" module instead of XIRQ, or not? Because it would break existing implementations...

@stnolting
Copy link
Owner

To have a "fully" compatible behavior of the XIRQ, the entire PLIC address space needs to be populated as the according HAL would require access to all these locations... But compatibility would still fail as the XIRQ CPU interrupt is routed to a FIRQ instead of MEI... 🙈

So I think it having an external PLIC module would be the way to go. Maybe there is an open-source version available (Pulp)?!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants