diff --git a/include/sbi/sbi_irqchip.h b/include/sbi/sbi_irqchip.h index c3ded271..d2c47ae8 100644 --- a/include/sbi/sbi_irqchip.h +++ b/include/sbi/sbi_irqchip.h @@ -21,6 +21,9 @@ struct sbi_irqchip_device { /** Node in the list of irqchip devices */ struct sbi_dlist node; + /** Unique ID of this irqchip */ + u32 id; + /** Set of harts targetted by this irqchip */ struct sbi_hartmask target_harts; @@ -41,6 +44,9 @@ struct sbi_irqchip_device { */ int sbi_irqchip_process(void); +/** Find an irqchip device based on unique ID */ +struct sbi_irqchip_device *sbi_irqchip_find_device(u32 id); + /** Register an irqchip device to receive callbacks */ int sbi_irqchip_add_device(struct sbi_irqchip_device *chip); diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c index d3e58288..5df6189b 100644 --- a/lib/sbi/sbi_irqchip.c +++ b/lib/sbi/sbi_irqchip.c @@ -30,6 +30,18 @@ int sbi_irqchip_process(void) return hd->chip->process_hwirqs(hd->chip); } +struct sbi_irqchip_device *sbi_irqchip_find_device(u32 id) +{ + struct sbi_irqchip_device *chip; + + sbi_list_for_each_entry(chip, &irqchip_list, node) { + if (chip->id == id) + return chip; + } + + return NULL; +} + int sbi_irqchip_add_device(struct sbi_irqchip_device *chip) { struct sbi_irqchip_hart_data *hd; @@ -39,6 +51,9 @@ int sbi_irqchip_add_device(struct sbi_irqchip_device *chip) if (!chip || !sbi_hartmask_weight(&chip->target_harts)) return SBI_EINVAL; + if (sbi_irqchip_find_device(chip->id)) + return SBI_EALREADY; + if (chip->process_hwirqs) { sbi_hartmask_for_each_hartindex(h, &chip->target_harts) { scratch = sbi_hartindex_to_scratch(h); diff --git a/lib/utils/irqchip/aplic.c b/lib/utils/irqchip/aplic.c index ea5cb7c4..d47a810b 100644 --- a/lib/utils/irqchip/aplic.c +++ b/lib/utils/irqchip/aplic.c @@ -306,6 +306,7 @@ int aplic_cold_irqchip_init(struct aplic_data *aplic) } /* Register irqchip device */ + aplic->irqchip.id = aplic->unique_id; rc = sbi_irqchip_add_device(&aplic->irqchip); if (rc) return rc; diff --git a/lib/utils/irqchip/imsic.c b/lib/utils/irqchip/imsic.c index 5ec9dff4..0f296c89 100644 --- a/lib/utils/irqchip/imsic.c +++ b/lib/utils/irqchip/imsic.c @@ -391,6 +391,7 @@ int imsic_cold_irqchip_init(struct imsic_data *imsic) } /* Register irqchip device */ + imsic_device.id = imsic->unique_id; sbi_hartmask_set_all(&imsic_device.target_harts); rc = sbi_irqchip_add_device(&imsic_device); if (rc) diff --git a/lib/utils/irqchip/plic.c b/lib/utils/irqchip/plic.c index 25cc2787..973f7c2a 100644 --- a/lib/utils/irqchip/plic.c +++ b/lib/utils/irqchip/plic.c @@ -280,6 +280,7 @@ int plic_cold_irqchip_init(struct plic_data *plic) } /* Register irqchip device */ + plic->irqchip.id = plic->unique_id; plic->irqchip.warm_init = plic_warm_irqchip_init; return sbi_irqchip_add_device(&plic->irqchip); }