diff options
97 files changed, 2146 insertions, 1096 deletions
diff --git a/bsps/aarch64/include/dev/irq/arm-gic-arch.h b/bsps/aarch64/include/dev/irq/arm-gic-arch.h index f1b6fdc03d..5ca2c7314e 100644 --- a/bsps/aarch64/include/dev/irq/arm-gic-arch.h +++ b/bsps/aarch64/include/dev/irq/arm-gic-arch.h @@ -3,9 +3,10 @@ /** * @file * - * @ingroup RTEMSBSPsAArch64Shared + * @ingroup DevIRQGIC * - * @brief AArch64-specific ARM GICv3 handlers. + * @brief This header file provides interfaces of the ARM Generic Interrupt + * Controller (GIC) support specific to the AArch64 architecture. */ /* @@ -46,14 +47,24 @@ extern "C" { #endif -static inline void arm_interrupt_handler_dispatch(rtems_vector_number vector) +/** + * @addtogroup DevIRQGIC + * + * @{ + */ + +static inline uint32_t arm_interrupt_enable_interrupts(void) { - uint32_t interrupt_level = _CPU_ISR_Get_level(); + uint32_t status = _CPU_ISR_Get_level(); /* Enable interrupts for nesting */ _CPU_ISR_Set_level(0); - bsp_interrupt_handler_dispatch(vector); + return status; +} + +static inline void arm_interrupt_restore_interrupts(uint32_t status) +{ /* Restore interrupts to previous level */ - _CPU_ISR_Set_level(interrupt_level); + _CPU_ISR_Set_level(status); } static inline void arm_interrupt_facility_set_exception_handler(void) @@ -68,6 +79,8 @@ static inline void arm_interrupt_facility_set_exception_handler(void) ); } +/** @} */ + #ifdef __cplusplus } #endif diff --git a/bsps/aarch64/raspberrypi/include/bsp/irq.h b/bsps/aarch64/raspberrypi/include/bsp/irq.h index effec1b040..d493e83707 100644 --- a/bsps/aarch64/raspberrypi/include/bsp/irq.h +++ b/bsps/aarch64/raspberrypi/include/bsp/irq.h @@ -9,6 +9,7 @@ /** * Copyright (c) 2013 Alan Cudmore * Copyright (c) 2022 Mohd Noor Aman + * Copyright (c) 2024 Ning Yang * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -23,14 +24,8 @@ #ifndef ASM #include <rtems.h> -#include <rtems/irq.h> -#include <rtems/irq-extension.h> #include <dev/irq/arm-gic-irq.h> -#if defined(RTEMS_SMP) -#include <rtems/score/processormask.h> -#endif - /** * @defgroup raspberrypi_interrupt Interrrupt Support * @@ -39,15 +34,18 @@ * @brief Interrupt support. */ -#define BCM2835_INTC_TOTAL_IRQ (64 + 8) +#define BCM2835_INTC_TOTAL_IRQ 216 #define BCM2835_IRQ_SET1_MIN 0 #define BCM2835_IRQ_SET2_MIN 32 -#define BCM2835_IRQ_ID_GPU_TIMER_M0 0 -#define BCM2835_IRQ_ID_GPU_TIMER_M1 1 -#define BCM2835_IRQ_ID_GPU_TIMER_M2 2 -#define BCM2835_IRQ_ID_GPU_TIMER_M3 3 +#define BCM2711_IRQ_VC_PERIPHERAL_BASE 96 + +/* Interrupt Vectors: System Timer */ +#define BCM2835_IRQ_ID_GPU_TIMER_M0 (BCM2711_IRQ_VC_PERIPHERAL_BASE + 0) +#define BCM2835_IRQ_ID_GPU_TIMER_M1 (BCM2711_IRQ_VC_PERIPHERAL_BASE + 1) +#define BCM2835_IRQ_ID_GPU_TIMER_M2 (BCM2711_IRQ_VC_PERIPHERAL_BASE + 2) +#define BCM2835_IRQ_ID_GPU_TIMER_M3 (BCM2711_IRQ_VC_PERIPHERAL_BASE + 3) #define BCM2835_IRQ_ID_USB 9 #define BCM2835_IRQ_ID_AUX 29 @@ -83,27 +81,5 @@ #define BSP_IRQ_COUNT (BCM2835_INTC_TOTAL_IRQ) -#if defined(RTEMS_SMP) -static inline rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -) -{ - (void) vector; - (void) affinity; - return RTEMS_UNSATISFIED; -} - -static inline rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -) -{ - (void) vector; - _Processor_mask_From_index( affinity, 0 ); - return RTEMS_UNSATISFIED; -} -#endif - #endif /* ASM */ #endif /* LIBBSP_ARM_RASPBERRYPI_IRQ_H */ diff --git a/bsps/aarch64/raspberrypi/include/bsp/raspberrypi.h b/bsps/aarch64/raspberrypi/include/bsp/raspberrypi.h index 55dd9ed1e9..f185d1df57 100644 --- a/bsps/aarch64/raspberrypi/include/bsp/raspberrypi.h +++ b/bsps/aarch64/raspberrypi/include/bsp/raspberrypi.h @@ -8,6 +8,7 @@ /* * Copyright (c) 2022 Mohd Noor Aman + * Copyright (c) 2024 Ning Yang * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -44,6 +45,7 @@ #define BCM2711_REG(x) (*(volatile uint64_t *)(x)) #define BCM2711_BIT(n) (1 << (n)) +#define BCM2835_REG(addr) (*(volatile uint32_t*)(addr)) /** @} */ @@ -198,6 +200,13 @@ #define BCM2711_GPU_TIMER_C2 (BCM2711_GPU_TIMER_BASE + 0x14) #define BCM2711_GPU_TIMER_C3 (BCM2711_GPU_TIMER_BASE + 0x18) +/** + * NOTE: compatible with the BCM2835 system timer + */ +#define BCM2835_GPU_TIMER_CS_M3 BCM2711_GPU_TIMER_CS_M3 +#define BCM2835_GPU_TIMER_C3 BCM2711_GPU_TIMER_C3 +#define BCM2835_GPU_TIMER_CLO BCM2711_GPU_TIMER_CLO +#define BCM2835_GPU_TIMER_CS BCM2711_GPU_TIMER_CS /** @} */ /** diff --git a/bsps/aarch64/xilinx-zynqmp/console/console.c b/bsps/aarch64/xilinx-zynqmp/console/console.c index 9ce0b1da63..4023d5c6f3 100644 --- a/bsps/aarch64/xilinx-zynqmp/console/console.c +++ b/bsps/aarch64/xilinx-zynqmp/console/console.c @@ -35,7 +35,6 @@ */ #include <rtems/console.h> -#include <rtems/bspIo.h> #include <rtems/endian.h> #include <rtems/sysinit.h> #include <rtems/termiostypes.h> @@ -45,6 +44,7 @@ #include <bsp/irq.h> #include <dev/serial/zynq-uart.h> +#include <dev/serial/zynq-uart-regs.h> #include <bspopts.h> #include <libfdt.h> @@ -187,11 +187,11 @@ RTEMS_SYSINIT_ITEM( static zynq_uart_context zynqmp_uart_instances[2] = { { .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ), - .regs = (volatile struct zynq_uart *) 0xff000000, + .regs = (volatile zynq_uart *) ZYNQ_UART_0_BASE_ADDR, .irq = ZYNQMP_IRQ_UART_0 }, { .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ), - .regs = (volatile struct zynq_uart *) 0xff010000, + .regs = (volatile zynq_uart *) ZYNQ_UART_1_BASE_ADDR, .irq = ZYNQMP_IRQ_UART_1 } }; @@ -207,6 +207,7 @@ rtems_status_code console_initialize( rtems_termios_initialize(); for (i = 0; i < RTEMS_ARRAY_SIZE(zynqmp_uart_instances); ++i) { + zynq_uart_context *ctx = &zynqmp_uart_instances[i]; char uart[] = "/dev/ttySX"; uart[sizeof(uart) - 2] = (char) ('0' + i); @@ -214,10 +215,10 @@ rtems_status_code console_initialize( &uart[0], &zynq_uart_handler, NULL, - &zynqmp_uart_instances[i].base + &ctx->base ); - if (i == BSP_CONSOLE_MINOR) { + if (ctx->regs == (zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR) { link(&uart[0], CONSOLE_DEVICE_NAME); } } @@ -236,50 +237,5 @@ rtems_status_code console_initialize( void zynqmp_debug_console_flush(void) { - zynq_uart_reset_tx_flush(&zynqmp_uart_instances[BSP_CONSOLE_MINOR]); + zynq_uart_reset_tx_flush((zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR); } - -static void zynqmp_debug_console_out(char c) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_write_polled(base, c); -} - -static void zynqmp_debug_console_init(void) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_initialize(base); - BSP_output_char = zynqmp_debug_console_out; -} - -static void zynqmp_debug_console_early_init(char c) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_initialize(base); - BSP_output_char = zynqmp_debug_console_out; - zynqmp_debug_console_out(c); -} - -static int zynqmp_debug_console_in(void) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - return zynq_uart_read_polled(base); -} - -BSP_output_char_function_type BSP_output_char = zynqmp_debug_console_early_init; - -BSP_polling_getchar_function_type BSP_poll_char = zynqmp_debug_console_in; - -RTEMS_SYSINIT_ITEM( - zynqmp_debug_console_init, - RTEMS_SYSINIT_BSP_START, - RTEMS_SYSINIT_ORDER_LAST_BUT_5 -); diff --git a/bsps/aarch64/xilinx-zynqmp/include/bsp.h b/bsps/aarch64/xilinx-zynqmp/include/bsp.h index 0ccca8b196..38a9fad768 100644 --- a/bsps/aarch64/xilinx-zynqmp/include/bsp.h +++ b/bsps/aarch64/xilinx-zynqmp/include/bsp.h @@ -55,6 +55,8 @@ #include <rtems.h> #include <rtems/termiostypes.h> +#include <dev/serial/zynq-uart-zynqmp.h> + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ diff --git a/bsps/arm/include/dev/irq/arm-gic-arch.h b/bsps/arm/include/dev/irq/arm-gic-arch.h index c9931be61a..f6c8b5d426 100644 --- a/bsps/arm/include/dev/irq/arm-gic-arch.h +++ b/bsps/arm/include/dev/irq/arm-gic-arch.h @@ -3,9 +3,10 @@ /** * @file * - * @ingroup RTEMSBSPsARMShared + * @ingroup DevIRQGIC * - * @brief ARM-specific IRQ handlers. + * @brief This header file provides interfaces of the ARM Generic Interrupt + * Controller (GIC) support specific to the Arm architecture. */ /* @@ -44,12 +45,20 @@ extern "C" { #endif -static inline void arm_interrupt_handler_dispatch(rtems_vector_number vector) +/** + * @addtogroup DevIRQGIC + * + * @{ + */ + +static inline uint32_t arm_interrupt_enable_interrupts(void) { - uint32_t psr = _ARMV4_Status_irq_enable(); - bsp_interrupt_handler_dispatch(vector); + return _ARMV4_Status_irq_enable(); +} - _ARMV4_Status_restore(psr); +static inline void arm_interrupt_restore_interrupts(uint32_t status) +{ + _ARMV4_Status_restore(status); } static inline void arm_interrupt_facility_set_exception_handler(void) @@ -60,6 +69,8 @@ static inline void arm_interrupt_facility_set_exception_handler(void) */ } +/** @} */ + #ifdef __cplusplus } #endif diff --git a/bsps/arm/raspberrypi/include/bsp/irq.h b/bsps/arm/raspberrypi/include/bsp/irq.h index 6801b01d84..895b268dfe 100644 --- a/bsps/arm/raspberrypi/include/bsp/irq.h +++ b/bsps/arm/raspberrypi/include/bsp/irq.h @@ -22,12 +22,6 @@ #ifndef ASM #include <rtems.h> -#include <rtems/irq.h> -#include <rtems/irq-extension.h> - -#if defined(RTEMS_SMP) -#include <rtems/score/processormask.h> -#endif /** * @defgroup raspberrypi_interrupt Interrrupt Support @@ -78,27 +72,5 @@ #define BSP_IRQ_COUNT (BCM2835_INTC_TOTAL_IRQ) -#if defined(RTEMS_SMP) -static inline rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -) -{ - (void) vector; - (void) affinity; - return RTEMS_UNSATISFIED; -} - -static inline rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -) -{ - (void) vector; - _Processor_mask_From_index( affinity, 0 ); - return RTEMS_UNSATISFIED; -} -#endif - #endif /* ASM */ #endif /* LIBBSP_ARM_RASPBERRYPI_IRQ_H */ diff --git a/bsps/arm/raspberrypi/irq/irq.c b/bsps/arm/raspberrypi/irq/irq.c index 30e10e5aec..7177cd2c05 100644 --- a/bsps/arm/raspberrypi/irq/irq.c +++ b/bsps/arm/raspberrypi/irq/irq.c @@ -19,7 +19,6 @@ #include <rtems/score/armv4.h> #include <bsp.h> -#include <bsp/irq.h> #include <bsp/irq-generic.h> #include <bsp/raspberrypi.h> #include <bsp/linker-symbols.h> @@ -207,6 +206,28 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +#if defined(RTEMS_SMP) +rtems_status_code bsp_interrupt_get_affinity( + rtems_vector_number vector, + Processor_mask *affinity +) +{ + (void) vector; + _Processor_mask_From_index( affinity, 0 ); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_set_affinity( + rtems_vector_number vector, + const Processor_mask *affinity +) +{ + (void) vector; + (void) affinity; + return RTEMS_UNSATISFIED; +} +#endif + void bsp_interrupt_handler_default(rtems_vector_number vector) { printk("spurious interrupt: %" PRIdrtems_vector_number "\n", vector); diff --git a/bsps/arm/xen/include/bsp/irq.h b/bsps/arm/xen/include/bsp/irq.h index 58ce78ffd2..e64fde3037 100644 --- a/bsps/arm/xen/include/bsp/irq.h +++ b/bsps/arm/xen/include/bsp/irq.h @@ -40,7 +40,7 @@ extern "C" { #endif /* __cplusplus */ -#define BSP_INTERRUPT_VECTOR_COUNT 1024 +#define BSP_INTERRUPT_VECTOR_COUNT 1019 /* Xen guest interrupts */ #define GUEST_TIMER_VIRT_PPI 27 diff --git a/bsps/arm/xilinx-zynq/console/console-init.c b/bsps/arm/xilinx-zynq/console/console-init.c index 72fa27da11..2018aaa710 100644 --- a/bsps/arm/xilinx-zynq/console/console-init.c +++ b/bsps/arm/xilinx-zynq/console/console-init.c @@ -29,7 +29,22 @@ #include <rtems/termiostypes.h> #include <bsp.h> +#include <bsp/bootcard.h> +#include <bsp/irq.h> #include <dev/serial/zynq-uart.h> +#include <dev/serial/zynq-uart-regs.h> + +static zynq_uart_context zynq_uart_instances[2] = { + { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ), + .regs = (volatile zynq_uart *) ZYNQ_UART_0_BASE_ADDR, + .irq = ZYNQ_IRQ_UART_0 + }, { + .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ), + .regs = (volatile zynq_uart *) ZYNQ_UART_1_BASE_ADDR, + .irq = ZYNQ_IRQ_UART_1 + } +}; rtems_status_code console_initialize( rtems_device_major_number major, @@ -42,6 +57,7 @@ rtems_status_code console_initialize( rtems_termios_initialize(); for (i = 0; i < RTEMS_ARRAY_SIZE(zynq_uart_instances); ++i) { + zynq_uart_context *ctx = &zynq_uart_instances[i]; char uart[] = "/dev/ttySX"; uart[sizeof(uart) - 2] = (char) ('0' + i); @@ -49,10 +65,10 @@ rtems_status_code console_initialize( &uart[0], &zynq_uart_handler, NULL, - &zynq_uart_instances[i].base + &ctx->base ); - if (i == BSP_CONSOLE_MINOR) { + if (ctx->regs == (zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR) { link(&uart[0], CONSOLE_DEVICE_NAME); } } diff --git a/bsps/arm/xilinx-zynq/include/bsp.h b/bsps/arm/xilinx-zynq/include/bsp.h index 3311a99b50..151e603812 100644 --- a/bsps/arm/xilinx-zynq/include/bsp.h +++ b/bsps/arm/xilinx-zynq/include/bsp.h @@ -54,7 +54,7 @@ #include <bsp/default-initial-extension.h> #include <bsp/start.h> -#include <dev/serial/zynq-uart.h> +#include <dev/serial/zynq-uart-zynq.h> #ifdef __cplusplus extern "C" { @@ -74,8 +74,6 @@ extern "C" { #define BSP_ARM_L2C_310_ID 0x410000c8 -extern zynq_uart_context zynq_uart_instances[2]; - /** * @brief Zynq specific set up of the MMU. * diff --git a/bsps/arm/xilinx-zynq/start/bspreset.c b/bsps/arm/xilinx-zynq/start/bspreset.c index f8cc3b6999..b6cf09ba02 100644 --- a/bsps/arm/xilinx-zynq/start/bspreset.c +++ b/bsps/arm/xilinx-zynq/start/bspreset.c @@ -35,14 +35,16 @@ #include <bsp.h> #include <bsp/bootcard.h> -#include <dev/serial/zynq-uart.h> +#include <dev/serial/zynq-uart-regs.h> void bsp_reset(void) { + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; volatile uint32_t *slcr_unlock = (volatile uint32_t *) 0xf8000008; volatile uint32_t *pss_rst_ctrl = (volatile uint32_t *) 0xf8000200; - zynq_uart_reset_tx_flush(&zynq_uart_instances[BSP_CONSOLE_MINOR]); + zynq_uart_reset_tx_flush(regs); while (true) { *slcr_unlock = 0xdf0d; diff --git a/bsps/arm/xilinx-zynqmp-rpu/console/console-config.c b/bsps/arm/xilinx-zynqmp-rpu/console/console-config.c index f52e008f2b..db03d1e9f3 100644 --- a/bsps/arm/xilinx-zynqmp-rpu/console/console-config.c +++ b/bsps/arm/xilinx-zynqmp-rpu/console/console-config.c @@ -32,22 +32,22 @@ #include <rtems/console.h> #include <rtems/bspIo.h> -#include <rtems/sysinit.h> #include <rtems/termiostypes.h> #include <bsp/irq.h> #include <dev/serial/zynq-uart.h> +#include <dev/serial/zynq-uart-regs.h> #include <bspopts.h> static zynq_uart_context zynqmp_uart_instances[2] = { { .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ), - .regs = (volatile struct zynq_uart *) 0xff000000, + .regs = (volatile zynq_uart *) ZYNQ_UART_0_BASE_ADDR, .irq = ZYNQMP_IRQ_UART_0 }, { .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ), - .regs = (volatile struct zynq_uart *) 0xff010000, + .regs = (volatile zynq_uart *) ZYNQ_UART_1_BASE_ADDR, .irq = ZYNQMP_IRQ_UART_1 } }; @@ -61,6 +61,7 @@ rtems_status_code console_initialize( size_t i; for (i = 0; i < RTEMS_ARRAY_SIZE(zynqmp_uart_instances); ++i) { + zynq_uart_context *ctx = &zynqmp_uart_instances[i]; char uart[] = "/dev/ttySX"; uart[sizeof(uart) - 2] = (char) ('0' + i); @@ -68,10 +69,10 @@ rtems_status_code console_initialize( &uart[0], &zynq_uart_handler, NULL, - &zynqmp_uart_instances[i].base + &ctx->base ); - if (i == BSP_CONSOLE_MINOR) { + if (ctx->regs == (zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR) { link(&uart[0], CONSOLE_DEVICE_NAME); } } @@ -81,49 +82,5 @@ rtems_status_code console_initialize( void zynqmp_debug_console_flush(void) { - zynq_uart_reset_tx_flush(&zynqmp_uart_instances[BSP_CONSOLE_MINOR]); + zynq_uart_reset_tx_flush((zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR); } - -static void zynqmp_debug_console_out(char c) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_write_polled(base, c); -} - -static void zynqmp_debug_console_init(void) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_initialize(base); - BSP_output_char = zynqmp_debug_console_out; -} - -static void zynqmp_debug_console_early_init(char c) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_initialize(base); - zynqmp_debug_console_out(c); -} - -static int zynqmp_debug_console_in(void) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - return zynq_uart_read_polled(base); -} - -BSP_output_char_function_type BSP_output_char = zynqmp_debug_console_early_init; - -BSP_polling_getchar_function_type BSP_poll_char = zynqmp_debug_console_in; - -RTEMS_SYSINIT_ITEM( - zynqmp_debug_console_init, - RTEMS_SYSINIT_BSP_START, - RTEMS_SYSINIT_ORDER_LAST_BUT_5 -); diff --git a/bsps/arm/xilinx-zynqmp-rpu/include/bsp.h b/bsps/arm/xilinx-zynqmp-rpu/include/bsp.h index e386bd4b26..70ad4f3c57 100644 --- a/bsps/arm/xilinx-zynqmp-rpu/include/bsp.h +++ b/bsps/arm/xilinx-zynqmp-rpu/include/bsp.h @@ -59,7 +59,8 @@ #include <bsp/default-initial-extension.h> #include <bsp/start.h> -#include <peripheral_maps/xilinx_zynqmp.h> + +#include <dev/serial/zynq-uart-zynqmp.h> #ifdef __cplusplus extern "C" { @@ -74,8 +75,6 @@ extern "C" { #define BSP_ARM_A9MPCORE_GT_BASE 0 -#define BSP_SELECTED_TTC_ADDR ZYNQMP_TTC0 - /** * @brief Zynq UltraScale+ MPSoC specific set up of the MMU. * diff --git a/bsps/arm/xilinx-zynqmp-rpu/include/bsp/irq.h b/bsps/arm/xilinx-zynqmp-rpu/include/bsp/irq.h index a65e5404f0..51aa613cdd 100644 --- a/bsps/arm/xilinx-zynqmp-rpu/include/bsp/irq.h +++ b/bsps/arm/xilinx-zynqmp-rpu/include/bsp/irq.h @@ -51,7 +51,6 @@ extern "C" { #endif /* __cplusplus */ -#define BSP_SELECTED_TTC_IRQ ZYNQMP_IRQ_TTC_0_0 #define BSP_INTERRUPT_VECTOR_COUNT 188 /** @} */ diff --git a/bsps/arm/xilinx-zynqmp/console/console-config.c b/bsps/arm/xilinx-zynqmp/console/console-config.c index eadd7f11a2..550e930415 100644 --- a/bsps/arm/xilinx-zynqmp/console/console-config.c +++ b/bsps/arm/xilinx-zynqmp/console/console-config.c @@ -32,22 +32,22 @@ #include <rtems/console.h> #include <rtems/bspIo.h> -#include <rtems/sysinit.h> #include <rtems/termiostypes.h> #include <bsp/irq.h> #include <dev/serial/zynq-uart.h> +#include <dev/serial/zynq-uart-regs.h> #include <bspopts.h> static zynq_uart_context zynqmp_uart_instances[2] = { { .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ), - .regs = (volatile struct zynq_uart *) 0xff000000, + .regs = (volatile zynq_uart *) ZYNQ_UART_0_BASE_ADDR, .irq = ZYNQMP_IRQ_UART_0 }, { .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ), - .regs = (volatile struct zynq_uart *) 0xff010000, + .regs = (volatile zynq_uart *) ZYNQ_UART_1_BASE_ADDR, .irq = ZYNQMP_IRQ_UART_1 } }; @@ -63,6 +63,7 @@ rtems_status_code console_initialize( rtems_termios_initialize(); for (i = 0; i < RTEMS_ARRAY_SIZE(zynqmp_uart_instances); ++i) { + zynq_uart_context *ctx = &zynqmp_uart_instances[i]; char uart[] = "/dev/ttySX"; uart[sizeof(uart) - 2] = (char) ('0' + i); @@ -70,10 +71,10 @@ rtems_status_code console_initialize( &uart[0], &zynq_uart_handler, NULL, - &zynqmp_uart_instances[i].base + &ctx->base ); - if (i == BSP_CONSOLE_MINOR) { + if (ctx->regs == (zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR) { link(&uart[0], CONSOLE_DEVICE_NAME); } } @@ -83,49 +84,5 @@ rtems_status_code console_initialize( void zynqmp_debug_console_flush(void) { - zynq_uart_reset_tx_flush(&zynqmp_uart_instances[BSP_CONSOLE_MINOR]); + zynq_uart_reset_tx_flush((zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR); } - -static void zynqmp_debug_console_out(char c) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_write_polled(base, c); -} - -static void zynqmp_debug_console_init(void) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_initialize(base); - BSP_output_char = zynqmp_debug_console_out; -} - -static void zynqmp_debug_console_early_init(char c) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - zynq_uart_initialize(base); - zynqmp_debug_console_out(c); -} - -static int zynqmp_debug_console_in(void) -{ - rtems_termios_device_context *base = - &zynqmp_uart_instances[BSP_CONSOLE_MINOR].base; - - return zynq_uart_read_polled(base); -} - -BSP_output_char_function_type BSP_output_char = zynqmp_debug_console_early_init; - -BSP_polling_getchar_function_type BSP_poll_char = zynqmp_debug_console_in; - -RTEMS_SYSINIT_ITEM( - zynqmp_debug_console_init, - RTEMS_SYSINIT_BSP_START, - RTEMS_SYSINIT_ORDER_LAST_BUT_5 -); diff --git a/bsps/arm/xilinx-zynqmp/include/bsp.h b/bsps/arm/xilinx-zynqmp/include/bsp.h index a08a5feee9..cdc37b79a4 100644 --- a/bsps/arm/xilinx-zynqmp/include/bsp.h +++ b/bsps/arm/xilinx-zynqmp/include/bsp.h @@ -60,6 +60,8 @@ #include <bsp/default-initial-extension.h> #include <bsp/start.h> +#include <dev/serial/zynq-uart-zynqmp.h> + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ diff --git a/bsps/i386/shared/irq/irq.c b/bsps/i386/shared/irq/irq.c index fe43bc1d7c..3f85c69812 100644 --- a/bsps/i386/shared/irq/irq.c +++ b/bsps/i386/shared/irq/irq.c @@ -15,6 +15,7 @@ #include <bsp/irq.h> #include <bsp/irq-generic.h> #include <rtems/score/cpu.h> +#include <rtems/score/processormaskimpl.h> #include <stdlib.h> #include <stdio.h> @@ -295,6 +296,17 @@ rtems_status_code bsp_interrupt_raise(rtems_vector_number vector) return RTEMS_UNSATISFIED; } +#if defined(RTEMS_SMP) +rtems_status_code bsp_interrupt_raise_on( + rtems_vector_number vector, + uint32_t cpu_index +) +{ + bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); + return RTEMS_UNSATISFIED; +} +#endif + rtems_status_code bsp_interrupt_clear(rtems_vector_number vector) { bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector)); @@ -326,6 +338,28 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +#if defined(RTEMS_SMP) +rtems_status_code bsp_interrupt_get_affinity( + rtems_vector_number vector, + Processor_mask *affinity +) +{ + (void) vector; + _Processor_mask_From_index( affinity, 0 ); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_set_affinity( + rtems_vector_number vector, + const Processor_mask *affinity +) +{ + (void) vector; + (void) affinity; + return RTEMS_UNSATISFIED; +} +#endif + void bsp_interrupt_facility_initialize(void) { int i; diff --git a/bsps/include/bsp/fatal.h b/bsps/include/bsp/fatal.h index ffdb4bc8e1..87fc481ead 100644 --- a/bsps/include/bsp/fatal.h +++ b/bsps/include/bsp/fatal.h @@ -214,6 +214,9 @@ typedef enum { /* MicroBlaze fatal codes */ MICROBLAZE_FATAL_CLOCK_IRQ_INSTALL = BSP_FATAL_CODE_BLOCK(16), + + /* Xilinx fatal codes */ + XIL_FATAL_TTC_IRQ_INSTALL = BSP_FATAL_CODE_BLOCK(17), } bsp_fatal_code; RTEMS_NO_RETURN static inline void diff --git a/bsps/include/bsp/irq-generic.h b/bsps/include/bsp/irq-generic.h index 5ed9cac688..3aef0be855 100644 --- a/bsps/include/bsp/irq-generic.h +++ b/bsps/include/bsp/irq-generic.h @@ -12,7 +12,7 @@ /* * Copyright (C) 2016 Chris Johns <chrisj@rtems.org> * - * Copyright (C) 2008, 2021 embedded brains GmbH & Co. KG + * Copyright (C) 2008, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -47,6 +47,7 @@ #include <rtems/irq-extension.h> #include <rtems/score/assert.h> +#include <rtems/score/processormask.h> #ifdef RTEMS_SMP #include <rtems/score/atomic.h> @@ -372,6 +373,55 @@ rtems_status_code bsp_interrupt_raise_on( */ rtems_status_code bsp_interrupt_clear( rtems_vector_number vector ); +/** + * @brief Gets the processor affinity set of the interrupt vector. + * + * The function may have no implementation in uniprocessor configurations. + * + * @param vector is the interrupt vector number. + * + * @param[out] affinity is the pointer to a Processor_mask object. When the + * directive call is successful, the processor affinity set of the interrupt + * vector will be stored in this object. A set bit in the processor set + * means that the corresponding processor is in the processor affinity set of + * the interrupt vector, otherwise the bit is cleared. + * + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. + * + * @retval ::RTEMS_UNSATISFIED The request to get the processor affinity of the + * interrupt vector has not been satisfied. + */ +rtems_status_code bsp_interrupt_get_affinity( + rtems_vector_number vector, + Processor_mask *affinity +); + +/** + * @brief Sets the processor affinity set of the interrupt vector. + * + * The function may have no implementation in uniprocessor configurations. + * + * @param vector is the interrupt vector number. It shall be valid. + * + * @param affinity is the pointer to a Processor_mask object. The processor set + * defines the new processor affinity set of the interrupt vector. A set bit + * in the processor set means that the corresponding processor shall be in + * the processor affinity set of the interrupt vector, otherwise the bit + * shall be cleared. + * + * @retval ::RTEMS_SUCCESSFUL The requested operation was successful. + * + * @retval ::RTEMS_INVALID_NUMBER The referenced processor set was not a valid + * new processor affinity set for the interrupt vector. + * + * @retval ::RTEMS_UNSATISFIED The request to set the processor affinity of the + * interrupt vector has not been satisfied. + */ +rtems_status_code bsp_interrupt_set_affinity( + rtems_vector_number vector, + const Processor_mask *affinity +); + #if defined(RTEMS_SMP) /** * @brief Handles a spurious interrupt. @@ -417,7 +467,7 @@ static inline void bsp_interrupt_entry_store_release( #if defined(RTEMS_SMP) _Atomic_Store_uintptr( (Atomic_Uintptr *) ptr, - (Atomic_Uintptr) value, + (uintptr_t) value, ATOMIC_ORDER_RELEASE ); #else diff --git a/bsps/include/dev/irq/arm-gic-irq.h b/bsps/include/dev/irq/arm-gic-irq.h index b3487176f6..c3615a12a0 100644 --- a/bsps/include/dev/irq/arm-gic-irq.h +++ b/bsps/include/dev/irq/arm-gic-irq.h @@ -1,11 +1,12 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /** - * @file + * @file * - * @ingroup arm_gic + * @ingroup DevIRQGIC * - * @brief ARM GIC IRQ + * @brief This header file provides interfaces of the ARM Generic Interrupt + * Controller (GIC) support. */ /* @@ -38,12 +39,17 @@ #include <bsp.h> #include <dev/irq/arm-gic.h> -#include <rtems/score/processormask.h> #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +/** + * @addtogroup DevIRQGIC + * + * @{ + */ + #define ARM_GIC_IRQ_SGI_0 0 #define ARM_GIC_IRQ_SGI_1 1 #define ARM_GIC_IRQ_SGI_2 2 @@ -85,16 +91,6 @@ rtems_status_code arm_gic_irq_get_group( gic_group *group ); -rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -); - -rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -); - void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets); static inline rtems_status_code arm_gic_irq_generate_software_irq( @@ -119,6 +115,8 @@ uint32_t arm_gic_irq_processor_count(void); void arm_gic_irq_initialize_secondary_cpu(void); #endif +/** @} */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bsps/include/dev/irq/arm-gic-regs.h b/bsps/include/dev/irq/arm-gic-regs.h index 097ff67c13..c03a7a7a07 100644 --- a/bsps/include/dev/irq/arm-gic-regs.h +++ b/bsps/include/dev/irq/arm-gic-regs.h @@ -1,11 +1,12 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /** - * @file + * @file * - * @ingroup arm_gic + * @ingroup DevIRQGIC * - * @brief ARM GIC Register definitions + * @brief This header file provides interfaces of the ARM Generic Interrupt + * Controller (GIC) memory-mapped registers. */ /* @@ -38,6 +39,12 @@ #include <bsp/utility.h> +/** + * @addtogroup DevIRQGIC + * + * @{ + */ + typedef struct { uint32_t iccicr; #define GIC_CPUIF_ICCICR_CBPR BSP_BIT32(4) @@ -225,4 +232,6 @@ typedef struct { uint32_t icspigrpmodr[64]; } gic_sgi_ppi; +/** @} */ + #endif /* LIBBSP_ARM_SHARED_ARM_GIC_REGS_H */ diff --git a/bsps/include/dev/irq/arm-gic-tm27.h b/bsps/include/dev/irq/arm-gic-tm27.h index f2a16afae3..70e76c7603 100644 --- a/bsps/include/dev/irq/arm-gic-tm27.h +++ b/bsps/include/dev/irq/arm-gic-tm27.h @@ -1,11 +1,12 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /** - * @file + * @file * - * @ingroup arm_gic + * @ingroup DevIRQGIC * - * @brief ARM GIC TM27 Support + * @brief This header file provides the TM27 support for the ARM Generic + * Interrupt Controller (GIC). */ /* diff --git a/bsps/include/dev/irq/arm-gic.h b/bsps/include/dev/irq/arm-gic.h index 73c9a688d5..4e418de68f 100644 --- a/bsps/include/dev/irq/arm-gic.h +++ b/bsps/include/dev/irq/arm-gic.h @@ -1,11 +1,12 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /** - * @file + * @file * - * @ingroup arm_gic + * @ingroup DevIRQGIC * - * @brief ARM GIC Support + * @brief This header file provides interfaces of the ARM Generic Interrupt + * Controller (GIC) support. */ /* @@ -45,11 +46,14 @@ extern "C" { #endif /* __cplusplus */ /** - * @defgroup arm_gic ARM GIC + * @defgroup DevIRQGIC ARM Generic Interrupt Controller (GIC) Support * - * @ingroup RTEMSBSPsARMShared + * @ingroup RTEMSImplClassicIntr * - * @brief ARM_GIC Support Package + * @brief This group contains the Interrupt Manager implementation parts + * specific to the ARM Generic Interrupt Controller. + * + * @{ */ #define GIC_ID_TO_ONE_BIT_REG_INDEX(id) ((id) >> 5) @@ -248,6 +252,8 @@ static inline void gic_id_set_handling_model( dist->icdicfr[i] = icdicfr; } +/* @} */ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bsps/include/dev/irq/arm-gicv3.h b/bsps/include/dev/irq/arm-gicv3.h index 09d1b50422..8829c32384 100644 --- a/bsps/include/dev/irq/arm-gicv3.h +++ b/bsps/include/dev/irq/arm-gicv3.h @@ -3,9 +3,10 @@ /** * @file * - * @ingroup arm_gic + * @ingroup DevIRQGIC * - * @brief This header file contains interfaces to access an Arm GICv3. + * @brief This header file provides interfaces of the ARM Generic Interrupt + * Controller (GIC) support specific to the GICv3. */ /* @@ -44,6 +45,12 @@ extern "C" { #endif +/** + * @addtogroup DevIRQGIC + * + * @{ + */ + #define PRIORITY_DEFAULT 127 #define MPIDR_AFFINITY2(val) BSP_FLD64(val, 16, 23) @@ -387,6 +394,8 @@ static inline void gicv3_get_attributes( } } +/** @} */ + #ifdef __cplusplus } #endif diff --git a/bsps/include/dev/serial/zynq-uart-regs.h b/bsps/include/dev/serial/zynq-uart-regs.h index 3574532b85..5e872d16c3 100644 --- a/bsps/include/dev/serial/zynq-uart-regs.h +++ b/bsps/include/dev/serial/zynq-uart-regs.h @@ -43,6 +43,8 @@ #include <bsp/utility.h> +#define ZYNQ_UART_DEFAULT_BAUD 115200 + #define ZYNQ_UART_FIFO_DEPTH 64 typedef struct zynq_uart { @@ -158,6 +160,24 @@ typedef struct zynq_uart { #define ZYNQ_UART_TX_FIFO_TRG_LVL_TTRIG_SET(reg, val) BSP_FLD32SET(reg, val, 0, 5) } zynq_uart; +void zynq_uart_initialize(volatile zynq_uart *regs); + +int zynq_uart_read_char_polled(volatile zynq_uart *regs); + +void zynq_uart_write_char_polled(volatile zynq_uart *regs, char c); + +/** + * Flush TX FIFO and wait until it is empty. Used in bsp_reset. + */ +void zynq_uart_reset_tx_flush(volatile zynq_uart *regs); + +int zynq_cal_baud_rate( + uint32_t baudrate, + uint32_t* brgr, + uint32_t* bauddiv, + uint32_t modereg +); + /** @} */ #endif /* LIBBSP_ARM_XILINX_ZYNQ_UART_REGS_H */ diff --git a/bsps/arm/xilinx-zynq/console/console-config.c b/bsps/include/dev/serial/zynq-uart-zynq.h index d22ceb557d..169037b33a 100644 --- a/bsps/arm/xilinx-zynq/console/console-config.c +++ b/bsps/include/dev/serial/zynq-uart-zynq.h @@ -3,13 +3,14 @@ /** * @file * - * @ingroup RTEMSBSPsARMZynq + * @ingroup zynq_uart * - * @brief This source file contains the definition of ::zynq_uart_instances. + * @brief This header file provides interfaces with respect to the Zynq + * platform. */ /* - * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG + * Copyright (C) 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,17 +34,33 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <bsp/irq.h> -#include <dev/serial/zynq-uart.h> - -zynq_uart_context zynq_uart_instances[2] = { - { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 0" ), - .regs = (volatile struct zynq_uart *) 0xe0000000, - .irq = ZYNQ_IRQ_UART_0 - }, { - .base = RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( "Zynq UART 1" ), - .regs = (volatile struct zynq_uart *) 0xe0001000, - .irq = ZYNQ_IRQ_UART_1 - } -}; +#ifndef _DEV_SERIAL_ZYNQ_UART_ZYNQ_H +#define _DEV_SERIAL_ZYNQ_UART_ZYNQ_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @addtogroup zynq_uart + * + * @{ + */ + +/** + * @brief This constant defines the Xilinx Zynq UART 0 base address. + */ +#define ZYNQ_UART_0_BASE_ADDR 0xe0000000 + +/** + * @brief This constant defines the Xilinx Zynq UART 1 base address. + */ +#define ZYNQ_UART_1_BASE_ADDR 0xe0001000 + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DEV_SERIAL_ZYNQ_UART_ZYNQ_H */ diff --git a/bsps/include/dev/serial/zynq-uart-zynqmp.h b/bsps/include/dev/serial/zynq-uart-zynqmp.h new file mode 100644 index 0000000000..9f29003053 --- /dev/null +++ b/bsps/include/dev/serial/zynq-uart-zynqmp.h @@ -0,0 +1,66 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup zynq_uart + * + * @brief This header file provides interfaces with respect to the Zynq + * UltraScale+ MPSoC and RFSoC platforms. + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _DEV_SERIAL_ZYNQ_UART_ZYNQMP_H +#define _DEV_SERIAL_ZYNQ_UART_ZYNQMP_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @addtogroup zynq_uart + * + * @{ + */ + +/** + * @brief This constant defines the Xilinx Zynq UART 0 base address. + */ +#define ZYNQ_UART_0_BASE_ADDR 0xff000000 + +/** + * @brief This constant defines the Xilinx Zynq UART 1 base address. + */ +#define ZYNQ_UART_1_BASE_ADDR 0xff010000 + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _DEV_SERIAL_ZYNQ_UART_ZYNQMP_H */ diff --git a/bsps/include/dev/serial/zynq-uart.h b/bsps/include/dev/serial/zynq-uart.h index e7854af5f1..002adcdbd6 100644 --- a/bsps/include/dev/serial/zynq-uart.h +++ b/bsps/include/dev/serial/zynq-uart.h @@ -59,29 +59,6 @@ typedef struct { extern const rtems_termios_device_handler zynq_uart_handler; -#define ZYNQ_UART_DEFAULT_BAUD 115200 - -void zynq_uart_initialize(rtems_termios_device_context *base); - -int zynq_uart_read_polled(rtems_termios_device_context *base); - -void zynq_uart_write_polled( - rtems_termios_device_context *base, - char c -); - -/** - * Flush TX FIFO and wait until it is empty. Used in bsp_reset. - */ -void zynq_uart_reset_tx_flush(zynq_uart_context *ctx); - -int zynq_cal_baud_rate( - uint32_t baudrate, - uint32_t* brgr, - uint32_t* bauddiv, - uint32_t modereg -); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bsps/powerpc/qoriq/clock/clock-config.c b/bsps/powerpc/qoriq/clock/clock-config.c index 8ecc19ef0d..17347278f3 100644 --- a/bsps/powerpc/qoriq/clock/clock-config.c +++ b/bsps/powerpc/qoriq/clock/clock-config.c @@ -40,7 +40,7 @@ #include <bsp.h> #include <bsp/fatal.h> #include <bsp/qoriq.h> -#include <bsp/irq.h> +#include <bsp/irq-generic.h> static struct timecounter qoriq_clock_tc; diff --git a/bsps/powerpc/qoriq/include/bsp/irq.h b/bsps/powerpc/qoriq/include/bsp/irq.h index 7419095438..5eaf36ba4c 100644 --- a/bsps/powerpc/qoriq/include/bsp/irq.h +++ b/bsps/powerpc/qoriq/include/bsp/irq.h @@ -37,7 +37,6 @@ #define LIBBSP_POWERPC_QORIQ_IRQ_H #include <bsp.h> -#include <rtems/score/processormask.h> #ifdef __cplusplus extern "C" { @@ -409,16 +408,6 @@ rtems_status_code qoriq_pic_set_priority( int *old_priority ); -rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -); - -rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -); - rtems_status_code qoriq_pic_msi_allocate(rtems_vector_number *vector); rtems_status_code qoriq_pic_msi_free(rtems_vector_number vector); diff --git a/bsps/powerpc/qoriq/irq/irq.c b/bsps/powerpc/qoriq/irq/irq.c index 8d6afa6c12..96fbe4e020 100644 --- a/bsps/powerpc/qoriq/irq/irq.c +++ b/bsps/powerpc/qoriq/irq/irq.c @@ -43,11 +43,11 @@ #include <asm/epapr_hcalls.h> #include <bsp.h> -#include <bsp/irq.h> #include <bsp/irq-generic.h> #include <bsp/vectors.h> #include <bsp/utility.h> #include <bsp/qoriq.h> +#include <rtems/score/processormaskimpl.h> #ifdef RTEMS_SMP #include <rtems/score/smpimpl.h> diff --git a/bsps/powerpc/t32mppc/include/bsp/irq.h b/bsps/powerpc/t32mppc/include/bsp/irq.h index be2e7a5883..e4f4614a53 100644 --- a/bsps/powerpc/t32mppc/include/bsp/irq.h +++ b/bsps/powerpc/t32mppc/include/bsp/irq.h @@ -29,9 +29,6 @@ #define LIBBSP_POWERPC_T32MPPC_IRQ_H #include <rtems.h> -#include <rtems/irq.h> -#include <rtems/irq-extension.h> -#include <rtems/score/processormask.h> #ifdef __cplusplus extern "C" { @@ -39,26 +36,6 @@ extern "C" { #define BSP_INTERRUPT_VECTOR_COUNT 1 -static inline rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -) -{ - (void) vector; - (void) affinity; - return RTEMS_SUCCESSFUL; -} - -static inline rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -) -{ - (void) vector; - _Processor_mask_From_index( affinity, 0 ); - return RTEMS_SUCCESSFUL; -} - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bsps/powerpc/t32mppc/irq/irq.c b/bsps/powerpc/t32mppc/irq/irq.c index 6bd37b3df4..a3f2504443 100644 --- a/bsps/powerpc/t32mppc/irq/irq.c +++ b/bsps/powerpc/t32mppc/irq/irq.c @@ -92,6 +92,28 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) return RTEMS_SUCCESSFUL; } +#if defined(RTEMS_SMP) +rtems_status_code bsp_interrupt_get_affinity( + rtems_vector_number vector, + Processor_mask *affinity +) +{ + (void) vector; + _Processor_mask_From_index( affinity, 0 ); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_set_affinity( + rtems_vector_number vector, + const Processor_mask *affinity +) +{ + (void) vector; + (void) affinity; + return RTEMS_UNSATISFIED; +} +#endif + void bsp_interrupt_facility_initialize(void) { /* Nothing to do */ diff --git a/bsps/riscv/griscv/clock/clockdrv.c b/bsps/riscv/griscv/clock/clockdrv.c index 817cb331b6..3174bae468 100644 --- a/bsps/riscv/griscv/clock/clockdrv.c +++ b/bsps/riscv/griscv/clock/clockdrv.c @@ -41,7 +41,7 @@ #include <bsp.h> #include <amba.h> -#include <bsp/irq.h> +#include <bsp/irq-generic.h> #include <bspopts.h> #include <bsp/fatal.h> #include <rtems/rtems/intr.h> diff --git a/bsps/riscv/griscv/include/bsp/irq.h b/bsps/riscv/griscv/include/bsp/irq.h index 9256e4ff3c..43ee019620 100644 --- a/bsps/riscv/griscv/include/bsp/irq.h +++ b/bsps/riscv/griscv/include/bsp/irq.h @@ -40,9 +40,6 @@ #ifndef ASM #include <bsp.h> -#include <rtems/irq.h> -#include <rtems/irq-extension.h> -#include <rtems/score/processormask.h> #define RISCV_INTERRUPT_VECTOR_SOFTWARE 0 @@ -56,16 +53,6 @@ #define BSP_INTERRUPT_VECTOR_COUNT RISCV_INTERRUPT_VECTOR_EXTERNAL(RISCV_MAXIMUM_EXTERNAL_INTERRUPTS) -rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -); - -rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -); - #endif /* ASM */ #endif /* LIBBSP_RISCV_GRISCV_IRQ_H */ diff --git a/bsps/riscv/griscv/irq/irq.c b/bsps/riscv/griscv/irq/irq.c index 507302d4dd..12af7d7b3d 100644 --- a/bsps/riscv/griscv/irq/irq.c +++ b/bsps/riscv/griscv/irq/irq.c @@ -34,7 +34,6 @@ * SUCH DAMAGE. */ -#include <bsp/irq.h> #include <bsp/fatal.h> #include <bsp/irq-generic.h> #include <amba.h> diff --git a/bsps/riscv/noel/include/bsp/irq.h b/bsps/riscv/noel/include/bsp/irq.h index 0c0dc1a48e..3bbea3edfe 100644 --- a/bsps/riscv/noel/include/bsp/irq.h +++ b/bsps/riscv/noel/include/bsp/irq.h @@ -42,9 +42,6 @@ #ifndef ASM #include <bsp.h> -#include <rtems/irq.h> -#include <rtems/irq-extension.h> -#include <rtems/score/processormask.h> #define RISCV_INTERRUPT_VECTOR_SOFTWARE 0 @@ -60,16 +57,6 @@ #define BSP_INTERRUPT_CUSTOM_VALID_VECTOR -rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -); - -rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -); - #endif /* ASM */ #endif /* LIBBSP_GENERIC_RISCV_IRQ_H */ diff --git a/bsps/riscv/riscv/include/bsp/irq.h b/bsps/riscv/riscv/include/bsp/irq.h index 0c0dc1a48e..3bbea3edfe 100644 --- a/bsps/riscv/riscv/include/bsp/irq.h +++ b/bsps/riscv/riscv/include/bsp/irq.h @@ -42,9 +42,6 @@ #ifndef ASM #include <bsp.h> -#include <rtems/irq.h> -#include <rtems/irq-extension.h> -#include <rtems/score/processormask.h> #define RISCV_INTERRUPT_VECTOR_SOFTWARE 0 @@ -60,16 +57,6 @@ #define BSP_INTERRUPT_CUSTOM_VALID_VECTOR -rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -); - -rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -); - #endif /* ASM */ #endif /* LIBBSP_GENERIC_RISCV_IRQ_H */ diff --git a/bsps/riscv/riscv/irq/irq.c b/bsps/riscv/riscv/irq/irq.c index 4679d5a624..ada418b7fb 100644 --- a/bsps/riscv/riscv/irq/irq.c +++ b/bsps/riscv/riscv/irq/irq.c @@ -36,7 +36,6 @@ * SUCH DAMAGE. */ -#include <bsp/irq.h> #include <bsp/fatal.h> #include <bsp/fdt.h> #include <bsp/irq-generic.h> diff --git a/bsps/arm/raspberrypi/clock/clockdrv.c b/bsps/shared/dev/clock/bcm2835-system-timer.c index bb8490d03a..bb8490d03a 100644 --- a/bsps/arm/raspberrypi/clock/clockdrv.c +++ b/bsps/shared/dev/clock/bcm2835-system-timer.c diff --git a/bsps/shared/dev/clock/clockimpl.h b/bsps/shared/dev/clock/clockimpl.h index 592046ec27..b27f7c15bc 100644 --- a/bsps/shared/dev/clock/clockimpl.h +++ b/bsps/shared/dev/clock/clockimpl.h @@ -42,6 +42,7 @@ #include <bsp.h> #include <rtems/clockdrv.h> #include <rtems/score/percpu.h> +#include <rtems/score/processormaskimpl.h> #include <rtems/score/smpimpl.h> #include <rtems/score/timecounter.h> #include <rtems/score/thread.h> diff --git a/bsps/shared/dev/clock/xil-ttc.c b/bsps/shared/dev/clock/xil-ttc.c index 340c428a48..624845d71c 100644 --- a/bsps/shared/dev/clock/xil-ttc.c +++ b/bsps/shared/dev/clock/xil-ttc.c @@ -1,14 +1,16 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + /** * @file * - * @ingroup RTEMSBSPsARMZynqMP + * @ingroup RTEMSDriverClockXilTTC * - * @brief Triple Timer Counter clock functions definitions. + * @brief This source file contains a Clock Driver implementation using the + * Xilinx Triple Timer Counter (TTC). */ /* - * SPDX-License-Identifier: BSD-2-Clause - * + * Copyright (C) 2024 embedded brains GmbH & Co. KG * Copyright (C) 2023 Reflex Aerospace GmbH * * Written by Philip Kirkpatrick <p.kirkpatrick@reflexaerospace.com> @@ -35,187 +37,178 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <stdlib.h> - -#include <rtems.h> #include <bsp.h> #include <bsp/irq.h> -#include <peripheral_maps/xilinx_zynqmp.h> +#include <bsp/fatal.h> #include <dev/clock/xttcps_hw.h> +#include <rtems/sysinit.h> #include <rtems/timecounter.h> -typedef struct { - struct timecounter ttc_tc; - uint32_t irq_match_interval; - uint32_t tick_miss; -} ttc_clock_context; - -static ttc_clock_context ttc_clock_instance = {0, }; +#if XTTCPS_COUNT_VALUE_MASK != UINT32_MAX +#error "unexpected XTTCPS_COUNT_VALUE_MASK value" +#endif -#define TTC_REFERENCE_CLOCK 100000000 +/** + * @defgroup RTEMSDriverClockXilTTC \ + * Xilinx Triple Timer Counter (TTC) Clock Driver + * + * @ingroup RTEMSDriverClockImpl + * + * @brief This group contains the Xilinx Triple Timer Counter (TTC) Clock + * Driver implementation. + * + * @{ + */ uint32_t _CPU_Counter_frequency( void ) { - return ttc_clock_instance.ttc_tc.tc_frequency; + return XIL_CLOCK_TTC_REFERENCE_CLOCK; } -static uint32_t zynqmp_ttc_get_timecount(struct timecounter *tc) +CPU_Counter_ticks _CPU_Counter_read(void) { - uint32_t time; - time = XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_COUNT_VALUE_OFFSET); - return time; + return XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); } -CPU_Counter_ticks _CPU_Counter_read(void) +static void xil_ttc_initialize(void) { - return zynqmp_ttc_get_timecount(&ttc_clock_instance.ttc_tc); + /* Do not use a prescaler to get a high resolution time source */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_CLK_CNTRL_OFFSET, 0); + + /* Disable interupts */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_IER_OFFSET, 0); + + /* + * Enable the timer, do not enable waveform output, increment up, use + * overflow mode, enable match mode. + */ + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_CNT_CNTRL_OFFSET, + XTTCPS_CNT_CNTRL_EN_WAVE_MASK | XTTCPS_CNT_CNTRL_MATCH_MASK); } -/** - * @brief Initialize the HW peripheral for clock driver - * - * Clock driver is implemented by RTI module - * - * @retval Void - */ -static void zynqmp_ttc_clock_driver_support_initialize_hardware(void) -{ +RTEMS_SYSINIT_ITEM( + xil_ttc_initialize, + RTEMS_SYSINIT_CPU_COUNTER, + RTEMS_SYSINIT_ORDER_MIDDLE +); - uint32_t microsec_per_tick; - uint16_t clock_ratio; - uint8_t index; - uint32_t frequency; - uint32_t prescaler; - uint32_t tmp_reg_val; +typedef struct { + struct timecounter base; + uint32_t irq_match_interval; +} xil_ttc_timecounter; - microsec_per_tick = rtems_configuration_get_microseconds_per_tick(); +static xil_ttc_timecounter xil_ttc_clock_instance; - /* Check the TTC is OFF before reconfiguring */ - XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_CNT_CNTRL_OFFSET, - /* Don't enable waveform output */ - XTTCPS_CNT_CNTRL_DIS_MASK | XTTCPS_CNT_CNTRL_EN_WAVE_MASK); +static uint32_t xil_ttc_get_timecount(struct timecounter *tc) +{ + (void) tc; + return XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); +} - /* Prescaler value is 2^(N + 1) - * Divide down the clock as much as possible while still retaining a - * frequency that is an integer multiple of 1MHz. This maximizes time to - * overflow while minimizing rounding errors in 1us periods - */ - clock_ratio = TTC_REFERENCE_CLOCK / 1000000; - /* Search for the highest set bit. This is effectively min(log2(ratio)) */ - for(index = sizeof(clock_ratio) * 8 - 1; index > 0; index--) { - if((clock_ratio >> (index)) & 0x01) { - break; - } - } - if(index == 0 && (clock_ratio & 0x01) == 0) { - /* No prescaler */ - frequency = TTC_REFERENCE_CLOCK; - XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_CLK_CNTRL_OFFSET, 0); - } else { - prescaler = index - 1; - frequency = TTC_REFERENCE_CLOCK / (1 << (prescaler + 1)); - XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_CLK_CNTRL_OFFSET, - prescaler << XTTCPS_CLK_CNTRL_PS_VAL_SHIFT | - XTTCPS_CLK_CNTRL_PS_EN_MASK); - } +static void xil_ttc_clock_driver_support_initialize_hardware(void) +{ + xil_ttc_timecounter *tc; + uint64_t frequency; + uint32_t irq_match_interval; + uint32_t count; - /* Max out the counter interval */ - tmp_reg_val = XTTCPS_INTERVAL_VAL_MASK; - XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_INTERVAL_VAL_OFFSET, - tmp_reg_val); + tc = &xil_ttc_clock_instance; + frequency = XIL_CLOCK_TTC_REFERENCE_CLOCK; + irq_match_interval = (uint32_t) + ((frequency * rtems_configuration_get_microseconds_per_tick()) / 1000000); + + /* Setup match register to generate clock interrupts */ + count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, + count + irq_match_interval); - /* Setup match register to generate tick IRQ */ - ttc_clock_instance.irq_match_interval = - (uint32_t) (((uint64_t)frequency * microsec_per_tick) / 1000000); - XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_MATCH_0_OFFSET, - ttc_clock_instance.irq_match_interval); /* Clear interupts (clear on read) */ - XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_ISR_OFFSET); + (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET); + /* Enable interupt for match register */ - XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_IER_OFFSET, + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_IER_OFFSET, XTTCPS_IXR_MATCH_0_MASK); - /* Configure, reset, and enable counter */ - XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_CNT_CNTRL_OFFSET, - XTTCPS_CNT_CNTRL_EN_WAVE_MASK | /* Don't enable waveform output */ - XTTCPS_CNT_CNTRL_RST_MASK | /* Reset count and start counter */ - XTTCPS_CNT_CNTRL_MATCH_MASK /* Enable match mode */ - /* Increment mode */ - /* Overflow mode */ - /* Not disabled */ - ); - - /* set timecounter */ - ttc_clock_instance.ttc_tc.tc_get_timecount = zynqmp_ttc_get_timecount; - ttc_clock_instance.ttc_tc.tc_counter_mask = XTTCPS_COUNT_VALUE_MASK; - ttc_clock_instance.ttc_tc.tc_frequency = frequency; - ttc_clock_instance.ttc_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; - rtems_timecounter_install(&ttc_clock_instance.ttc_tc); + + /* Install timecounter */ + tc->irq_match_interval = irq_match_interval; + tc->base.tc_counter_mask = UINT32_MAX; + tc->base.tc_frequency = XIL_CLOCK_TTC_REFERENCE_CLOCK; + tc->base.tc_get_timecount = xil_ttc_get_timecount; + tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&tc->base); } -/** - * @brief Clears interrupt source - * - * @retval Void - */ -static void zynqmp_ttc_clock_driver_support_at_tick(ttc_clock_context *tc) +static void xil_ttc_clock_driver_support_at_tick(xil_ttc_timecounter *tc) { - uint32_t irq_flags; - uint32_t cval; - uint32_t now; - uint32_t delta; - - /* Get and clear interupts (clear on read) */ - irq_flags = XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_ISR_OFFSET); - - if(irq_flags & XTTCPS_IXR_MATCH_0_MASK) { - /* Update match */ - cval = XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_MATCH_0_OFFSET); - /* Check that the match for the next tick is in the future - * If no, then set the match for one irq interval from now - * This will have the effect that your timebase will slip but - * won't hang waiting for the counter to wrap around. - * If this happens during normal operation, there is a problem - * causing this interrupt to not be serviced quickly enough - * If this happens during debugging, that is normal and expected - * because the TTC does NOT pause when the CPU is halted on a breakpoint + uint32_t irq_match_interval; + uint32_t count; + uint32_t match; + + irq_match_interval = tc->irq_match_interval; + + /* Update match register */ + match = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET); + match += irq_match_interval; + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, match); + + /* Clear interupts (clear on read) */ + (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET); + + /* Check that the new match value is in the future */ + count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); + + while (RTEMS_PREDICT_FALSE(match - count > irq_match_interval)) { + /* + * Tick misses may happen if interrupts are disabled for an extremly long + * period or while debugging. */ - now = XTtcPs_ReadReg(BSP_SELECTED_TTC_ADDR, XTTCPS_COUNT_VALUE_OFFSET); - delta = now - cval; - if(delta > tc->irq_match_interval) { - cval = now; - tc->tick_miss++; - } - cval += tc->irq_match_interval; - XTtcPs_WriteReg(BSP_SELECTED_TTC_ADDR, XTTCPS_MATCH_0_OFFSET, cval); + rtems_timecounter_tick(); + + /* Update match register */ + match += irq_match_interval; + XTtcPs_WriteReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_MATCH_0_OFFSET, match); + + /* Clear interupts (clear on read) */ + (void) XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_ISR_OFFSET); + + /* Maybe the new match value is now in the future */ + count = XTtcPs_ReadReg(XIL_CLOCK_TTC_BASE_ADDR, XTTCPS_COUNT_VALUE_OFFSET); } - /* Else, something is set up wrong, only match should be enabled */ } -static void zynqmp_ttc_clock_driver_support_install_isr( +static rtems_interrupt_entry xil_ttc_interrupt_entry; + +static void xil_ttc_clock_driver_support_install_isr( rtems_interrupt_handler handler ) { rtems_status_code sc; - sc = rtems_interrupt_handler_install( - BSP_SELECTED_TTC_IRQ, - "Clock", - RTEMS_INTERRUPT_UNIQUE, + rtems_interrupt_entry_initialize( + &xil_ttc_interrupt_entry, handler, - &ttc_clock_instance + &xil_ttc_clock_instance, + "Clock" + ); + sc = rtems_interrupt_entry_install( + XIL_CLOCK_TTC_IRQ, + RTEMS_INTERRUPT_UNIQUE, + &xil_ttc_interrupt_entry ); if ( sc != RTEMS_SUCCESSFUL ) { - rtems_fatal_error_occurred(0xdeadbeef); + bsp_fatal(XIL_FATAL_TTC_IRQ_INSTALL); } } #define Clock_driver_support_at_tick(arg) \ - zynqmp_ttc_clock_driver_support_at_tick(arg) + xil_ttc_clock_driver_support_at_tick(arg) #define Clock_driver_support_initialize_hardware \ - zynqmp_ttc_clock_driver_support_initialize_hardware + xil_ttc_clock_driver_support_initialize_hardware #define Clock_driver_support_install_isr(isr) \ - zynqmp_ttc_clock_driver_support_install_isr(isr) + xil_ttc_clock_driver_support_install_isr(isr) + +/** @} */ #include "../../../shared/dev/clock/clockimpl.h" diff --git a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c index 3280671ab6..613174bb3a 100644 --- a/bsps/shared/dev/irq/arm-gicv2-get-attributes.c +++ b/bsps/shared/dev/irq/arm-gicv2-get-attributes.c @@ -3,9 +3,10 @@ /** * @file * - * @ingroup RTEMSBSPsShared + * @ingroup DevIRQGIC * - * @brief This source file contains the interrupt get attribute implementation. + * @brief This source file contains the implementation of + * bsp_interrupt_get_attributes() for the GICv2. */ /* diff --git a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c index ee4479155a..bb9bfafb48 100644 --- a/bsps/shared/dev/irq/arm-gicv2-zynqmp.c +++ b/bsps/shared/dev/irq/arm-gicv2-zynqmp.c @@ -3,9 +3,11 @@ /** * @file * - * @ingroup RTEMSBSPsShared + * @ingroup DevIRQGIC * - * @brief This source file contains the interrupt get attribute implementation. + * @brief This source file contains the implementation of + * bsp_interrupt_get_attributes() for the GICv2 of Xilinx Zynq UltraScale+ + * MPSoC and RFSoC devices. */ /* diff --git a/bsps/shared/dev/irq/arm-gicv2.c b/bsps/shared/dev/irq/arm-gicv2.c index 8dc0895956..263278148b 100644 --- a/bsps/shared/dev/irq/arm-gicv2.c +++ b/bsps/shared/dev/irq/arm-gicv2.c @@ -3,9 +3,10 @@ /** * @file * - * @ingroup RTEMSBSPsARMShared + * @ingroup DevIRQGIC * - * @brief This source file contains the implementation of ARM GICv2 support. + * @brief This source file contains the implementation of the generic GICv2 + * support. */ /* @@ -36,9 +37,17 @@ #include <dev/irq/arm-gic.h> #include <dev/irq/arm-gic-arch.h> -#include <bsp/irq.h> #include <bsp/irq-generic.h> #include <bsp/start.h> +#include <rtems/score/processormaskimpl.h> + +/* + * The GIC architecture reserves interrupt ID numbers 1020 to 1023 for special + * purposes. + */ +#if BSP_INTERRUPT_VECTOR_COUNT >= 1020 +#error "BSP_INTERRUPT_VECTOR_COUNT is too large" +#endif #define GIC_CPUIF ((volatile gic_cpuif *) BSP_ARM_GIC_CPUIF_BASE) @@ -74,12 +83,19 @@ void bsp_interrupt_dispatch(void) { volatile gic_cpuif *cpuif = GIC_CPUIF; - uint32_t icciar = cpuif->icciar; - rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); - rtems_vector_number spurious = 1023; - if (vector != spurious) { - arm_interrupt_handler_dispatch(vector); + while (true) { + uint32_t icciar = cpuif->icciar; + rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); + uint32_t status; + + if (!bsp_interrupt_is_valid_vector(vector)) { + break; + } + + status = arm_interrupt_enable_interrupts(); + bsp_interrupt_handler_dispatch_unchecked(vector); + arm_interrupt_restore_interrupts(status); cpuif->icceoir = icciar; } @@ -328,6 +344,7 @@ rtems_status_code arm_gic_irq_get_group( return sc; } +#ifdef RTEMS_SMP rtems_status_code bsp_interrupt_set_affinity( rtems_vector_number vector, const Processor_mask *affinity @@ -387,6 +404,7 @@ rtems_status_code bsp_interrupt_get_affinity( _Processor_mask_From_uint32_t(affinity, targets, 0); return RTEMS_SUCCESSFUL; } +#endif void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets) { diff --git a/bsps/shared/dev/irq/arm-gicv3.c b/bsps/shared/dev/irq/arm-gicv3.c index 108d64348a..958b1061bd 100644 --- a/bsps/shared/dev/irq/arm-gicv3.c +++ b/bsps/shared/dev/irq/arm-gicv3.c @@ -1,6 +1,15 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup DevIRQGIC * + * @brief This source file contains the implementation of the generic GICv3 + * support. + */ + +/* * Copyright (C) 2019 On-Line Applications Research Corporation (OAR) * * Redistribution and use in source and binary forms, with or without @@ -27,18 +36,24 @@ #include <dev/irq/arm-gicv3.h> -#include <bsp/irq.h> #include <bsp/irq-generic.h> #include <bsp/start.h> +#include <rtems/score/processormaskimpl.h> void bsp_interrupt_dispatch(void) { - uint32_t icciar = READ_SR(ICC_IAR1); - rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); - rtems_vector_number spurious = 1023; + while (true) { + uint32_t icciar = READ_SR(ICC_IAR1); + rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar); + uint32_t status; + + if (!bsp_interrupt_is_valid_vector(vector)) { + break; + } - if (vector != spurious) { - arm_interrupt_handler_dispatch(vector); + status = arm_interrupt_enable_interrupts(); + bsp_interrupt_handler_dispatch_unchecked(vector); + arm_interrupt_restore_interrupts(status); WRITE_SR(ICC_EOIR1, icciar); } @@ -242,6 +257,7 @@ rtems_status_code arm_gic_irq_get_priority( return sc; } +#ifdef RTEMS_SMP rtems_status_code bsp_interrupt_set_affinity( rtems_vector_number vector, const Processor_mask *affinity @@ -274,6 +290,7 @@ rtems_status_code bsp_interrupt_get_affinity( _Processor_mask_From_uint32_t(affinity, targets, 0); return RTEMS_SUCCESSFUL; } +#endif void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets) { diff --git a/bsps/arm/xilinx-zynq/console/debug-console.c b/bsps/shared/dev/serial/zynq-uart-kernel-io.c index d398ca7988..61b1043cd2 100644 --- a/bsps/arm/xilinx-zynq/console/debug-console.c +++ b/bsps/shared/dev/serial/zynq-uart-kernel-io.c @@ -3,14 +3,14 @@ /** * @file * - * @ingroup RTEMSBSPsARMZynq + * @ingroup zynq_uart * * @brief This source file contains the definition of ::BSP_output_char and * ::BSP_poll_char. */ /* - * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG + * Copyright (C) 2013, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,56 +35,54 @@ */ #include <rtems/bspIo.h> -#include <rtems/sysinit.h> #include <bsp.h> -#include <dev/serial/zynq-uart.h> +#include <dev/serial/zynq-uart-regs.h> +#include <rtems/sysinit.h> -#include <bspopts.h> +static void zynq_uart_kernel_output_char(char c) +{ + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; + + zynq_uart_write_char_polled(regs, c); +} -static void zynq_debug_console_out(char c) +static int zynq_uart_kernel_poll_char(void) { - rtems_termios_device_context *base = - &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; - zynq_uart_write_polled(base, c); + return zynq_uart_read_char_polled(regs); } -static void zynq_debug_console_early_init(char c); +static void zynq_uart_kernel_early_init(char c); -static void zynq_debug_console_init(void) +static void zynq_uart_kernel_init(void) { - rtems_termios_device_context *base = - &zynq_uart_instances[BSP_CONSOLE_MINOR].base; + volatile zynq_uart *regs = + (volatile zynq_uart *) ZYNQ_UART_KERNEL_IO_BASE_ADDR; - if (BSP_output_char != zynq_debug_console_early_init) { + if (BSP_output_char != zynq_uart_kernel_early_init) { return; } - zynq_uart_initialize(base); - BSP_output_char = zynq_debug_console_out; + zynq_uart_initialize(regs); + BSP_output_char = zynq_uart_kernel_output_char; } -static void zynq_debug_console_early_init(char c) +static void zynq_uart_kernel_early_init(char c) { - zynq_debug_console_init(); - zynq_debug_console_out(c); -} - -static int zynq_debug_console_in(void) -{ - rtems_termios_device_context *base = - &zynq_uart_instances[BSP_CONSOLE_MINOR].base; - - return zynq_uart_read_polled(base); + zynq_uart_kernel_init(); + zynq_uart_kernel_output_char(c); } -BSP_output_char_function_type BSP_output_char = zynq_debug_console_early_init; +BSP_output_char_function_type BSP_output_char = zynq_uart_kernel_early_init; -BSP_polling_getchar_function_type BSP_poll_char = zynq_debug_console_in; +BSP_polling_getchar_function_type BSP_poll_char = zynq_uart_kernel_poll_char; RTEMS_SYSINIT_ITEM( - zynq_debug_console_init, + zynq_uart_kernel_init, RTEMS_SYSINIT_BSP_START, RTEMS_SYSINIT_ORDER_LAST_BUT_5 ); diff --git a/bsps/shared/dev/serial/zynq-uart-polled.c b/bsps/shared/dev/serial/zynq-uart-polled.c index 7d5dd8ff1a..dbf75539f6 100644 --- a/bsps/shared/dev/serial/zynq-uart-polled.c +++ b/bsps/shared/dev/serial/zynq-uart-polled.c @@ -124,10 +124,8 @@ int zynq_cal_baud_rate(uint32_t baudrate, return 0; } -void zynq_uart_initialize(rtems_termios_device_context *base) +void zynq_uart_initialize(volatile zynq_uart *regs) { - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; uint32_t brgr = 0x3e; uint32_t bauddiv = 0x6; uint32_t mode_clks = regs->mode & ZYNQ_UART_MODE_CLKS; @@ -154,18 +152,15 @@ void zynq_uart_initialize(rtems_termios_device_context *base) | ZYNQ_UART_MODE_CHRL(ZYNQ_UART_MODE_CHRL_8) | mode_clks; - while (zynq_uart_read_polled(base) >= 0) { + while (zynq_uart_read_char_polled(regs) >= 0) { /* Drop */ } - zynq_uart_reset_tx_flush(ctx); + zynq_uart_reset_tx_flush(regs); } -int zynq_uart_read_polled(rtems_termios_device_context *base) +int zynq_uart_read_char_polled(volatile zynq_uart *regs) { - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - if ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_REMPTY) != 0) { return -1; } else { @@ -173,14 +168,8 @@ int zynq_uart_read_polled(rtems_termios_device_context *base) } } -void zynq_uart_write_polled( - rtems_termios_device_context *base, - char c -) +void zynq_uart_write_char_polled(volatile zynq_uart *regs, char c) { - zynq_uart_context *ctx = (zynq_uart_context *) base; - volatile zynq_uart *regs = ctx->regs; - while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TNFUL) != 0) { /* Wait */ } @@ -188,13 +177,12 @@ void zynq_uart_write_polled( regs->tx_rx_fifo = ZYNQ_UART_TX_RX_FIFO_FIFO(c); } -void zynq_uart_reset_tx_flush(zynq_uart_context *ctx) +void zynq_uart_reset_tx_flush(volatile zynq_uart *regs) { - volatile zynq_uart *regs = ctx->regs; - int c = 4; + int c = 4; while (c-- > 0) - zynq_uart_write_polled(&ctx->base, '\r'); + zynq_uart_write_char_polled(regs, '\r'); while ((regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TEMPTY) == 0 || (regs->channel_sts & ZYNQ_UART_CHANNEL_STS_TACTIVE) != 0) { diff --git a/bsps/shared/dev/serial/zynq-uart.c b/bsps/shared/dev/serial/zynq-uart.c index 390ee1f527..0489288271 100644 --- a/bsps/shared/dev/serial/zynq-uart.c +++ b/bsps/shared/dev/serial/zynq-uart.c @@ -67,14 +67,14 @@ static bool zynq_uart_first_open( rtems_libio_open_close_args_t *args ) { -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS zynq_uart_context *ctx = (zynq_uart_context *) base; volatile zynq_uart *regs = ctx->regs; +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS rtems_status_code sc; #endif rtems_termios_set_initial_baud(tty, ZYNQ_UART_DEFAULT_BAUD); - zynq_uart_initialize(base); + zynq_uart_initialize(regs); #ifdef ZYNQ_CONSOLE_USE_INTERRUPTS regs->rx_fifo_trg_lvl = 1; @@ -109,15 +109,23 @@ static void zynq_uart_last_close( } #endif +#ifndef ZYNQ_CONSOLE_USE_INTERRUPTS +static int zynq_uart_read_polled(rtems_termios_device_context *base) +{ + zynq_uart_context *ctx = (zynq_uart_context *) base; + return zynq_uart_read_char_polled(ctx->regs); +} +#endif + static void zynq_uart_write_support( rtems_termios_device_context *base, const char *buf, size_t len ) { -#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS zynq_uart_context *ctx = (zynq_uart_context *) base; volatile zynq_uart *regs = ctx->regs; +#ifdef ZYNQ_CONSOLE_USE_INTERRUPTS regs->irq_dis = ZYNQ_UART_TEMPTY; @@ -135,9 +143,9 @@ static void zynq_uart_write_support( regs->irq_en = ZYNQ_UART_TEMPTY; } #else - ssize_t i; + size_t i; for (i = 0; i < len; ++i) { - zynq_uart_write_polled(base, buf[i]); + zynq_uart_write_char_polled(regs, buf[i]); } #endif } diff --git a/bsps/shared/irq/irq-affinity.c b/bsps/shared/irq/irq-affinity.c index 6c1522f77f..7e9250a948 100644 --- a/bsps/shared/irq/irq-affinity.c +++ b/bsps/shared/irq/irq-affinity.c @@ -36,7 +36,6 @@ #include <bsp/irq-generic.h> -#include <rtems/score/processormask.h> #include <rtems/score/smpimpl.h> rtems_status_code rtems_interrupt_set_affinity( diff --git a/bsps/sparc/erc32/include/bsp/irq.h b/bsps/sparc/erc32/include/bsp/irq.h index 1b021d1f9b..210883ad05 100644 --- a/bsps/sparc/erc32/include/bsp/irq.h +++ b/bsps/sparc/erc32/include/bsp/irq.h @@ -37,31 +37,11 @@ #ifndef LIBBSP_ERC32_IRQ_CONFIG_H #define LIBBSP_ERC32_IRQ_CONFIG_H -#include <rtems/score/processormask.h> +#include <rtems.h> #define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */ #define BSP_INTERRUPT_VECTOR_COUNT (BSP_INTERRUPT_VECTOR_MAX_STD + 1) #define BSP_INTERRUPT_CUSTOM_VALID_VECTOR -static inline rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -) -{ - (void) vector; - (void) affinity; - return RTEMS_SUCCESSFUL; -} - -static inline rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -) -{ - (void) vector; - _Processor_mask_From_index( affinity, 0 ); - return RTEMS_SUCCESSFUL; -} - #endif /* LIBBSP_ERC32_IRQ_CONFIG_H */ diff --git a/bsps/sparc/leon3/clock/ckinit.c b/bsps/sparc/leon3/clock/ckinit.c index f0307bf908..503cb28bab 100644 --- a/bsps/sparc/leon3/clock/ckinit.c +++ b/bsps/sparc/leon3/clock/ckinit.c @@ -42,9 +42,8 @@ #include <bsp.h> #include <bsp/fatal.h> -#include <bsp/irq.h> +#include <bsp/irq-generic.h> #include <bsp/leon3.h> -#include <rtems/rtems/intr.h> #include <grlib/irqamp.h> #include <rtems/score/profiling.h> #include <rtems/timecounter.h> diff --git a/bsps/sparc/leon3/include/bsp/irq.h b/bsps/sparc/leon3/include/bsp/irq.h index 2e500622bf..dd6fd91aa1 100644 --- a/bsps/sparc/leon3/include/bsp/irq.h +++ b/bsps/sparc/leon3/include/bsp/irq.h @@ -38,7 +38,6 @@ #define LIBBSP_LEON3_IRQ_CONFIG_H #include <rtems.h> -#include <rtems/score/processormask.h> #define BSP_INTERRUPT_VECTOR_MAX_STD 15 /* Standard IRQ controller */ #define BSP_INTERRUPT_VECTOR_MAX_EXT 31 /* Extended IRQ controller */ @@ -48,14 +47,4 @@ /* The check is different depending on IRQ controller, runtime detected */ #define BSP_INTERRUPT_CUSTOM_VALID_VECTOR -rtems_status_code bsp_interrupt_set_affinity( - rtems_vector_number vector, - const Processor_mask *affinity -); - -rtems_status_code bsp_interrupt_get_affinity( - rtems_vector_number vector, - Processor_mask *affinity -); - #endif /* LIBBSP_LEON3_IRQ_CONFIG_H */ diff --git a/bsps/sparc/leon3/include/tm27.h b/bsps/sparc/leon3/include/tm27.h index 3de349f363..75004ef5ae 100644 --- a/bsps/sparc/leon3/include/tm27.h +++ b/bsps/sparc/leon3/include/tm27.h @@ -40,7 +40,7 @@ #define __tm27_h #include <bsp.h> -#include <bsp/irq.h> +#include <bsp/irq-generic.h> #if defined(RTEMS_SMP) #include <rtems/score/smpimpl.h> diff --git a/bsps/sparc/leon3/start/bspsmp.c b/bsps/sparc/leon3/start/bspsmp.c index 8c7c88da63..82d6e5a163 100644 --- a/bsps/sparc/leon3/start/bspsmp.c +++ b/bsps/sparc/leon3/start/bspsmp.c @@ -16,7 +16,7 @@ #include <bsp.h> #include <bsp/bootcard.h> #include <bsp/fatal.h> -#include <bsp/irq.h> +#include <bsp/irq-generic.h> #include <bsp/leon3.h> #include <rtems/bspIo.h> #include <rtems/sysinit.h> diff --git a/bsps/sparc/leon3/start/eirq.c b/bsps/sparc/leon3/start/eirq.c index 78a1baef25..58ef1828d6 100644 --- a/bsps/sparc/leon3/start/eirq.c +++ b/bsps/sparc/leon3/start/eirq.c @@ -38,9 +38,9 @@ * */ -#include <bsp/irq.h> #include <bsp/irq-generic.h> #include <bsp/irqimpl.h> +#include <rtems/score/processormaskimpl.h> #if !defined(LEON3_IRQAMP_EXTENDED_INTERRUPT) /* GRLIB extended IRQ controller IRQ number */ diff --git a/bsps/sparc/shared/irq/irq-shared.c b/bsps/sparc/shared/irq/irq-shared.c index efa1d86020..3d73ad90e7 100644 --- a/bsps/sparc/shared/irq/irq-shared.c +++ b/bsps/sparc/shared/irq/irq-shared.c @@ -29,6 +29,7 @@ #include <bsp.h> #include <bsp/irq-generic.h> +#include <rtems/score/processormaskimpl.h> static inline int bsp_irq_cpu(int irq) { @@ -140,3 +141,25 @@ rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) BSP_Cpu_Mask_interrupt(vector, 0); return RTEMS_SUCCESSFUL; } + +#if defined(RTEMS_SMP) +rtems_status_code bsp_interrupt_get_affinity( + rtems_vector_number vector, + Processor_mask *affinity +) +{ + (void) vector; + _Processor_mask_From_index( affinity, 0 ); + return RTEMS_UNSATISFIED; +} + +rtems_status_code bsp_interrupt_set_affinity( + rtems_vector_number vector, + const Processor_mask *affinity +) +{ + (void) vector; + (void) affinity; + return RTEMS_UNSATISFIED; +} +#endif diff --git a/cpukit/doxygen/appl-config.h b/cpukit/doxygen/appl-config.h index 81150af066..de93acbaa7 100644 --- a/cpukit/doxygen/appl-config.h +++ b/cpukit/doxygen/appl-config.h @@ -3312,7 +3312,8 @@ * @parblock * The following constraints apply to this configuration option: * - * * The value of the configuration option shall be greater than zero. + * * The value of the configuration option shall be greater than or equal to + * one. * * * The value of the configuration option shall be less than or equal to <a * href="https://en.cppreference.com/w/c/types/integer">UINT32_MAX</a>. @@ -3685,7 +3686,7 @@ * The following constraints apply to this configuration option: * * * The value of the configuration option shall be greater than or equal to - * one. + * zero. * * * The value of the configuration option shall be less than or equal to <a * href="https://en.cppreference.com/w/c/types/integer">UINT32_MAX</a>. diff --git a/cpukit/include/rtems/score/basedefs.h b/cpukit/include/rtems/score/basedefs.h index 4f28e6a525..010728d795 100644 --- a/cpukit/include/rtems/score/basedefs.h +++ b/cpukit/include/rtems/score/basedefs.h @@ -168,9 +168,9 @@ extern "C" { * * @return Returns the alignment requirement of the type. */ -#if __cplusplus >= 201103L +#if defined( __cplusplus ) && __cplusplus >= 201103L #define RTEMS_ALIGNOF( _type_name ) alignof( _type_name ) -#elif __STDC_VERSION__ >= 201112L +#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L #define RTEMS_ALIGNOF( _type_name ) _Alignof( _type_name ) #else #define RTEMS_ALIGNOF( _type_name ) sizeof( _type_name ) @@ -376,9 +376,9 @@ extern "C" { * @brief Tells the compiler in a function declaration that this function does * not return. */ -#if __cplusplus >= 201103L +#if defined( __cplusplus ) && __cplusplus >= 201103L #define RTEMS_NO_RETURN [[noreturn]] -#elif __STDC_VERSION__ >= 201112L +#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L #define RTEMS_NO_RETURN _Noreturn #elif defined(__GNUC__) #define RTEMS_NO_RETURN __attribute__(( __noreturn__ )) @@ -833,9 +833,9 @@ extern "C" { * * @param _msg is the error message in case the static assertion fails. */ -#if __cplusplus >= 201103L +#if defined( __cplusplus ) && __cplusplus >= 201103L #define RTEMS_STATIC_ASSERT( _cond, _msg ) static_assert( _cond, # _msg ) -#elif __STDC_VERSION__ >= 201112L +#elif defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L #define RTEMS_STATIC_ASSERT( _cond, _msg ) _Static_assert( _cond, # _msg ) #else #define RTEMS_STATIC_ASSERT( _cond, _msg ) \ diff --git a/cpukit/include/rtems/score/processormask.h b/cpukit/include/rtems/score/processormask.h index ce23f6c10d..71ed37cd0e 100644 --- a/cpukit/include/rtems/score/processormask.h +++ b/cpukit/include/rtems/score/processormask.h @@ -39,9 +39,7 @@ #include <rtems/score/cpu.h> -#include <sys/cpuset.h> - -#include <strings.h> +#include <sys/_bitset.h> #ifdef __cplusplus extern "C" { @@ -123,381 +121,6 @@ extern "C" { */ typedef __BITSET_DEFINE( Processor_mask, CPU_MAXIMUM_PROCESSORS ) Processor_mask; -/** - * @brief Sets the bits of the mask to zero, also considers CPU_MAXIMUM_PROCESSORS. - * - * @param[out] mask The mask to set to zero. - */ -static inline void _Processor_mask_Zero( Processor_mask *mask ) -{ - __BIT_ZERO( CPU_MAXIMUM_PROCESSORS, mask ); -} - -/** - * @brief Checks if the mask is zero, also considers CPU_MAXIMUM_PROCESSORS. - * - * @param mask The mask to check whether is is zero - * - * @retval true The mask is zero. - * @retval false The mask is not zero. - */ -static inline bool _Processor_mask_Is_zero( const Processor_mask *mask ) -{ - return __BIT_EMPTY( CPU_MAXIMUM_PROCESSORS, mask ); -} - -/** - * @brief Fills the mask, also considers CPU_MAXIMUM_PROCESSORS. - * - * @param[out] mask The mask to fill - */ -static inline void _Processor_mask_Fill( Processor_mask *mask ) -{ - __BIT_FILL( CPU_MAXIMUM_PROCESSORS, mask ); -} - -/** - * @brief Copies the mask to another mask, also considers CPU_MAXIMUM_PROCESSORS. - * - * @param[out] dst The mask to copy @a src to. - * @param src The mask to copy to @a dst. - */ -static inline void _Processor_mask_Assign( - Processor_mask *dst, const Processor_mask *src -) -{ - __BIT_COPY( CPU_MAXIMUM_PROCESSORS, src, dst ); -} - -/** - * @brief Sets the specified index bit of the mask. - * - * @param[out] mask The mask to set the bit of. - * @param index The index of the bit that shall be set. - */ -static inline void _Processor_mask_Set( - Processor_mask *mask, - uint32_t index -) -{ - __BIT_SET( CPU_MAXIMUM_PROCESSORS, index, mask ); -} - -/** - * @brief Clears the specified index bit of the mask. - * - * @param[out] mask The mask to clear the bit of. - * @param index The index of the bit that shall be cleared. - */ -static inline void _Processor_mask_Clear( - Processor_mask *mask, - uint32_t index -) -{ - __BIT_CLR( CPU_MAXIMUM_PROCESSORS, index, mask ); -} - -/** - * @brief Checks if the specified index bit of the mask is set. - * - * @param mask The mask to check if the specified bit is set. - * @param index The index of the bit that is checked. - * - * @retval true The specified index bit is set. - * @retval false The specified index bit is not set. - */ -static inline bool _Processor_mask_Is_set( - const Processor_mask *mask, - uint32_t index -) -{ - return __BIT_ISSET( CPU_MAXIMUM_PROCESSORS, index, mask ); -} - -/** - * @brief Checks if the processor sets a and b are equal. - * - * @param a The first processor set. - * @param b The seconde processor set. - * - * @retval true The processor sets a and b are equal. - * @retval false The processor sets a and b are not equal. - */ -static inline bool _Processor_mask_Is_equal( - const Processor_mask *a, - const Processor_mask *b -) -{ - return !__BIT_CMP( CPU_MAXIMUM_PROCESSORS, a, b ); -} - -/** - * @brief Checks if the intersection of the processor sets a and b is - * non-empty. - * - * @param a The first processor set. - * @param b The second processor set. - * - * @retval true The intersection of the processor sets a and b is non-empty. - * @retval false The intersection of the processor sets a and b is empty. - */ -static inline bool _Processor_mask_Has_overlap( - const Processor_mask *a, - const Processor_mask *b -) -{ - return __BIT_OVERLAP( CPU_MAXIMUM_PROCESSORS, a, b ); -} - -/** - * @brief Checks if the processor set small is a subset of processor set - * big. - * - * @param big The bigger processor set. - * @param small The smaller processor set. - * - * @retval true @a small is a subset of @a big. - * @retval false @a small is not a subset of @a big. - */ -static inline bool _Processor_mask_Is_subset( - const Processor_mask *big, - const Processor_mask *small -) -{ - return __BIT_SUBSET( CPU_MAXIMUM_PROCESSORS, big, small ); -} - -/** - * @brief Performs a bitwise a = b & c. - * - * @param[out] a The processor mask that is set by this operation. - * @param b The first parameter of the AND-operation. - * @param c The second parameter of the AND-operation. - */ -static inline void _Processor_mask_And( - Processor_mask *a, - const Processor_mask *b, - const Processor_mask *c -) -{ - __BIT_AND2( CPU_MAXIMUM_PROCESSORS, a, b, c ); -} - -/** - * @brief Performs a bitwise a = b | c. - * - * @param[out] a The processor mask that is set by this operation. - * @param b The first parameter of the OR-operation. - * @param c The second parameter of the OR-operation. - */ -static inline void _Processor_mask_Or( - Processor_mask *a, - const Processor_mask *b, - const Processor_mask *c -) -{ - __BIT_OR2( CPU_MAXIMUM_PROCESSORS, a, b, c ); -} - -/** - * @brief Performs a bitwise a = b ^ c. - * - * @param[out] a The processor mask that is set by this operation. - * @param b The first parameter of the XOR-operation. - * @param c The second parameter of the XOR-operation. - */ -static inline void _Processor_mask_Xor( - Processor_mask *a, - const Processor_mask *b, - const Processor_mask *c -) -{ - __BIT_XOR2( CPU_MAXIMUM_PROCESSORS, a, b, c ); -} - -/** - * @brief Gets the number of set bits in the processor mask. - * - * @param a The processor mask of which the set bits are counted. - * - * @return The number of set bits in @a a. - */ -static inline uint32_t _Processor_mask_Count( const Processor_mask *a ) -{ - return (uint32_t) __BIT_COUNT( CPU_MAXIMUM_PROCESSORS, a ); -} - -/** - * @brief Finds the last set of the processor mask. - * - * @param a The processor mask wo find the last set of. - * - * @return The last set of @a a. - */ -static inline uint32_t _Processor_mask_Find_last_set( const Processor_mask *a ) -{ - return (uint32_t) __BIT_FLS( CPU_MAXIMUM_PROCESSORS, a ); -} - -/** - * @brief Returns the subset of 32 processors containing the specified index as - * an unsigned 32-bit integer. - * - * @param mask The processor mask. - * @param index The specified index. - * - * @return The subset containing the specified index as an unsigned 32-bit integer. - */ -static inline uint32_t _Processor_mask_To_uint32_t( - const Processor_mask *mask, - uint32_t index -) -{ - long bits = mask->__bits[ index / _BITSET_BITS ]; - - return (uint32_t) ( bits >> ( 32 * ( ( index % _BITSET_BITS ) / 32 ) ) ); -} - -/** - * @brief Creates a processor set from an unsigned 32-bit integer relative to - * the specified index. - * - * @param[out] mask The mask that is created. - * @param bits The bits for creating the mask. - * @param index The index to which the mask is relative. - */ -static inline void _Processor_mask_From_uint32_t( - Processor_mask *mask, - uint32_t bits, - uint32_t index -) -{ - _Processor_mask_Zero( mask ); - mask->__bits[ __bitset_words( index ) ] = ((long) bits) << (32 * (index % _BITSET_BITS) / 32); -} - -/** - * @brief Creates a processor set from the specified index. - * - * @param[out] The mask that is created. - * @param index The specified index. - */ -static inline void _Processor_mask_From_index( - Processor_mask *mask, - uint32_t index -) -{ - __BIT_SETOF( CPU_MAXIMUM_PROCESSORS, (int) index, mask ); -} - -typedef enum { - PROCESSOR_MASK_COPY_LOSSLESS, - PROCESSOR_MASK_COPY_PARTIAL_LOSS, - PROCESSOR_MASK_COPY_COMPLETE_LOSS, - PROCESSOR_MASK_COPY_INVALID_SIZE -} Processor_mask_Copy_status; - -/** - * @brief Checks if the copy status guarantees at most partial loss. - * - * @param status The copy status to check. - * - * @retval true At most partial loss can be guaranteed. - * @retval false The status indicates more than partial loss. - */ -static inline bool _Processor_mask_Is_at_most_partial_loss( - Processor_mask_Copy_status status -) -{ - return (unsigned int) status <= PROCESSOR_MASK_COPY_PARTIAL_LOSS; -} - -/** - * @brief Copies one mask to another. - * - * @param[out] dst The destination of the copy operation. - * @param dst_size The size of @a dst. - * @param src The source of the copy operation. - * @param src_size The size of @a src. - * - * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy - * operation is lossless. - * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes - * is invalid (bigger than the size of a long). - */ -Processor_mask_Copy_status _Processor_mask_Copy( - long *dst, - size_t dst_size, - const long *src, - size_t src_size -); - -/** - * @brief Copies one mask to another. - * - * @param src The source for the copy operation. - * @param dst_size The size of @a dst. - * @param[out] dst The destination for the copy operation. - * - * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy - * operation is lossless. - * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes - * is invalid (bigger than the size of a long). - */ -static inline Processor_mask_Copy_status _Processor_mask_To_cpu_set_t( - const Processor_mask *src, - size_t dst_size, - cpu_set_t *dst -) -{ - return _Processor_mask_Copy( - &dst->__bits[ 0 ], - dst_size, - &src->__bits[ 0 ], - sizeof( *src ) - ); -} - -/** - * @brief Copies one mask to another. - * - * @param src The source for the copy operation. - * @param src_size The size of @a src. - * @param[out] dst The destination for the copy operation. - * - * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy - * operation is lossless. - * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due - * to the sizes of @a src and @a dst. - * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes - * is invalid (bigger than the size of a long). - */ -static inline Processor_mask_Copy_status _Processor_mask_From_cpu_set_t( - Processor_mask *dst, - size_t src_size, - const cpu_set_t *src -) -{ - return _Processor_mask_Copy( - &dst->__bits[ 0 ], - sizeof( *dst ), - &src->__bits[ 0 ], - src_size - ); -} - -extern const Processor_mask _Processor_mask_The_one_and_only; - /** @} */ #ifdef __cplusplus diff --git a/cpukit/include/rtems/score/processormaskimpl.h b/cpukit/include/rtems/score/processormaskimpl.h new file mode 100644 index 0000000000..bc997edfd4 --- /dev/null +++ b/cpukit/include/rtems/score/processormaskimpl.h @@ -0,0 +1,437 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSScoreProcessorMask + * + * @brief This header file provides the interfaces of the + * @ref RTEMSScoreProcessorMask. + */ + +/* + * Copyright (C) 2016, 2017 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RTEMS_SCORE_PROCESSORMASKIMPL_H +#define _RTEMS_SCORE_PROCESSORMASKIMPL_H + +#include <rtems/score/processormask.h> + +#include <sys/cpuset.h> + +#include <strings.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * @addtogroup RTEMSScoreProcessorMask + * + * @{ + */ + +/** + * @brief Sets the bits of the mask to zero, also considers CPU_MAXIMUM_PROCESSORS. + * + * @param[out] mask The mask to set to zero. + */ +static inline void _Processor_mask_Zero( Processor_mask *mask ) +{ + __BIT_ZERO( CPU_MAXIMUM_PROCESSORS, mask ); +} + +/** + * @brief Checks if the mask is zero, also considers CPU_MAXIMUM_PROCESSORS. + * + * @param mask The mask to check whether is is zero + * + * @retval true The mask is zero. + * @retval false The mask is not zero. + */ +static inline bool _Processor_mask_Is_zero( const Processor_mask *mask ) +{ + return __BIT_EMPTY( CPU_MAXIMUM_PROCESSORS, mask ); +} + +/** + * @brief Fills the mask, also considers CPU_MAXIMUM_PROCESSORS. + * + * @param[out] mask The mask to fill + */ +static inline void _Processor_mask_Fill( Processor_mask *mask ) +{ + __BIT_FILL( CPU_MAXIMUM_PROCESSORS, mask ); +} + +/** + * @brief Copies the mask to another mask, also considers CPU_MAXIMUM_PROCESSORS. + * + * @param[out] dst The mask to copy @a src to. + * @param src The mask to copy to @a dst. + */ +static inline void _Processor_mask_Assign( + Processor_mask *dst, const Processor_mask *src +) +{ + __BIT_COPY( CPU_MAXIMUM_PROCESSORS, src, dst ); +} + +/** + * @brief Sets the specified index bit of the mask. + * + * @param[out] mask The mask to set the bit of. + * @param index The index of the bit that shall be set. + */ +static inline void _Processor_mask_Set( + Processor_mask *mask, + uint32_t index +) +{ + __BIT_SET( CPU_MAXIMUM_PROCESSORS, index, mask ); +} + +/** + * @brief Clears the specified index bit of the mask. + * + * @param[out] mask The mask to clear the bit of. + * @param index The index of the bit that shall be cleared. + */ +static inline void _Processor_mask_Clear( + Processor_mask *mask, + uint32_t index +) +{ + __BIT_CLR( CPU_MAXIMUM_PROCESSORS, index, mask ); +} + +/** + * @brief Checks if the specified index bit of the mask is set. + * + * @param mask The mask to check if the specified bit is set. + * @param index The index of the bit that is checked. + * + * @retval true The specified index bit is set. + * @retval false The specified index bit is not set. + */ +static inline bool _Processor_mask_Is_set( + const Processor_mask *mask, + uint32_t index +) +{ + return __BIT_ISSET( CPU_MAXIMUM_PROCESSORS, index, mask ); +} + +/** + * @brief Checks if the processor sets a and b are equal. + * + * @param a The first processor set. + * @param b The seconde processor set. + * + * @retval true The processor sets a and b are equal. + * @retval false The processor sets a and b are not equal. + */ +static inline bool _Processor_mask_Is_equal( + const Processor_mask *a, + const Processor_mask *b +) +{ + return !__BIT_CMP( CPU_MAXIMUM_PROCESSORS, a, b ); +} + +/** + * @brief Checks if the intersection of the processor sets a and b is + * non-empty. + * + * @param a The first processor set. + * @param b The second processor set. + * + * @retval true The intersection of the processor sets a and b is non-empty. + * @retval false The intersection of the processor sets a and b is empty. + */ +static inline bool _Processor_mask_Has_overlap( + const Processor_mask *a, + const Processor_mask *b +) +{ + return __BIT_OVERLAP( CPU_MAXIMUM_PROCESSORS, a, b ); +} + +/** + * @brief Checks if the processor set small is a subset of processor set + * big. + * + * @param big The bigger processor set. + * @param small The smaller processor set. + * + * @retval true @a small is a subset of @a big. + * @retval false @a small is not a subset of @a big. + */ +static inline bool _Processor_mask_Is_subset( + const Processor_mask *big, + const Processor_mask *small +) +{ + return __BIT_SUBSET( CPU_MAXIMUM_PROCESSORS, big, small ); +} + +/** + * @brief Performs a bitwise a = b & c. + * + * @param[out] a The processor mask that is set by this operation. + * @param b The first parameter of the AND-operation. + * @param c The second parameter of the AND-operation. + */ +static inline void _Processor_mask_And( + Processor_mask *a, + const Processor_mask *b, + const Processor_mask *c +) +{ + __BIT_AND2( CPU_MAXIMUM_PROCESSORS, a, b, c ); +} + +/** + * @brief Performs a bitwise a = b | c. + * + * @param[out] a The processor mask that is set by this operation. + * @param b The first parameter of the OR-operation. + * @param c The second parameter of the OR-operation. + */ +static inline void _Processor_mask_Or( + Processor_mask *a, + const Processor_mask *b, + const Processor_mask *c +) +{ + __BIT_OR2( CPU_MAXIMUM_PROCESSORS, a, b, c ); +} + +/** + * @brief Performs a bitwise a = b ^ c. + * + * @param[out] a The processor mask that is set by this operation. + * @param b The first parameter of the XOR-operation. + * @param c The second parameter of the XOR-operation. + */ +static inline void _Processor_mask_Xor( + Processor_mask *a, + const Processor_mask *b, + const Processor_mask *c +) +{ + __BIT_XOR2( CPU_MAXIMUM_PROCESSORS, a, b, c ); +} + +/** + * @brief Gets the number of set bits in the processor mask. + * + * @param a The processor mask of which the set bits are counted. + * + * @return The number of set bits in @a a. + */ +static inline uint32_t _Processor_mask_Count( const Processor_mask *a ) +{ + return (uint32_t) __BIT_COUNT( CPU_MAXIMUM_PROCESSORS, a ); +} + +/** + * @brief Finds the last set of the processor mask. + * + * @param a The processor mask wo find the last set of. + * + * @return The last set of @a a. + */ +static inline uint32_t _Processor_mask_Find_last_set( const Processor_mask *a ) +{ + return (uint32_t) __BIT_FLS( CPU_MAXIMUM_PROCESSORS, a ); +} + +/** + * @brief Returns the subset of 32 processors containing the specified index as + * an unsigned 32-bit integer. + * + * @param mask The processor mask. + * @param index The specified index. + * + * @return The subset containing the specified index as an unsigned 32-bit integer. + */ +static inline uint32_t _Processor_mask_To_uint32_t( + const Processor_mask *mask, + uint32_t index +) +{ + long bits = mask->__bits[ index / _BITSET_BITS ]; + + return (uint32_t) ( bits >> ( 32 * ( ( index % _BITSET_BITS ) / 32 ) ) ); +} + +/** + * @brief Creates a processor set from an unsigned 32-bit integer relative to + * the specified index. + * + * @param[out] mask The mask that is created. + * @param bits The bits for creating the mask. + * @param index The index to which the mask is relative. + */ +static inline void _Processor_mask_From_uint32_t( + Processor_mask *mask, + uint32_t bits, + uint32_t index +) +{ + _Processor_mask_Zero( mask ); + mask->__bits[ __bitset_words( index ) ] = ((long) bits) << (32 * (index % _BITSET_BITS) / 32); +} + +/** + * @brief Creates a processor set from the specified index. + * + * @param[out] The mask that is created. + * @param index The specified index. + */ +static inline void _Processor_mask_From_index( + Processor_mask *mask, + uint32_t index +) +{ + __BIT_SETOF( CPU_MAXIMUM_PROCESSORS, (int) index, mask ); +} + +typedef enum { + PROCESSOR_MASK_COPY_LOSSLESS, + PROCESSOR_MASK_COPY_PARTIAL_LOSS, + PROCESSOR_MASK_COPY_COMPLETE_LOSS, + PROCESSOR_MASK_COPY_INVALID_SIZE +} Processor_mask_Copy_status; + +/** + * @brief Checks if the copy status guarantees at most partial loss. + * + * @param status The copy status to check. + * + * @retval true At most partial loss can be guaranteed. + * @retval false The status indicates more than partial loss. + */ +static inline bool _Processor_mask_Is_at_most_partial_loss( + Processor_mask_Copy_status status +) +{ + return (unsigned int) status <= PROCESSOR_MASK_COPY_PARTIAL_LOSS; +} + +/** + * @brief Copies one mask to another. + * + * @param[out] dst The destination of the copy operation. + * @param dst_size The size of @a dst. + * @param src The source of the copy operation. + * @param src_size The size of @a src. + * + * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy + * operation is lossless. + * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes + * is invalid (bigger than the size of a long). + */ +Processor_mask_Copy_status _Processor_mask_Copy( + long *dst, + size_t dst_size, + const long *src, + size_t src_size +); + +/** + * @brief Copies one mask to another. + * + * @param src The source for the copy operation. + * @param dst_size The size of @a dst. + * @param[out] dst The destination for the copy operation. + * + * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy + * operation is lossless. + * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes + * is invalid (bigger than the size of a long). + */ +static inline Processor_mask_Copy_status _Processor_mask_To_cpu_set_t( + const Processor_mask *src, + size_t dst_size, + cpu_set_t *dst +) +{ + return _Processor_mask_Copy( + &dst->__bits[ 0 ], + dst_size, + &src->__bits[ 0 ], + sizeof( *src ) + ); +} + +/** + * @brief Copies one mask to another. + * + * @param src The source for the copy operation. + * @param src_size The size of @a src. + * @param[out] dst The destination for the copy operation. + * + * @retval PROCESSOR_MASK_COPY_LOSSLESS It is guaranteed that the copy + * operation is lossless. + * @retval PROCESSOR_MASK_COPY_PARTIAL_LOSS Partial loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_COMPLETE_LOSS Complete loss happened due + * to the sizes of @a src and @a dst. + * @retval PROCESSOR_MASK_COPY_INVALID_SIZE One of the arguments sizes + * is invalid (bigger than the size of a long). + */ +static inline Processor_mask_Copy_status _Processor_mask_From_cpu_set_t( + Processor_mask *dst, + size_t src_size, + const cpu_set_t *src +) +{ + return _Processor_mask_Copy( + &dst->__bits[ 0 ], + sizeof( *dst ), + &src->__bits[ 0 ], + src_size + ); +} + +extern const Processor_mask _Processor_mask_The_one_and_only; + +/** @} */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _RTEMS_SCORE_PROCESSORMASKIMPL_H */ diff --git a/cpukit/include/rtems/score/smpimpl.h b/cpukit/include/rtems/score/smpimpl.h index 2ffc047070..a8e3a3be15 100644 --- a/cpukit/include/rtems/score/smpimpl.h +++ b/cpukit/include/rtems/score/smpimpl.h @@ -40,7 +40,7 @@ #include <rtems/score/smp.h> #include <rtems/score/percpu.h> -#include <rtems/score/processormask.h> +#include <rtems/score/processormaskimpl.h> #include <rtems/fatal.h> #ifdef __cplusplus diff --git a/cpukit/score/src/processormaskcopy.c b/cpukit/score/src/processormaskcopy.c index 863bd1574e..3f1c2cf250 100644 --- a/cpukit/score/src/processormaskcopy.c +++ b/cpukit/score/src/processormaskcopy.c @@ -39,7 +39,7 @@ #include "config.h" #endif -#include <rtems/score/processormask.h> +#include <rtems/score/processormaskimpl.h> const Processor_mask _Processor_mask_The_one_and_only = { .__bits[ 0 ] = 1 }; diff --git a/spec/build/bsps/aarch64/grp.yml b/spec/build/bsps/aarch64/grp.yml index 9428fb9435..8f40a9952e 100644 --- a/spec/build/bsps/aarch64/grp.yml +++ b/spec/build/bsps/aarch64/grp.yml @@ -12,9 +12,6 @@ install: source: - bsps/aarch64/include/bsp/linker-symbols.h - bsps/aarch64/include/bsp/start.h -- destination: ${BSP_INCLUDEDIR}/dev/clock - source: - - bsps/include/dev/clock/arm-generic-timer.h - destination: ${BSP_INCLUDEDIR}/dev/irq source: - bsps/aarch64/include/dev/irq/arm-gic-arch.h diff --git a/spec/build/bsps/aarch64/raspberrypi/bspraspberrypi4.yml b/spec/build/bsps/aarch64/raspberrypi/bspraspberrypi4.yml index a579c094ba..7b6511a8cc 100644 --- a/spec/build/bsps/aarch64/raspberrypi/bspraspberrypi4.yml +++ b/spec/build/bsps/aarch64/raspberrypi/bspraspberrypi4.yml @@ -20,6 +20,10 @@ install: - bsps/aarch64/raspberrypi/include/bsp/raspberrypi.h links: - role: build-dependency + uid: objclock +- role: build-dependency + uid: objsystemtimer +- role: build-dependency uid: ../grp - role: build-dependency uid: ../start @@ -50,10 +54,8 @@ source: - bsps/aarch64/raspberrypi/start/bspstart.c - bsps/aarch64/raspberrypi/start/bspstarthooks.c - bsps/aarch64/raspberrypi/start/bspstartmmu.c -- bsps/aarch64/shared/clock/arm-generic-timer-aarch64.c - bsps/aarch64/shared/cache/cache.c - bsps/aarch64/shared/mmu/vmsav8-64.c -- bsps/shared/dev/clock/arm-generic-timer.c - bsps/shared/dev/irq/arm-gicv2.c - bsps/shared/dev/irq/arm-gicv2-get-attributes.c - bsps/shared/dev/serial/console-termios-init.c diff --git a/spec/build/bsps/aarch64/raspberrypi/objclock.yml b/spec/build/bsps/aarch64/raspberrypi/objclock.yml new file mode 100644 index 0000000000..24f61c93c4 --- /dev/null +++ b/spec/build/bsps/aarch64/raspberrypi/objclock.yml @@ -0,0 +1,31 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: + - Copyright (C) 2022 Mohd Noor Aman + - Copyright (C) 2023 Utkarsh Verma + - Copyright (C) 2024 Ning Yang + +type: build +enabled-by: + not: BSP_CLOCK_USE_SYSTEMTIMER + +build-type: objects +cflags: [] +cppflags: [] +cxxflags: [] +includes: [] +install: +- destination: ${BSP_INCLUDEDIR}/dev/clock + source: + - bsps/include/dev/clock/arm-generic-timer.h + +source: + - bsps/aarch64/shared/clock/arm-generic-timer-aarch64.c + - bsps/shared/dev/clock/arm-generic-timer.c + +links: + - role: build-dependency + uid: ../optgtusevirt + - role: build-dependency + uid: ../optgtuseps + - role: build-dependency + uid: optsystemtimer
\ No newline at end of file diff --git a/spec/build/bsps/aarch64/raspberrypi/objsystemtimer.yml b/spec/build/bsps/aarch64/raspberrypi/objsystemtimer.yml new file mode 100644 index 0000000000..1ead15fdd5 --- /dev/null +++ b/spec/build/bsps/aarch64/raspberrypi/objsystemtimer.yml @@ -0,0 +1,23 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: + - Copyright (C) 2024 Ning Yang + +type: build +enabled-by: +- BSP_CLOCK_USE_SYSTEMTIMER + +build-type: objects +cflags: [] +cppflags: [] +cxxflags: [] +includes: [] +install: [] + +source: + - bsps/shared/dev/clock/bcm2835-system-timer.c + - bsps/shared/dev/cpucounter/cpucounterfrequency.c + - bsps/shared/dev/cpucounter/cpucounterread.c + +links: + - role: build-dependency + uid: optsystemtimer
\ No newline at end of file diff --git a/spec/build/bsps/aarch64/raspberrypi/optsystemtimer.yml b/spec/build/bsps/aarch64/raspberrypi/optsystemtimer.yml new file mode 100644 index 0000000000..c20371ab8b --- /dev/null +++ b/spec/build/bsps/aarch64/raspberrypi/optsystemtimer.yml @@ -0,0 +1,25 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +copyrights: + - Copyright (C) 2024 Ning Yang + +type: build +build-type: option + +enabled-by: true +name: BSP_CLOCK_USE_SYSTEMTIMER +description: | + The clock from the ARM timer is derived from the system clock. This clock can + change dynamically e.g. if the system goes into reduced power or in low power + mode. Thus the clock speed adapts to the overall system performance + capabilities. For accurate timing it is recommended to use the system timers. + +actions: + - get-boolean: null + - define-condition: null + - env-enable: null +default: + - enabled-by: + - aarch64/raspberrypi4b + value: false + +links: []
\ No newline at end of file diff --git a/spec/build/bsps/aarch64/xilinx-zynqmp/grp.yml b/spec/build/bsps/aarch64/xilinx-zynqmp/grp.yml index a00490a826..00b1060be6 100644 --- a/spec/build/bsps/aarch64/xilinx-zynqmp/grp.yml +++ b/spec/build/bsps/aarch64/xilinx-zynqmp/grp.yml @@ -39,8 +39,6 @@ links: - role: build-dependency uid: optclkuart - role: build-dependency - uid: ../../optconminor -- role: build-dependency uid: ../../obj - role: build-dependency uid: ../../objirq diff --git a/spec/build/bsps/arm/raspberrypi/obj.yml b/spec/build/bsps/arm/raspberrypi/obj.yml index ec5c82a8fb..ea370829df 100644 --- a/spec/build/bsps/arm/raspberrypi/obj.yml +++ b/spec/build/bsps/arm/raspberrypi/obj.yml @@ -26,7 +26,6 @@ install: - bsps/arm/raspberrypi/include/bsp/vc.h links: [] source: -- bsps/arm/raspberrypi/clock/clockdrv.c - bsps/arm/raspberrypi/console/console-config.c - bsps/arm/raspberrypi/console/fb.c - bsps/arm/raspberrypi/console/fbcons.c @@ -47,6 +46,7 @@ source: - bsps/arm/shared/cp15/arm-cp15-set-exception-handler.c - bsps/arm/shared/cp15/arm-cp15-set-ttb-entries.c - bsps/arm/shared/start/bsp-start-memcpy.S +- bsps/shared/dev/clock/bcm2835-system-timer.c - bsps/shared/dev/cpucounter/cpucounterfrequency.c - bsps/shared/dev/cpucounter/cpucounterread.c - bsps/shared/dev/getentropy/getentropy-cpucounter.c diff --git a/spec/build/bsps/arm/xilinx-zynq/grp.yml b/spec/build/bsps/arm/xilinx-zynq/grp.yml index eeffea0e63..529fdb320f 100644 --- a/spec/build/bsps/arm/xilinx-zynq/grp.yml +++ b/spec/build/bsps/arm/xilinx-zynq/grp.yml @@ -35,8 +35,6 @@ links: - role: build-dependency uid: optconirq - role: build-dependency - uid: ../../optconminor -- role: build-dependency uid: optint0len - role: build-dependency uid: optint0ori diff --git a/spec/build/bsps/arm/xilinx-zynq/obj.yml b/spec/build/bsps/arm/xilinx-zynq/obj.yml index 505c2afcc4..bc7259c10a 100644 --- a/spec/build/bsps/arm/xilinx-zynq/obj.yml +++ b/spec/build/bsps/arm/xilinx-zynq/obj.yml @@ -26,9 +26,7 @@ source: - bsps/arm/shared/cp15/arm-cp15-set-exception-handler.c - bsps/arm/shared/cp15/arm-cp15-set-ttb-entries.c - bsps/arm/shared/start/bsp-start-memcpy.S -- bsps/arm/xilinx-zynq/console/console-config.c - bsps/arm/xilinx-zynq/console/console-init.c -- bsps/arm/xilinx-zynq/console/debug-console.c - bsps/shared/dev/i2c/cadence-i2c.c - bsps/arm/xilinx-zynq/start/bspreset.c - bsps/arm/xilinx-zynq/start/bspstart.c diff --git a/spec/build/bsps/arm/xilinx-zynqmp-rpu/grp.yml b/spec/build/bsps/arm/xilinx-zynqmp-rpu/grp.yml index b886948d47..a088c69052 100644 --- a/spec/build/bsps/arm/xilinx-zynqmp-rpu/grp.yml +++ b/spec/build/bsps/arm/xilinx-zynqmp-rpu/grp.yml @@ -25,7 +25,11 @@ links: - role: build-dependency uid: optconirq - role: build-dependency - uid: ../../optconminor + uid: ../../optxilclockttcbaseaddr +- role: build-dependency + uid: ../../optxilclockttcirq +- role: build-dependency + uid: ../../optxilclockttcrefclk - role: build-dependency uid: optint0len - role: build-dependency diff --git a/spec/build/bsps/arm/xilinx-zynqmp/bspxilinxzynqmp.yml b/spec/build/bsps/arm/xilinx-zynqmp/bspxilinxzynqmp.yml index 53c5b4d7d2..d947123247 100644 --- a/spec/build/bsps/arm/xilinx-zynqmp/bspxilinxzynqmp.yml +++ b/spec/build/bsps/arm/xilinx-zynqmp/bspxilinxzynqmp.yml @@ -43,8 +43,6 @@ links: - role: build-dependency uid: optconirq - role: build-dependency - uid: ../../optconminor -- role: build-dependency uid: optint0len - role: build-dependency uid: optint0ori diff --git a/spec/build/bsps/objdevserialzynq.yml b/spec/build/bsps/objdevserialzynq.yml index deb3c83a33..a187ebfc10 100644 --- a/spec/build/bsps/objdevserialzynq.yml +++ b/spec/build/bsps/objdevserialzynq.yml @@ -12,8 +12,13 @@ install: source: - bsps/include/dev/serial/zynq-uart-regs.h - bsps/include/dev/serial/zynq-uart.h -links: [] + - bsps/include/dev/serial/zynq-uart-zynq.h + - bsps/include/dev/serial/zynq-uart-zynqmp.h +links: +- role: build-dependency + uid: optzynquartkernbase source: +- bsps/shared/dev/serial/zynq-uart-kernel-io.c - bsps/shared/dev/serial/zynq-uart-polled.c - bsps/shared/dev/serial/zynq-uart.c type: build diff --git a/spec/build/bsps/optxilclockttcbaseaddr.yml b/spec/build/bsps/optxilclockttcbaseaddr.yml new file mode 100644 index 0000000000..c6f4769428 --- /dev/null +++ b/spec/build/bsps/optxilclockttcbaseaddr.yml @@ -0,0 +1,18 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +actions: +- get-integer: null +- format-and-define: null +build-type: option +copyrights: +- Copyright (C) 2024 embedded brains GmbH & Co. KG +default: +- enabled-by: true + value: 0xff110000 +description: | + This option defines the Xilinx Triple-Timer Counter (TTC) base address used by + the Clock Driver. +enabled-by: true +format: '{:#010x}' +links: [] +name: XIL_CLOCK_TTC_BASE_ADDR +type: build diff --git a/spec/build/bsps/optconminor.yml b/spec/build/bsps/optxilclockttcirq.yml index 9bb84e0c9e..248e4e313b 100644 --- a/spec/build/bsps/optconminor.yml +++ b/spec/build/bsps/optxilclockttcirq.yml @@ -4,18 +4,15 @@ actions: - define: null build-type: option copyrights: -- Copyright (C) 2020 embedded brains GmbH & Co. KG +- Copyright (C) 2024 embedded brains GmbH & Co. KG default: -- enabled-by: - - bsps/aarch64/xilinx-zynqmp - - arm/xilinx_zynq_microzed - value: 0 - enabled-by: true - value: 1 + value: 68 description: | - minor number of console device + This option defines the Xilinx Triple-Timer Counter (TTC) interrupt vector + number used by the Clock Driver. enabled-by: true format: '{}' links: [] -name: BSP_CONSOLE_MINOR +name: XIL_CLOCK_TTC_IRQ type: build diff --git a/spec/build/bsps/optxilclockttcrefclk.yml b/spec/build/bsps/optxilclockttcrefclk.yml new file mode 100644 index 0000000000..0a9723828b --- /dev/null +++ b/spec/build/bsps/optxilclockttcrefclk.yml @@ -0,0 +1,18 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +actions: +- get-integer: null +- define: null +build-type: option +copyrights: +- Copyright (C) 2024 embedded brains GmbH & Co. KG +default: +- enabled-by: true + value: 100000000 +description: | + This option defines the Xilinx Triple-Timer Counter (TTC) reference clock in + Hz used by the Clock Driver. +enabled-by: true +format: '{}' +links: [] +name: XIL_CLOCK_TTC_REFERENCE_CLOCK +type: build diff --git a/spec/build/bsps/optzynquartkernbase.yml b/spec/build/bsps/optzynquartkernbase.yml new file mode 100644 index 0000000000..8aba1c224f --- /dev/null +++ b/spec/build/bsps/optzynquartkernbase.yml @@ -0,0 +1,22 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +actions: +- get-string: null +- define-unquoted: null +build-type: option +copyrights: +- Copyright (C) 2024 embedded brains GmbH & Co. KG +default: +- enabled-by: + - bsps/aarch64/xilinx-zynqmp + - arm/xilinx_zynq_microzed + value: ZYNQ_UART_0_BASE_ADDR +- enabled-by: true + value: ZYNQ_UART_1_BASE_ADDR +description: | + This option defines the Xilinx Zynq UART base address used by the kernel I/O + device. +enabled-by: true +format: '{}' +links: [] +name: ZYNQ_UART_KERNEL_IO_BASE_ADDR +type: build diff --git a/spec/build/bsps/powerpc/qoriq/obj.yml b/spec/build/bsps/powerpc/qoriq/obj.yml index b0ab1e6ca2..046ad4166b 100644 --- a/spec/build/bsps/powerpc/qoriq/obj.yml +++ b/spec/build/bsps/powerpc/qoriq/obj.yml @@ -60,7 +60,6 @@ source: - bsps/powerpc/qoriq/start/restart.S - bsps/powerpc/shared/cache/cache.c - bsps/powerpc/shared/exceptions/ppc-exc-handler-table.c -- bsps/powerpc/shared/mmu/e500-mmu.c - bsps/powerpc/shared/start/bsp-start-zero.S - bsps/powerpc/shared/start/bspidle.c - bsps/powerpc/shared/start/tictac.c diff --git a/spec/build/cpukit/librtemscpu.yml b/spec/build/cpukit/librtemscpu.yml index f40dae98db..196a8acd4e 100644 --- a/spec/build/cpukit/librtemscpu.yml +++ b/spec/build/cpukit/librtemscpu.yml @@ -380,6 +380,7 @@ install: - cpukit/include/rtems/score/prioritybitmapimpl.h - cpukit/include/rtems/score/priorityimpl.h - cpukit/include/rtems/score/processormask.h + - cpukit/include/rtems/score/processormaskimpl.h - cpukit/include/rtems/score/profiling.h - cpukit/include/rtems/score/protectedheap.h - cpukit/include/rtems/score/rbtree.h diff --git a/spec/build/testsuites/validation/bsps/fatal-clock-xil-ttc-irq-install.yml b/spec/build/testsuites/validation/bsps/fatal-clock-xil-ttc-irq-install.yml new file mode 100644 index 0000000000..253131551d --- /dev/null +++ b/spec/build/testsuites/validation/bsps/fatal-clock-xil-ttc-irq-install.yml @@ -0,0 +1,21 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: test-program +cflags: [] +copyrights: +- Copyright (C) 2024 embedded brains GmbH & Co. KG +cppflags: [] +cxxflags: [] +enabled-by: bsps/arm/xilinx-zynqmp-rpu +features: c cprogram +includes: [] +ldflags: [] +links: [] +source: +- testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.c +- testsuites/validation/bsps/ts-fatal-clock-xil-ttc-irq-install.c +stlib: [] +target: testsuites/validation/bsps/ts-fatal-clock-xil-ttc-irq-install.exe +type: build +use-after: +- validation +use-before: [] diff --git a/spec/build/testsuites/validation/bsps/objclockxilttc.yml b/spec/build/testsuites/validation/bsps/objclockxilttc.yml new file mode 100644 index 0000000000..b080bcdbfb --- /dev/null +++ b/spec/build/testsuites/validation/bsps/objclockxilttc.yml @@ -0,0 +1,14 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: objects +cflags: [] +copyrights: +- Copyright (C) 2024 embedded brains GmbH & Co. KG +cppflags: [] +cxxflags: [] +enabled-by: bsps/arm/xilinx-zynqmp-rpu +includes: [] +install: [] +links: [] +source: +- testsuites/validation/tc-dev-clock-xil-ttc.c +type: build diff --git a/spec/build/testsuites/validation/bsps/validation-bsp-0.yml b/spec/build/testsuites/validation/bsps/validation-bsp-0.yml index af811b8502..790e05e0bc 100644 --- a/spec/build/testsuites/validation/bsps/validation-bsp-0.yml +++ b/spec/build/testsuites/validation/bsps/validation-bsp-0.yml @@ -5,13 +5,17 @@ copyrights: - Copyright (C) 2023 embedded brains GmbH & Co. KG cppflags: [] cxxflags: [] -enabled-by: bsps/sparc/leon3 +enabled-by: +- bsps/arm/xilinx-zynqmp-rpu +- bsps/sparc/leon3 features: c cprogram includes: [] ldflags: - -Wl,--wrap=_IO_Relax links: - role: build-dependency + uid: objclockxilttc +- role: build-dependency uid: objgrlib - role: build-dependency uid: objsparcgr712rc diff --git a/spec/build/testsuites/validation/grp.yml b/spec/build/testsuites/validation/grp.yml index 726cf732dd..f10c6a9823 100644 --- a/spec/build/testsuites/validation/grp.yml +++ b/spec/build/testsuites/validation/grp.yml @@ -79,6 +79,8 @@ links: - role: build-dependency uid: validation-tls-1 - role: build-dependency + uid: bsps/fatal-clock-xil-ttc-irq-install +- role: build-dependency uid: bsps/fatal-sparc-leon3-cache-snooping-disabled-boot - role: build-dependency uid: bsps/fatal-sparc-leon3-cache-snooping-disabled-secondary diff --git a/spec/build/testsuites/validation/objpreinitarray.yml b/spec/build/testsuites/validation/objpreinitarray.yml index d4542485b2..c38460ebfe 100644 --- a/spec/build/testsuites/validation/objpreinitarray.yml +++ b/spec/build/testsuites/validation/objpreinitarray.yml @@ -6,6 +6,7 @@ copyrights: cppflags: [] cxxflags: [] enabled-by: +- aarch64 - arm - riscv includes: [] diff --git a/testsuites/smptests/smpipi01/init.c b/testsuites/smptests/smpipi01/init.c index 290d13775f..f8172fed96 100644 --- a/testsuites/smptests/smpipi01/init.c +++ b/testsuites/smptests/smpipi01/init.c @@ -198,6 +198,43 @@ static const Per_CPU_Job_context counter_1_job_context = { .arg = &test_instance }; +static void sync_handler(void *arg) +{ + test_context *ctx = arg; + SMP_barrier_State *bs = &ctx->worker_barrier_state; + + /* (E) */ + barrier(ctx, bs); +} + +static const Per_CPU_Job_context sync_context = { + .handler = sync_handler, + .arg = &test_instance +}; + +static void wait_for_ipi_done(test_context *ctx, Per_CPU_Control *cpu) +{ + Per_CPU_Job job; + unsigned long done; + + job.context = &sync_context; + _Per_CPU_Submit_job(cpu, &job); + + while (cpu->isr_nest_level == 0) { + RTEMS_COMPILER_MEMORY_BARRIER(); + } + + /* (E) */ + barrier(ctx, &ctx->main_barrier_state); + + while (cpu->isr_nest_level != 0) { + RTEMS_COMPILER_MEMORY_BARRIER(); + } + + done = _Atomic_Load_ulong( &job.done, ATOMIC_ORDER_ACQUIRE ); + rtems_test_assert( done == PER_CPU_JOB_DONE ); +} + static void test_send_message_flood( test_context *ctx, uint32_t cpu_count @@ -211,20 +248,15 @@ static void test_send_message_flood( ctx->jobs[cpu_index][0].context = &counter_0_job_context; ctx->jobs[cpu_index][1].context = &counter_1_job_context; - _Per_CPU_Submit_job(cpu, &ctx->jobs[cpu_index][0]); + _Per_CPU_Add_job(cpu, &ctx->jobs[cpu_index][0]); } for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { Per_CPU_Control *cpu; - Per_CPU_Control *cpu_self; uint32_t i; cpu = _Per_CPU_Get_by_index(cpu_index); - cpu_self = _Thread_Dispatch_disable(); - _SMP_Synchronize(); - _Thread_Dispatch_enable(cpu_self); - for (i = 0; i < cpu_count; ++i) { if (i != cpu_index) { ctx->copy_counters[i] = ctx->counters[i].value; @@ -235,6 +267,10 @@ static void test_send_message_flood( _SMP_Send_message(cpu, SMP_MESSAGE_PERFORM_JOBS); } + if (cpu_index != cpu_index_self) { + wait_for_ipi_done(ctx, cpu); + } + for (i = 0; i < cpu_count; ++i) { if (i != cpu_index) { rtems_test_assert(ctx->copy_counters[i] == ctx->counters[i].value); diff --git a/testsuites/smptests/smpmulticast01/init.c b/testsuites/smptests/smpmulticast01/init.c index ef8a1dbcb4..51a4624ea1 100644 --- a/testsuites/smptests/smpmulticast01/init.c +++ b/testsuites/smptests/smpmulticast01/init.c @@ -563,14 +563,16 @@ static void fatal_extension( bool ok; if (source == RTEMS_FATAL_SOURCE_SMP) { - T_step_eq_int(1, source, RTEMS_FATAL_SOURCE_SMP); - T_step_false(2, always_set_to_false, "unexpected argument value"); - T_step_eq_int(3, code, SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS); - T_case_end(); - - ok = T_run_finalize(); - rtems_test_assert(ok); - TEST_END(); + if (code != SMP_FATAL_SHUTDOWN_RESPONSE) { + T_step_eq_int(1, source, RTEMS_FATAL_SOURCE_SMP); + T_step_false(2, always_set_to_false, "unexpected argument value"); + T_step_eq_int(3, code, SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS); + T_case_end(); + + ok = T_run_finalize(); + rtems_test_assert(ok); + TEST_END(); + } } else if (source == RTEMS_FATAL_SOURCE_APPLICATION) { ok = T_run_finalize(); rtems_test_assert(ok); diff --git a/testsuites/unit/tc-compiler-builtins.c b/testsuites/unit/tc-compiler-builtins.c index 3beebe06fa..7a470b6632 100644 --- a/testsuites/unit/tc-compiler-builtins.c +++ b/testsuites/unit/tc-compiler-builtins.c @@ -130,6 +130,16 @@ uint64_t __udivmoddi4( uint64_t n, uint64_t d, uint64_t *r ); #endif +#if defined(TEST_UDIVMODDI4) && defined(__arm__) +/* + * Here __aeabi_uldivmod() may be used to carry out integer division + * operations even though the reminder is unused. This function is + * implemented by __udivmoddi4() which may never get called without a + * reminder for compiler generated code. + */ +#define TEST_UDIVMODDI4_WITHOUT_REMINDER +#endif + static bool do_longjmp; static jmp_buf exception_return_context; @@ -174,6 +184,9 @@ static void CompilerUnitBuiltins_Action_0( void ) { volatile unsigned int n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 1U; T_eq_int( __builtin_clz( n ), 31 ); @@ -192,6 +205,9 @@ static void CompilerUnitBuiltins_Action_1( void ) { volatile unsigned long long n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 1ULL; T_eq_int( __builtin_clzll( n ), 63 ); @@ -215,6 +231,9 @@ static void CompilerUnitBuiltins_Action_2( void ) { volatile unsigned int n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 1U; T_eq_int( __builtin_ctz( n ), 0 ); @@ -233,6 +252,9 @@ static void CompilerUnitBuiltins_Action_3( void ) { volatile unsigned long long n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 1ULL; T_eq_int( __builtin_ctzll( n ), 0 ); @@ -256,6 +278,9 @@ static void CompilerUnitBuiltins_Action_4( void ) { volatile unsigned int n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 1U; T_eq_int( __builtin_ffs( n ), 1 ); @@ -274,6 +299,9 @@ static void CompilerUnitBuiltins_Action_5( void ) { volatile unsigned long long n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 1ULL; T_eq_int( __builtin_ffsll( n ), 1 ); @@ -298,6 +326,9 @@ static void CompilerUnitBuiltins_Action_6( void ) { volatile unsigned int n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 1U; T_eq_int( __builtin_parity( n ), 1 ); @@ -313,6 +344,9 @@ static void CompilerUnitBuiltins_Action_7( void ) { volatile unsigned long long n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 1ULL; T_eq_int( __builtin_parityll( n ), 1 ); @@ -328,6 +362,9 @@ static void CompilerUnitBuiltins_Action_8( void ) { volatile unsigned int n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 0U; T_eq_int( __builtin_popcount( n ), 0 ); @@ -346,6 +383,9 @@ static void CompilerUnitBuiltins_Action_9( void ) { volatile unsigned long long n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = 0ULL; T_eq_int( __builtin_popcountll( n ), 0 ); @@ -364,6 +404,9 @@ static void CompilerUnitBuiltins_Action_10( void ) { volatile uint32_t n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = UINT32_C( 0 ); T_eq_u32( __builtin_bswap32( n ), n ); @@ -385,6 +428,9 @@ static void CompilerUnitBuiltins_Action_11( void ) { volatile uint64_t n; + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + n = UINT64_C( 0 ); T_eq_u64( __builtin_bswap64( n ), n ); @@ -406,6 +452,11 @@ static void CompilerUnitBuiltins_Action_12( void ) volatile int64_t a; volatile int64_t b; + a = 0; + RTEMS_OBFUSCATE_VARIABLE( a ); + b = 0; + RTEMS_OBFUSCATE_VARIABLE( b ); + a = INT64_C( 0 ); b = INT64_C( 0 ); T_false( a < b ); @@ -431,6 +482,11 @@ static void CompilerUnitBuiltins_Action_13( void ) volatile uint64_t a; volatile uint64_t b; + a = 0; + RTEMS_OBFUSCATE_VARIABLE( a ); + b = 0; + RTEMS_OBFUSCATE_VARIABLE( b ); + a = UINT64_C( 0 ); b = UINT64_C( 0 ); T_false( a < b ); @@ -456,6 +512,11 @@ static void CompilerUnitBuiltins_Action_14( void ) volatile int64_t i; volatile int s; + i = 0; + RTEMS_OBFUSCATE_VARIABLE( i ); + s = 0; + RTEMS_OBFUSCATE_VARIABLE( s ); + i = INT64_C( 1 ); s = 0; T_eq_i64( i << s, INT64_C( 1 ) ); @@ -482,6 +543,11 @@ static void CompilerUnitBuiltins_Action_15( void ) volatile int64_t i; volatile int s; + i = 0; + RTEMS_OBFUSCATE_VARIABLE( i ); + s = 0; + RTEMS_OBFUSCATE_VARIABLE( s ); + i = INT64_C( 1 ); s = 0; T_eq_i64( i >> s, INT64_C( 1 ) ); @@ -507,6 +573,11 @@ static void CompilerUnitBuiltins_Action_16( void ) volatile uint64_t i; volatile int s; + i = 0; + RTEMS_OBFUSCATE_VARIABLE( i ); + s = 0; + RTEMS_OBFUSCATE_VARIABLE( s ); + i = UINT64_C( 1 ); s = 0; T_eq_u64( i >> s, UINT64_C( 1 ) ); @@ -532,6 +603,11 @@ static void CompilerUnitBuiltins_Action_17( void ) volatile int64_t a; volatile int64_t b; + a = 0; + RTEMS_OBFUSCATE_VARIABLE( a ); + b = 0; + RTEMS_OBFUSCATE_VARIABLE( b ); + a = INT64_C( 1 ); b = INT64_C( 1 ); T_eq_i64( a * b, INT64_C( 1 ) ); @@ -552,6 +628,9 @@ static void CompilerUnitBuiltins_Action_18( void ) { volatile int64_t i; + i = 0; + RTEMS_OBFUSCATE_VARIABLE( i ); + i = INT64_C( 1 ); T_eq_i64( -i, -INT64_C( 1 ) ); @@ -566,13 +645,21 @@ static void CompilerUnitBuiltins_Action_19( void ) { volatile int64_t n; volatile int64_t d; + volatile int64_t x; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + d = 0; + RTEMS_OBFUSCATE_VARIABLE( d ); + x = 0; + RTEMS_OBFUSCATE_VARIABLE( x ); n = INT64_C( 0 ); d = INT64_C( 0 ); do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n / d; + x = n / d; } n = INT64_C( 1 ); @@ -580,7 +667,7 @@ static void CompilerUnitBuiltins_Action_19( void ) do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n / d; + x = n / d; } n = INT64_C( 0x7fffffffffffffff ); @@ -588,7 +675,7 @@ static void CompilerUnitBuiltins_Action_19( void ) do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n / d; + x = n / d; } n = INT64_C( 0x7fffffff00000000 ); @@ -596,7 +683,7 @@ static void CompilerUnitBuiltins_Action_19( void ) do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n / d; + x = n / d; } n = INT64_C( 0 ); @@ -675,74 +762,164 @@ static void CompilerUnitBuiltins_Action_20( void ) { volatile uint64_t n; volatile uint64_t d; + volatile uint64_t x; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + d = 0; + RTEMS_OBFUSCATE_VARIABLE( d ); + x = 0; + RTEMS_OBFUSCATE_VARIABLE( x ); n = UINT64_C( 0 ); d = UINT64_C( 0 ); do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n / d; + x = n / d; } + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); + } + #endif + n = UINT64_C( 1 ); d = UINT64_C( 0 ); do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n / d; + x = n / d; + } + + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); } + #endif n = UINT64_C( 0x7fffffffffffffff ); d = UINT64_C( 0 ); do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n / d; + x = n / d; + } + + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); } + #endif n = UINT64_C( 0x7fffffff00000000 ); d = UINT64_C( 0 ); do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n / d; + x = n / d; + } + + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); + } + #endif + + n = UINT64_C( 0x7fffffff00000000 ); + d = UINT64_C( 0x7fffffff00000000 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; } + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); + } + #endif + n = UINT64_C( 0 ); d = UINT64_C( 1 ); T_eq_u64( n / d, UINT64_C( 0 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) ); + #endif n = UINT64_C( 1 ); d = UINT64_C( 1 ); T_eq_u64( n / d, UINT64_C( 1 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 1 ) ); + #endif n = UINT64_C( 0xffffffffffffffff ); d = UINT64_C( 1 ); T_eq_u64( n / d, UINT64_C( 0xffffffffffffffff ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0xffffffffffffffff ) ); + #endif n = UINT64_C( 2 ); d = UINT64_C( 1 ); T_eq_u64( n / d, UINT64_C( 2 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 2 ) ); + #endif n = UINT64_C( 1 ); d = UINT64_C( 0xffffffffffffffff ); T_eq_u64( n / d, UINT64_C( 0 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) ); + #endif n = UINT64_C( 0xffffffffffffffff ); d = UINT64_C( 0xffffffffffffffff ); T_eq_u64( n / d, UINT64_C( 1 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 1 ) ); + #endif n = UINT64_C( 0xffffffffffffffff ); d = UINT64_C( 0x8000000000000000 ); T_eq_u64( n / d, UINT64_C( 1 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 1 ) ); + #endif n = UINT64_C( 0x0000000100000001 ); d = UINT64_C( 0x0000000f00000000 ); T_eq_u64( n / d, UINT64_C( 0 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) ); + #endif + + n = UINT64_C( 0x0000000100000000 ); + d = UINT64_C( 0x0000000f00000001 ); + T_eq_u64( n / d, UINT64_C( 0 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) ); + #endif n = UINT64_C( 0xffffffff0000000f ); d = UINT64_C( 0x000000010000000f ); T_eq_u64( n / d, UINT64_C( 4294967280 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 4294967280 ) ); + #endif } /** @@ -752,13 +929,21 @@ static void CompilerUnitBuiltins_Action_21( void ) { volatile int64_t n; volatile int64_t d; + volatile int64_t x; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + d = 0; + RTEMS_OBFUSCATE_VARIABLE( d ); + x = 0; + RTEMS_OBFUSCATE_VARIABLE( x ); n = INT64_C( 0 ); d = INT64_C( 0 ); do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n % d; + x = n % d; } n = INT64_C( 1 ); @@ -766,7 +951,7 @@ static void CompilerUnitBuiltins_Action_21( void ) do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n % d; + x = n % d; } n = INT64_C( 0x7fffffffffffffff ); @@ -774,7 +959,7 @@ static void CompilerUnitBuiltins_Action_21( void ) do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n % d; + x = n % d; } n = INT64_C( 0x7fffffff00000000 ); @@ -782,7 +967,7 @@ static void CompilerUnitBuiltins_Action_21( void ) do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n % d; + x = n % d; } n = INT64_C( 0 ); @@ -873,13 +1058,21 @@ static void CompilerUnitBuiltins_Action_22( void ) { volatile uint64_t n; volatile uint64_t d; + volatile uint64_t x; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + d = 0; + RTEMS_OBFUSCATE_VARIABLE( d ); + x = 0; + RTEMS_OBFUSCATE_VARIABLE( x ); n = UINT64_C( 0 ); d = UINT64_C( 0 ); do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n % d; + x = n % d; } n = UINT64_C( 1 ); @@ -887,7 +1080,7 @@ static void CompilerUnitBuiltins_Action_22( void ) do_longjmp = true; if ( setjmp( exception_return_context ) == 0 ) { - n = n % d; + x = n % d; } n = UINT64_C( 0 ); diff --git a/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.c b/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.c new file mode 100644 index 0000000000..731b454ee4 --- /dev/null +++ b/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.c @@ -0,0 +1,187 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup DevClockXilTtcValFatalIrqInstall + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <bsp.h> +#include <rtems.h> +#include <bsp/fatal.h> +#include <rtems/sysinit.h> + +#include "tr-fatal-clock-xil-ttc-irq-install.h" + +#include <rtems/test.h> + +/** + * @defgroup DevClockXilTtcValFatalIrqInstall \ + * spec:/dev/clock/xil-ttc/val/fatal-irq-install + * + * @ingroup TestsuitesBspsFatalClockXilTtcIrqInstall + * + * @brief Tests a fatal error. + * + * This test case performs the following actions: + * + * - The test action is carried out by the OccupyClockInterrupt() system + * initialization handler. + * + * - Check that the expected fatal source is present. + * + * - Check that the expected fatal code is present. + * + * @{ + */ + +/** + * @brief Test context for spec:/dev/clock/xil-ttc/val/fatal-irq-install test + * case. + */ +typedef struct { + /** + * @brief This member contains a copy of the corresponding + * DevClockXilTtcValFatalIrqInstall_Run() parameter. + */ + rtems_fatal_source source; + + /** + * @brief This member contains a copy of the corresponding + * DevClockXilTtcValFatalIrqInstall_Run() parameter. + */ + rtems_fatal_code code; +} DevClockXilTtcValFatalIrqInstall_Context; + +static DevClockXilTtcValFatalIrqInstall_Context + DevClockXilTtcValFatalIrqInstall_Instance; + +static void ClockInterrupt( void *arg ) +{ + (void) arg; +} + +static rtems_interrupt_entry interrupt_entry = RTEMS_INTERRUPT_ENTRY_INITIALIZER( + ClockInterrupt, + NULL, + "Clock" +); + +static void OccupyClockInterrupt( void ) +{ + (void) rtems_interrupt_entry_install( + XIL_CLOCK_TTC_IRQ, + RTEMS_INTERRUPT_UNIQUE, + &interrupt_entry + ); +} + +RTEMS_SYSINIT_ITEM( + OccupyClockInterrupt, + RTEMS_SYSINIT_DEVICE_DRIVERS, + RTEMS_SYSINIT_ORDER_FIRST +); + +static T_fixture DevClockXilTtcValFatalIrqInstall_Fixture = { + .setup = NULL, + .stop = NULL, + .teardown = NULL, + .scope = NULL, + .initial_context = &DevClockXilTtcValFatalIrqInstall_Instance +}; + +/** + * @brief The test action is carried out by the OccupyClockInterrupt() system + * initialization handler. + */ +static void DevClockXilTtcValFatalIrqInstall_Action_0( + DevClockXilTtcValFatalIrqInstall_Context *ctx +) +{ + /* Nothing to do */ + + /* + * Check that the expected fatal source is present. + */ + T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_BSP ); + + /* + * Check that the expected fatal code is present. + */ + T_step_eq_ulong( + 1, + ctx->code, + XIL_FATAL_TTC_IRQ_INSTALL + ); +} + +void DevClockXilTtcValFatalIrqInstall_Run( + rtems_fatal_source source, + rtems_fatal_code code +) +{ + DevClockXilTtcValFatalIrqInstall_Context *ctx; + + ctx = &DevClockXilTtcValFatalIrqInstall_Instance; + ctx->source = source; + ctx->code = code; + + ctx = T_case_begin( + "DevClockXilTtcValFatalIrqInstall", + &DevClockXilTtcValFatalIrqInstall_Fixture + ); + + T_plan( 2 ); + + DevClockXilTtcValFatalIrqInstall_Action_0( ctx ); + + T_case_end(); +} + +/** @} */ diff --git a/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.h b/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.h new file mode 100644 index 0000000000..74021233a0 --- /dev/null +++ b/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup DevClockXilTtcValFatalIrqInstall + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifndef _TR_FATAL_CLOCK_XIL_TTC_IRQ_INSTALL_H +#define _TR_FATAL_CLOCK_XIL_TTC_IRQ_INSTALL_H + +#include <rtems.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup DevClockXilTtcValFatalIrqInstall + * + * @{ + */ + +/** + * @brief Runs the parameterized test case. + * + * @param source is fatal source. + * + * @param code is fatal code. + */ +void DevClockXilTtcValFatalIrqInstall_Run( + rtems_fatal_source source, + rtems_fatal_code code +); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TR_FATAL_CLOCK_XIL_TTC_IRQ_INSTALL_H */ diff --git a/testsuites/validation/bsps/ts-fatal-clock-xil-ttc-irq-install.c b/testsuites/validation/bsps/ts-fatal-clock-xil-ttc-irq-install.c new file mode 100644 index 0000000000..e5c1062348 --- /dev/null +++ b/testsuites/validation/bsps/ts-fatal-clock-xil-ttc-irq-install.c @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup TestsuitesBspsFatalClockXilTtcIrqInstall + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tr-fatal-clock-xil-ttc-irq-install.h" + +#include <rtems/test.h> + +/** + * @defgroup TestsuitesBspsFatalClockXilTtcIrqInstall \ + * spec:/testsuites/bsps/fatal-clock-xil-ttc-irq-install + * + * @ingroup RTEMSTestSuitesValidation + * + * @brief This validation test suite contains a test case which triggers a + * fatal error during system initialization. + * + * @{ + */ + +const char rtems_test_name[] = "TestsuitesBspsFatalClockXilTtcIrqInstall"; + +#define FATAL_SYSINIT_RUN DevClockXilTtcValFatalIrqInstall_Run + +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#include "ts-fatal-sysinit.h" + +/** @} */ diff --git a/testsuites/validation/tc-dev-clock-xil-ttc.c b/testsuites/validation/tc-dev-clock-xil-ttc.c new file mode 100644 index 0000000000..70f49a4cc6 --- /dev/null +++ b/testsuites/validation/tc-dev-clock-xil-ttc.c @@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup DevClockXilTtcValTickCatchUp + */ + +/* + * Copyright (C) 2024 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <sys/time.h> + +#include <rtems/test.h> + +/** + * @defgroup DevClockXilTtcValTickCatchUp \ + * spec:/dev/clock/xil-ttc/val/tick-catch-up + * + * @ingroup TestsuitesBspsValidationBsp0 + * + * @brief Tests some Xilinx TTC clock driver functions. + * + * This test case performs the following actions: + * + * - Synchronize with the clock tick. Disable interrupts. Busy wait three + * clock tick intervals. Enable interrupts. + * + * - Check that exactly three clock ticks happened once interrupts are + * enabled again. + * + * @{ + */ + +/** + * @brief Synchronize with the clock tick. Disable interrupts. Busy wait + * three clock tick intervals. Enable interrupts. + */ +static void DevClockXilTtcValTickCatchUp_Action_0( void ) +{ + uint32_t ns_per_tick; + uint64_t three_ticks_interval; + rtems_interrupt_level level; + rtems_interval t_0; + rtems_interval t_1; + rtems_interval t_2; + uint64_t m_0; + uint64_t m_1; + + ns_per_tick = rtems_configuration_get_nanoseconds_per_tick(); + three_ticks_interval = ( 7 * (uint64_t) nstosbt( ns_per_tick ) ) / 2; + t_0 = rtems_clock_get_ticks_since_boot(); + + /* Synchronize with clock tick */ + do { + t_1 = rtems_clock_get_ticks_since_boot(); + m_0 = (uint64_t) rtems_clock_get_monotonic_sbintime(); + } while ( t_0 == t_1 ); + + rtems_interrupt_local_disable( level ); + + do { + m_1 = (uint64_t) rtems_clock_get_monotonic_sbintime(); + } while ( m_1 - m_0 <= three_ticks_interval ); + + rtems_interrupt_local_enable( level ); + + /* + * Make sure the clock interrupt was serviced after the interrupt enable. + */ + do { + t_2 = rtems_clock_get_ticks_since_boot(); + } while ( t_1 == t_2 ); + + /* + * Check that exactly three clock ticks happened once interrupts are enabled + * again. + */ + T_step_eq_u32( 0, t_2 - t_1, 3 ); +} + +/** + * @fn void T_case_body_DevClockXilTtcValTickCatchUp( void ) + */ +T_TEST_CASE( DevClockXilTtcValTickCatchUp ) +{ + T_plan( 1 ); + + DevClockXilTtcValTickCatchUp_Action_0(); +} + +/** @} */ diff --git a/testsuites/validation/tc-score-fatal.c b/testsuites/validation/tc-score-fatal.c index dd61a87d80..b0a55f4664 100644 --- a/testsuites/validation/tc-score-fatal.c +++ b/testsuites/validation/tc-score-fatal.c @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH & Co. KG + * Copyright (C) 2021, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -74,14 +74,21 @@ * This test case performs the following actions: * * - Construct a task with a task body which returns. Check that the right - * fatal error occurs. + * fatal error occurred. * - * - Construct a task which performs a thread dispatch with maskable interrupts - * disabled. Check that the right fatal error occurs or no fatal error - * occurs. + * - Construct a task which performs a direct thread dispatch with maskable + * interrupts disabled. Where robust thread dispatching is required, check + * that the right fatal error occurred, otherwise check that no fatal error + * occurred. + * + * - Construct a task which performs an on demand thread dispatch with maskable + * interrupts disabled. Where robust thread dispatching is required, check + * that the right fatal error occurred, otherwise check that no fatal error + * occurred. * * - Construct a task which performs a direct thread dispatch with a thread - * dispatch level not equal to one. Check that the right fatal error occurs. + * dispatch level not equal to one. Check that the right fatal error + * occurred. * * - Create a mutex and construct a task which produces a deadlock which * involves the allocator mutex. @@ -164,10 +171,11 @@ static void FatalBadThreadDispatchEnvironment( { Fatal( source, code, arg ); _ISR_Set_level( 0 ); - _Thread_Dispatch_direct_no_return( _Per_CPU_Get() ); + _Thread_Dispatch_unnest( _Per_CPU_Get() ); + rtems_task_exit(); } -static void ISRDisabledThreadDispatchTask( rtems_task_argument arg ) +static void ISRDisabledDirectThreadDispatchTask( rtems_task_argument arg ) { rtems_interrupt_level level; @@ -177,6 +185,16 @@ static void ISRDisabledThreadDispatchTask( rtems_task_argument arg ) rtems_task_exit(); } +static void ISRDisabledOnDemandThreadDispatchTask( rtems_task_argument arg ) +{ + rtems_interrupt_level level; + + (void) arg; + rtems_interrupt_local_disable( level ); + (void) level; + SetSelfPriority( PRIO_VERY_HIGH ); +} + static void FatalBadThreadDispatchDisableLevel( rtems_fatal_source source, rtems_fatal_code code, @@ -245,7 +263,7 @@ static T_fixture ScoreValFatal_Fixture = { /** * @brief Construct a task with a task body which returns. Check that the - * right fatal error occurs. + * right fatal error occurred. */ static void ScoreValFatal_Action_0( ScoreValFatal_Context *ctx ) { @@ -265,9 +283,10 @@ static void ScoreValFatal_Action_0( ScoreValFatal_Context *ctx ) } /** - * @brief Construct a task which performs a thread dispatch with maskable - * interrupts disabled. Check that the right fatal error occurs or no fatal - * error occurs. + * @brief Construct a task which performs a direct thread dispatch with + * maskable interrupts disabled. Where robust thread dispatching is + * required, check that the right fatal error occurred, otherwise check that + * no fatal error occurred. */ static void ScoreValFatal_Action_1( ScoreValFatal_Context *ctx ) { @@ -278,7 +297,40 @@ static void ScoreValFatal_Action_1( ScoreValFatal_Context *ctx ) SetSelfPriority( PRIO_NORMAL ); counter = ResetFatalInfo( ctx ); id = CreateTask( "BENV", PRIO_HIGH ); - StartTask( id, ISRDisabledThreadDispatchTask, NULL ); + StartTask( id, ISRDisabledDirectThreadDispatchTask, NULL ); + + #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE + if ( rtems_configuration_get_maximum_processors() > 1 ) { + #endif + T_eq_uint( GetFatalCounter( ctx ), counter + 1 ); + T_eq_int( ctx->source, INTERNAL_ERROR_CORE ); + T_eq_ulong( ctx->code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT ); + #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE + } else { + T_eq_uint( GetFatalCounter( ctx ), counter ); + } + #endif + + RestoreRunnerPriority(); + SetFatalHandler( NULL, NULL ); +} + +/** + * @brief Construct a task which performs an on demand thread dispatch with + * maskable interrupts disabled. Where robust thread dispatching is + * required, check that the right fatal error occurred, otherwise check that + * no fatal error occurred. + */ +static void ScoreValFatal_Action_2( ScoreValFatal_Context *ctx ) +{ + rtems_id id; + unsigned int counter; + + SetFatalHandler( FatalBadThreadDispatchEnvironment, ctx ); + SetSelfPriority( PRIO_NORMAL ); + counter = ResetFatalInfo( ctx ); + id = CreateTask( "BENV", PRIO_HIGH ); + StartTask( id, ISRDisabledOnDemandThreadDispatchTask, NULL ); #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE if ( rtems_configuration_get_maximum_processors() > 1 ) { @@ -299,9 +351,9 @@ static void ScoreValFatal_Action_1( ScoreValFatal_Context *ctx ) /** * @brief Construct a task which performs a direct thread dispatch with a * thread dispatch level not equal to one. Check that the right fatal error - * occurs. + * occurred. */ -static void ScoreValFatal_Action_2( ScoreValFatal_Context *ctx ) +static void ScoreValFatal_Action_3( ScoreValFatal_Context *ctx ) { rtems_id id; unsigned int counter; @@ -322,7 +374,7 @@ static void ScoreValFatal_Action_2( ScoreValFatal_Context *ctx ) * @brief Create a mutex and construct a task which produces a deadlock which * involves the allocator mutex. */ -static void ScoreValFatal_Action_3( ScoreValFatal_Context *ctx ) +static void ScoreValFatal_Action_4( ScoreValFatal_Context *ctx ) { rtems_extensions_table extensions; rtems_status_code sc; @@ -374,7 +426,7 @@ static void ScoreValFatal_Action_3( ScoreValFatal_Context *ctx ) * SetFatalHandler() requires an initial extension this validates * CONFIGURE_INITIAL_EXTENSIONS. */ -static void ScoreValFatal_Action_4( ScoreValFatal_Context *ctx ) +static void ScoreValFatal_Action_5( ScoreValFatal_Context *ctx ) { unsigned int counter; @@ -404,6 +456,7 @@ T_TEST_CASE_FIXTURE( ScoreValFatal, &ScoreValFatal_Fixture ) ScoreValFatal_Action_2( ctx ); ScoreValFatal_Action_3( ctx ); ScoreValFatal_Action_4( ctx ); + ScoreValFatal_Action_5( ctx ); } /** @} */ diff --git a/testsuites/validation/tc-score-isr.c b/testsuites/validation/tc-score-isr.c index 9891829a84..b178541e72 100644 --- a/testsuites/validation/tc-score-isr.c +++ b/testsuites/validation/tc-score-isr.c @@ -221,7 +221,7 @@ static void ISRHandler( void *arg ) (void) arg; -#if defined(RTEMS_SMP) +#if defined(RTEMS_SMP) && !(defined(__PPC__) || (__powerpc64__)) Per_CPU_Control *cpu_self; cpu_self = _Per_CPU_Get(); diff --git a/testsuites/validation/tr-mtx-seize-wait.c b/testsuites/validation/tr-mtx-seize-wait.c index fa369e43db..2e2fe9d1ec 100644 --- a/testsuites/validation/tr-mtx-seize-wait.c +++ b/testsuites/validation/tr-mtx-seize-wait.c @@ -710,7 +710,7 @@ static void ScoreMtxReqSeizeWait_Post_Enqueued_Check( case ScoreMtxReqSeizeWait_Post_Enqueued_PriorityInherit: { /* - * The calling thread shall be enqueued in priority order with priorit + * The calling thread shall be enqueued in priority order with priority * inheritance. */ ScoreTqReqEnqueuePriorityInherit_Run( &ctx->tq_ctx->base ); |