From 06d554e8e64851502f104d27de98b81d7e3ae1f3 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 3 Jul 2025 16:56:12 +0200 Subject: [PATCH] build: restore interrupt.h files to fix AMD Zephyr build Turns out that two XTOS-specific interrupt.h files deleted by b8266ae003a0 ("build: delete more XTOS-only files") and d07ac0993ad1 ("build: remove obvioux XTOS-only files") breaks AMD Zephyr builds, restore them to the state before those commits. Signed-off-by: Guennadi Liakhovetski --- .../xtensa/include/arch/drivers/interrupt.h | 97 ++++++++ xtos/include/rtos/interrupt.h | 217 ++++++++++++++++++ 2 files changed, 314 insertions(+) create mode 100644 src/arch/xtensa/include/arch/drivers/interrupt.h create mode 100644 xtos/include/rtos/interrupt.h diff --git a/src/arch/xtensa/include/arch/drivers/interrupt.h b/src/arch/xtensa/include/arch/drivers/interrupt.h new file mode 100644 index 000000000000..c1a9306c59a5 --- /dev/null +++ b/src/arch/xtensa/include/arch/drivers/interrupt.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2016 Intel Corporation. All rights reserved. + * + * Author: Liam Girdwood + */ + +#ifdef __SOF_DRIVERS_INTERRUPT_H__ + +#ifndef __ARCH_DRIVERS_INTERRUPT_H__ +#define __ARCH_DRIVERS_INTERRUPT_H__ + +#include +#include +#include +#include + + +static inline int arch_interrupt_register(int irq, + void (*handler)(void *arg), void *arg) +{ + xthal_set_intclear(0x1 << irq); + _xtos_set_interrupt_handler_arg(irq, handler, arg); + return 0; +} + +static inline void arch_interrupt_unregister(int irq) +{ + _xtos_set_interrupt_handler_arg(irq, NULL, NULL); +} + +/* returns previous mask */ +#define arch_interrupt_enable_mask(mask) \ + _xtos_ints_on(mask) + +/* returns previous mask */ +#define arch_interrupt_disable_mask(mask) \ + _xtos_ints_off(mask) + +static inline uint32_t arch_interrupt_get_level(void) +{ + uint32_t level; + + __asm__ __volatile__( + " rsr.ps %0\n" + " extui %0, %0, 0, 4\n" + : "=&a" (level) :: "memory"); + + return level; +} + +static inline void arch_interrupt_set(int irq) +{ + xthal_set_intset(0x1 << irq); +} + +static inline void arch_interrupt_clear(int irq) +{ + xthal_set_intclear(0x1 << irq); +} + +static inline uint32_t arch_interrupt_get_enabled(void) +{ + return xthal_get_intenable(); +} + +static inline uint32_t arch_interrupt_get_status(void) +{ + return xthal_get_interrupt(); +} + +static inline uint32_t arch_interrupt_global_disable(void) +{ + uint32_t flags; + + __asm__ __volatile__("rsil %0, 5" + : "=a" (flags) :: "memory"); + return flags; +} + +static inline void arch_interrupt_global_enable(uint32_t flags) +{ + __asm__ __volatile__("wsr %0, ps; rsync" + :: "a" (flags) : "memory"); +} + +#if CONFIG_WAKEUP_HOOK +void arch_interrupt_on_wakeup(void); +#endif + +#endif /* __ARCH_DRIVERS_INTERRUPT_H__ */ + +#else + +#error "This file shouldn't be included from outside of sof/drivers/interrupt.h" + +#endif /* __SOF_INTERRUPT_H__ */ diff --git a/xtos/include/rtos/interrupt.h b/xtos/include/rtos/interrupt.h new file mode 100644 index 000000000000..58cefae94c81 --- /dev/null +++ b/xtos/include/rtos/interrupt.h @@ -0,0 +1,217 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2018 Intel Corporation. All rights reserved. + * + * Author: Janusz Jankowski + */ + +#ifndef __SOF_DRIVERS_INTERRUPT_H__ +#define __SOF_DRIVERS_INTERRUPT_H__ + +#include + +#if !defined(__ASSEMBLER__) && !defined(LINKER) +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * \brief child IRQ descriptor for cascading IRQ controllers. + */ +struct irq_child { + int enable_count[CONFIG_CORE_COUNT]; /**< IRQ enable counter */ + struct list_item list; /**< head for IRQ descriptors, + * sharing this interrupt + */ +}; + +/** + * \brief interrupt client descriptor + */ +struct irq_desc { + int irq; /**< virtual IRQ number */ + void (*handler)(void *arg); /**< interrupt handler function */ + void *handler_arg; /**< interrupt handler argument */ + uint32_t cpu_mask; /**< a mask of CPUs on which this + * interrupt is enabled + */ + struct list_item irq_list; /**< to link to other irq_desc */ +}; + +/** + * \brief cascading IRQ controller operations. + */ +struct irq_cascade_ops { + void (*mask)(struct irq_desc *desc, uint32_t irq, + unsigned int cpu); /**< mask */ + void (*unmask)(struct irq_desc *desc, uint32_t irq, + unsigned int cpu); /**< unmask */ +}; + +/** + * \brief cascading interrupt controller descriptor. + */ +struct irq_cascade_desc { + const char *name; /**< name of the + * controller + */ + int irq_base; /**< first virtual IRQ + * number, assigned to + * this controller + */ + const struct irq_cascade_ops *ops; /**< cascading interrupt + * controller driver + * operations + */ + struct irq_desc desc; /**< the interrupt, that + * this controller is + * generating + */ + struct irq_cascade_desc *next; /**< link to the global + * list of interrupt + * controllers + */ + bool global_mask; /**< the controller + * cannot mask input + * interrupts per core + */ + struct k_spinlock lock; /**< protect child + * lists, enable and + * child counters + */ + int enable_count[CONFIG_CORE_COUNT]; /**< enabled child + * interrupt counter + */ + unsigned int num_children[CONFIG_CORE_COUNT]; /**< number of children + */ + struct irq_child child[PLATFORM_IRQ_CHILDREN]; /**< array of child + * lists - one per + * multiplexed IRQ + */ +}; + +/* A descriptor for cascading interrupt controller template */ +struct irq_cascade_tmpl { + const char *name; + const struct irq_cascade_ops *ops; + int irq; + void (*handler)(void *arg); + bool global_mask; +}; + +/** + * \brief Cascading interrupt controller root. + */ +struct cascade_root { + struct k_spinlock lock; /**< locking mechanism */ + struct irq_cascade_desc *list; /**< list of child cascade irqs */ + int last_irq; /**< last registered cascade irq */ +}; + +static inline struct cascade_root *cascade_root_get(void) +{ + return sof_get()->cascade_root; +} + +/* For i.MX, while building SOF with Zephyr use the interrupt_* + * functions from second level interrupt handling and IRQ_STEER. + */ +#if defined(__ZEPHYR__) && (defined(CONFIG_IMX) || defined(CONFIG_AMD)) +int mux_interrupt_get_irq(unsigned int irq, const char *cascade); +int mux_interrupt_register(uint32_t irq, void(*handler)(void *arg), void *arg); +void mux_interrupt_unregister(uint32_t irq, const void *arg); +uint32_t mux_interrupt_enable(uint32_t irq, void *arg); +uint32_t mux_interrupt_disable(uint32_t irq, void *arg); +#endif + +int interrupt_register(uint32_t irq, void(*handler)(void *arg), void *arg); +void interrupt_unregister(uint32_t irq, const void *arg); +uint32_t interrupt_enable(uint32_t irq, void *arg); +uint32_t interrupt_disable(uint32_t irq, void *arg); + +/* Zephyr compat */ +#if !defined(__ZEPHYR__) +#define arch_irq_lock() arch_interrupt_disable_mask(0xffffffff) +#endif + +void platform_interrupt_init(void); + +void platform_interrupt_set(uint32_t irq); +void platform_interrupt_clear(uint32_t irq, uint32_t mask); +uint32_t platform_interrupt_get_enabled(void); +void interrupt_mask(uint32_t irq, unsigned int cpu); +void interrupt_unmask(uint32_t irq, unsigned int cpu); + +/* + * On platforms, supporting cascading interrupts cascaded interrupt numbers + * are greater than or equal to PLATFORM_IRQ_HW_NUM + */ +#define interrupt_is_dsp_direct(irq) (!PLATFORM_IRQ_CHILDREN || \ + irq < PLATFORM_IRQ_HW_NUM) + +void interrupt_init(struct sof *sof); +int interrupt_cascade_register(const struct irq_cascade_tmpl *tmpl); +struct irq_cascade_desc *interrupt_get_parent(uint32_t irq); +int interrupt_get_irq(unsigned int irq, const char *cascade); + +static inline void interrupt_set(int irq) +{ + platform_interrupt_set(irq); +} + +static inline void interrupt_clear_mask(int irq, uint32_t mask) +{ + platform_interrupt_clear(irq, mask); +} + +static inline void interrupt_clear(int irq) +{ + interrupt_clear_mask(irq, 1); +} + +static inline uint32_t interrupt_global_disable(void) +{ + return arch_interrupt_global_disable(); +} + +static inline void interrupt_global_enable(uint32_t flags) +{ + arch_interrupt_global_enable(flags); +} + +#if CONFIG_LIBRARY + +/* temporary fix to remove build warning for testbench that will need shortly + * realigned when Zephyr native APIs are used. + */ +static inline void __irq_local_disable(unsigned long flags) {} +static inline void __irq_local_enable(unsigned long flags) {} + +/* disables all IRQ sources on current core - NO effect on library */ +#define irq_local_disable(flags) \ + do { \ + flags = 0; \ + __irq_local_disable(flags); \ + } while (0) + +/* re-enables IRQ sources on current core - NO effect on library*/ +#define irq_local_enable(flags) \ + __irq_local_enable(flags) + +#else +/* disables all IRQ sources on current core */ +#define irq_local_disable(flags) \ + (flags = interrupt_global_disable()) + +/* re-enables IRQ sources on current core */ +#define irq_local_enable(flags) \ + interrupt_global_enable(flags) +#endif +#endif +#endif /* __SOF_DRIVERS_INTERRUPT_H__ */