1 /* 2 * Copyright (c) 2018 Intel Corporation. 3 * Copyright (c) 2024 Meta. 4 * 5 * SPDX-License-Identifier: Apache-2.0 6 */ 7 8 #include <zephyr/sw_isr_table.h> 9 #include <zephyr/sys/util.h> 10 11 /** 12 * @file 13 * @brief This file houses the deprecated legacy macros-generated multi-level interrupt lookup 14 * table code, compiled when `CONFIG_LEGACY_MULTI_LEVEL_TABLE_GENERATION` is enabled. 15 */ 16 17 /* 18 * Insert code if the node_id is an interrupt controller 19 */ 20 #define Z_IF_DT_IS_INTC(node_id, code) \ 21 IF_ENABLED(DT_NODE_HAS_PROP(node_id, interrupt_controller), (code)) 22 23 /* 24 * Expands to node_id if its IRQN is equal to `_irq`, nothing otherwise 25 * This only works for `_irq` between 0 & 4095, see `IS_EQ` 26 */ 27 #define Z_IF_DT_INTC_IRQN_EQ(node_id, _irq) IF_ENABLED(IS_EQ(DT_IRQ(node_id, irq), _irq), (node_id)) 28 29 /* 30 * Expands to node_id if it's an interrupt controller & its IRQN is `irq`, or nothing otherwise 31 */ 32 #define Z_DT_INTC_GET_IRQN(node_id, _irq) \ 33 Z_IF_DT_IS_INTC(node_id, Z_IF_DT_INTC_IRQN_EQ(node_id, _irq)) 34 35 /** 36 * Loop through child of "/soc" and get root interrupt controllers with `_irq` as IRQN, 37 * this assumes only one device has the IRQN 38 * @param _irq irq number 39 * @return node_id(s) that has the `_irq` number, or empty if none of them has the `_irq` 40 */ 41 #define INTC_DT_IRQN_GET(_irq) \ 42 DT_FOREACH_CHILD_STATUS_OKAY_VARGS(DT_PATH(soc), Z_DT_INTC_GET_IRQN, _irq) 43 44 #define INIT_IRQ_PARENT_OFFSET_2ND(n, d, i, o) \ 45 IRQ_PARENT_ENTRY_DEFINE(intc_l2_##n, DEVICE_DT_GET_OR_NULL(d), i, o, 2) 46 47 #define IRQ_INDEX_TO_OFFSET(i, base) (base + i * CONFIG_MAX_IRQ_PER_AGGREGATOR) 48 49 #define CAT_2ND_LVL_LIST(i, base) \ 50 INIT_IRQ_PARENT_OFFSET_2ND(i, INTC_DT_IRQN_GET(CONFIG_2ND_LVL_INTR_0##i##_OFFSET), \ 51 CONFIG_2ND_LVL_INTR_0##i##_OFFSET, \ 52 IRQ_INDEX_TO_OFFSET(i, base)) 53 54 LISTIFY(CONFIG_NUM_2ND_LEVEL_AGGREGATORS, CAT_2ND_LVL_LIST, (;), CONFIG_2ND_LVL_ISR_TBL_OFFSET); 55 56 #ifdef CONFIG_3RD_LEVEL_INTERRUPTS 57 58 BUILD_ASSERT((CONFIG_NUM_3RD_LEVEL_AGGREGATORS * CONFIG_MAX_IRQ_PER_AGGREGATOR) <= 59 BIT(CONFIG_3RD_LEVEL_INTERRUPT_BITS), 60 "L3 bits not enough to cover the number of L3 IRQs"); 61 62 #define INIT_IRQ_PARENT_OFFSET_3RD(n, d, i, o) \ 63 IRQ_PARENT_ENTRY_DEFINE(intc_l3_##n, DEVICE_DT_GET_OR_NULL(d), i, o, 3) 64 65 #define CAT_3RD_LVL_LIST(i, base) \ 66 INIT_IRQ_PARENT_OFFSET_3RD(i, INTC_DT_IRQN_GET(CONFIG_3RD_LVL_INTR_0##i##_OFFSET), \ 67 CONFIG_3RD_LVL_INTR_0##i##_OFFSET, \ 68 IRQ_INDEX_TO_OFFSET(i, base)) 69 70 LISTIFY(CONFIG_NUM_3RD_LEVEL_AGGREGATORS, CAT_3RD_LVL_LIST, (;), CONFIG_3RD_LVL_ISR_TBL_OFFSET); 71 72 #endif /* CONFIG_3RD_LEVEL_INTERRUPTS */ 73