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

arch: sw_isr: store device info in the table and add funtions to access #63172

Merged
merged 6 commits into from
Nov 9, 2023

Conversation

ycsin
Copy link
Member

@ycsin ycsin commented Sep 27, 2023

Change the internal function to get_parent_entry, which returns the entire entry of table.

Store the parent interrupt controller device in the irq_parent_offset table, and added 2 helper functions to:

  1. determine the parent interrupt controller based on the IRQ
  2. determine the IRQ of the parent interrupt controller

Declare the struct _irq_parent_entry in the header and added so that it can be used to test the functions in testsuites.

Note

This change will increase the LUT size for build with multi-level enabled by CONFIG_NUM_x_LEVEL_AGGREGATORS * sizeof(struct device)


Note

This PR is spined off from #62907, to hopefully make it easier to review, and is required to fix #63465

Important

Blocking #62907

galak
galak previously requested changes Sep 27, 2023
Copy link
Collaborator

@galak galak left a comment

Choose a reason for hiding this comment

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

We should NOT add a property for has-multi-instance to the devicetree, but scan the tree in some way to get the count of instances to determine its greater than 1.

@ycsin ycsin force-pushed the pr/sw_isr_changes branch 2 times, most recently from f66a225 to 9d7918d Compare September 28, 2023 04:23
@ycsin
Copy link
Member Author

ycsin commented Sep 28, 2023

@cfriedt @galak the has-multi-instance prop was misleading, I was using it as a shortcut to get the controller that this implementation supports.

This implementation doesn't support INTMUX, i.e. intc_rv32m1_intmux, a single instance of it has multiple interrupts as child:

intmux0: intmux@4004f000 {
compatible = "openisa,rv32m1-intmux";
reg = <0x4004f000 0x200>;
clocks = <&pcc0 0x13c>;
status = "disabled";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x0 0x4004f000 0x200>;
intmux0_ch0: interrupt-controller@0 {
compatible = "openisa,rv32m1-intmux-ch";
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-controller;
interrupts = <INTMUX_CH0_IRQ>;
reg = <0x0 0x40>;
status = "disabled";
};
intmux0_ch1: interrupt-controller@40 {
compatible = "openisa,rv32m1-intmux-ch";
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-controller;
interrupts = <INTMUX_CH1_IRQ>;
reg = <0x40 0x40>;
status = "disabled";
};
intmux0_ch2: interrupt-controller@80 {
compatible = "openisa,rv32m1-intmux-ch";
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-controller;
interrupts = <INTMUX_CH2_IRQ>;
reg = <0x80 0x40>;
status = "disabled";
};
intmux0_ch3: interrupt-controller@c0 {
compatible = "openisa,rv32m1-intmux-ch";
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-controller;
interrupts = <INTMUX_CH3_IRQ>;
reg = <0xc0 0x40>;
status = "disabled";
};
intmux0_ch4: interrupt-controller@100 {
compatible = "openisa,rv32m1-intmux-ch";
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-controller;
interrupts = <INTMUX_CH4_IRQ>;
reg = <0x100 0x40>;
status = "disabled";
};
intmux0_ch5: interrupt-controller@140 {
compatible = "openisa,rv32m1-intmux-ch";
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-controller;
interrupts = <INTMUX_CH5_IRQ>;
reg = <0x140 0x40>;
status = "disabled";
};
intmux0_ch6: interrupt-controller@180 {
compatible = "openisa,rv32m1-intmux-ch";
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-controller;
interrupts = <INTMUX_CH6_IRQ>;
reg = <0x180 0x40>;
status = "disabled";
};
intmux0_ch7: interrupt-controller@1c0 {
compatible = "openisa,rv32m1-intmux-ch";
#address-cells = <0>;
#interrupt-cells = <1>;
interrupt-controller;
interrupts = <INTMUX_CH7_IRQ>;
reg = <0x1c0 0x40>;
status = "disabled";
};
};

I've updated the filter to grab the interrupt controller that is the direct child of /soc instead, to just get the root interrupt controllers

@jhedberg jhedberg added this to the v3.5.0 milestone Oct 11, 2023
jhedberg
jhedberg previously approved these changes Oct 11, 2023
@zephyrbot zephyrbot added platform: Intel ADSP Intel Audio platforms area: Xtensa Xtensa Architecture labels Nov 6, 2023
@zephyrbot zephyrbot requested a review from lyakh November 6, 2023 04:19
Change the internal function to `get_parent_entry`, which
returns the entire entry of table.

Store the parent interrupt controller device in the
`irq_parent_offset` table, and added 2 helper functions to:

1. determine the parent interrupt controller based on the IRQ
2. determine the IRQ of the parent interrupt controller

Declare the `struct _irq_parent_entry` in the header and added
`-` suffix to the struct so that it can be used to test the
functions in testsuites.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Validate the following functions in the sw_isr_table:
- z_get_sw_isr_table_idx
- z_get_sw_isr_device_from_irq
- z_get_sw_isr_irq_from_device

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Relocate new and existing internal software-managed table
access functions from the public `sw_isr_table.h` into a
private header that should only be accessed internally.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
@ycsin ycsin removed the area: Xtensa Xtensa Architecture label Nov 6, 2023
@ycsin ycsin removed the request for review from lyakh November 6, 2023 06:34
Refactor multi-level IRQ related code from `sw_isr_common.c` to
`multilevel_irq.c` to simplify `sw_isr_common` & macrologies.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Instead of using a macro guard to prevent functions in
`sw_isr_common.c` from getting compiled when
`CONFIG_DYNAMIC_INTERRUPTS` isn't enabled, do that in
`CMakeLists.txt` instead.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
Convert `#if defined CONFIG_*` to use
`if (IS_ENABLED(CONFIG_*))` and removed some macro guards since
they are safe to be compile.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
@ycsin ycsin requested a review from cfriedt November 6, 2023 13:00
@carlescufi carlescufi requested review from rakons and removed request for peter-mitsis November 6, 2023 14:15

#ifdef CONFIG_3RD_LEVEL_INTERRUPTS

const struct _irq_parent_entry _lvl3_irq_list[CONFIG_NUM_3RD_LEVEL_AGGREGATORS]
Copy link
Member

Choose a reason for hiding this comment

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

Does this need to be conditionally defined?

E.g. can we remove the ifdef above, use if (IS_ENABLED()) elsewhere, and let the linker discard unused code and data?

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah it fails to compile as the initialization used some undefined macros when 3rd level isn't enabled

Copy link
Member

@fkokosinski fkokosinski left a comment

Choose a reason for hiding this comment

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

LGTM from the perspective of #62907.

@carlescufi
Copy link
Member

@dcpleung can you take a look?

Copy link
Member

@dcpleung dcpleung left a comment

Choose a reason for hiding this comment

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

TBH... we should probably start looking into DAG or tree-like hierarchy for multi-level interrupts so we can avoid making this even complicated in the future.

@ycsin
Copy link
Member Author

ycsin commented Nov 8, 2023

TBH... we should probably start looking into DAG or tree-like hierarchy for multi-level interrupts so we can avoid making this even complicated in the future.

Where can I read more about this? Any existing implementation?

@dcpleung
Copy link
Member

dcpleung commented Nov 8, 2023

Maybe the Linux kernel? The idea is (probably) simple, where each interrupt controller is a node in a tree. For multi-level interrupts, each node is a child of some other node (except the root node). So you can have arbitrary levels of interrupts, and each controller can trace back to the root controller. Though, this is an overhaul of interrupt handling and is going to be a huge project... for soul(s) brave enough to tackle it.

@cfriedt
Copy link
Member

cfriedt commented Nov 8, 2023

Maybe the Linux kernel?

Yep. Linux would suffice. Of course, it's mostly about the model. The model will also drastically simplify shared interrupts with a marginal increase in complexity. It's also more stateful.

Zephyr's multi-level model (maybe surprisingly) started out simple too, of course 🤪

@carlescufi carlescufi merged commit 7485ef9 into zephyrproject-rtos:main Nov 9, 2023
26 checks passed
@ycsin ycsin deleted the pr/sw_isr_changes branch December 18, 2023 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

arch: riscv: support for multi-instance multi-level interrupt
10 participants