Forum Discussion
Interrup numbers of Arria 10 EDAC
Hello,
If we look at the example section below of the device tree, we can state the following:
intc: interrupt-controller@ffffd000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; interrupt-controller; reg = <0xffffd000 0x1000>, <0xffffc100 0x100>; };
soc { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; device_type = "soc"; interrupt-parent = <&intc>; ranges; :
eccmgr: eccmgr { compatible = "altr,socfpga-a10-ecc-manager"; altr,sysmgr-syscon = <&sysmgr>; #address-cells = <1>; #size-cells = <1>; interrupts = <0 2 IRQ_TYPE_LEVEL_HIGH>, <0 0 IRQ_TYPE_LEVEL_HIGH>; interrupt-controller; #interrupt-cells = <2>;
sdramedac { compatible = "altr,sdram-edac-a10"; altr,sdr-syscon = <&sdr>; interrupts = <17 IRQ_TYPE_LEVEL_HIGH>, <49 IRQ_TYPE_LEVEL_HIGH>; };
l2-ecc@ffd06010 { compatible = "altr,socfpga-a10-l2-ecc"; reg = <0xffd06010 0x4>; interrupts = <0 IRQ_TYPE_LEVEL_HIGH>, <32 IRQ_TYPE_LEVEL_HIGH>; }; :
}; }; |
- intc node corresponds to the node related to the GIC in the Arria10 devices. The interrupt-controller; filed indicates that this is an interrupt controller and the #interrupt-cells indicates that the interrupts defined here will receive 3 parameters: the interrupt type, the interrupt number and the interrupt trigger. The possible value for interrupt type are:
The interrupt number parameter describes the peripheral ID that causes the interrupt, but since the 1st parameter (interrupt type) already defines the type, this seems to be using an offset 0 instead of 32 or 16. If we look into the table 88 in the TRM at https://www.intel.com/content/www/us/en/docs/programmable/683711/22-3/gic-interrupt-map-for-the-arria-10-soc-hps.html it defines the interrupt mappings for the SPI interrupt type, but we need to use the interrupt number as (interrupt ID - 32). The last parameter (interrupt trigger) defines how the interrupt is triggered like rising/falling edge or high/low level.
- The soc node indicates that this is an interrupt child of the intc node as indicated in the interrupt-parent field, so any node defined under this that doesn’t include an interrupt-parent field, will inherit the interrupt controller of this.
- The eccmgr node is a child of the soc node and inherits the intc and its interrupt controller. In this node are defined 2 SPI interrupts with interrupt-number of 0 and 2 (IDs 32 and 34). Looking at the table 88 in the TRM, these are System Manager related interrupts used to capture DERR/SERR maybe derived from ECC errors coming from different devices. Also observe in the last column in table 88 that the trigger of these interrupts Level, so this matches the definition in the interrupts as its indicated as IRQ_TYPE_LEVEL_HIGH. In this node we also see interrupt-controller field which indicates that this node is also considered as a interrupt-controller, but in this case seems that this is used to indicate different possible sources that could generate the interrupt. These normally have some kind of status register that indicates the source of the interrupt triggering. This also defines that any child of this node will inherits this interrupt controller and will use 2 parameters through the #interrupt-cells field. The 2 parameters that this interrupt controller receives are the interrupt ID (a bit in a mask that indicates the source of the interrupt) and the trigger type of the interrupt. For the ECC manager, seems that these bits are defined in the ecc_intmask_value register under the System Manager:https://www.intel.com/content/www/us/en/programmable/hps/arria-10/hps.html#topic/sfo1429890615426.html
- The sdramedac, l2-ecc and other nodes are child of the eccmgr node which also have as the eccmgr as interrupt controller parent. These defines their own interrupts with 2 parameters. For example, in the case of sdramedac it defines the interrupt number 17 and 49. The 17 seems to be related to ddr0 as indicated in the ecc_intmask_value register. I am not sure about the 2nd interrupt defined, but the value of this one corresponds to the 1st value + 32. Not sure if the 1st one targets CPU0 and the 2nd one targets CPU1. Same thing with the l2-ecc node, in which defines the interrupt number of 0 and 32. Also, the bit 0 corresponds to the l2 in the ecc_intmask_value register and the 2nd interrupt has an offset of 32 compared with the 1st one. These seems to match to all the nodes under the eccmgr node.
Hope this might help.
Fawaz.
Hi Fawaz,
Thank you for your detailed explanation! The hint and information to the bit field helped to understand the entries...
I updated the device tree according to your description and added the ECC node for EMAC1:
emac1-rx-ecc@ff8c1000 { compatible = "altr,socfpga-eth-mac-ecc"; reg = <0xff8c1000 0x400>; altr,ecc-parent = <&gmac1>; interrupts = <6 IRQ_TYPE_LEVEL_HIGH>, <38 IRQ_TYPE_LEVEL_HIGH>; }; emac1-tx-ecc@ff8c1400 { compatible = "altr,socfpga-eth-mac-ecc"; reg = <0xff8c1400 0x400>; altr,ecc-parent = <&gmac1>; interrupts = <7 IRQ_TYPE_LEVEL_HIGH>, <39 IRQ_TYPE_LEVEL_HIGH>; };
However for some reason, the kernel is still not booting anymore with the active EMAC driver. As said I followed the documentation: https://www.rocketboards.org/foswiki/Documentation/EnableL2CacheECCInLinux?erpm_id=6579622_ts1753093952709 which results in the failure.
I tried two things. First, exactly according to the documentation. In another test, I just enabled the Altera SOCFPGA ECC driver (without any of the sub-drivers). But in both cases, the kernel is not booting anymore.
What is wrong with the settings? Is there any other changes required?