Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:52

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup ScoreIsrValIsr
0007  */
0008 
0009 /*
0010  * Copyright (C) 2023 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 /*
0035  * This file is part of the RTEMS quality process and was automatically
0036  * generated.  If you find something that needs to be fixed or
0037  * worded better please post a report or patch to an RTEMS mailing list
0038  * or raise a bug report:
0039  *
0040  * https://www.rtems.org/bugs.html
0041  *
0042  * For information on updating and regenerating please refer to the How-To
0043  * section in the Software Requirements Engineering chapter of the
0044  * RTEMS Software Engineering manual.  The manual is provided as a part of
0045  * a release.  For development sources please refer to the online
0046  * documentation at:
0047  *
0048  * https://docs.rtems.org
0049  */
0050 
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054 
0055 #include <rtems.h>
0056 #include <rtems/sysinit.h>
0057 #include <rtems/score/percpu.h>
0058 #include <rtems/score/thread.h>
0059 
0060 #include "tx-support.h"
0061 
0062 #include <rtems/test.h>
0063 
0064 /**
0065  * @defgroup ScoreIsrValIsr spec:/score/isr/val/isr
0066  *
0067  * @ingroup TestsuitesValidationIntr
0068  *
0069  * @brief Tests general interrupt support behaviour.
0070  *
0071  * This test case performs the following actions:
0072  *
0073  * - Submit an ISR request during system initialization.  Check the stack of
0074  *   the interrupted context while the ISR request is serviced.  Store the
0075  *   result of the check in interrupted_stack_at_multitasking_start_is_valid.
0076  *
0077  *   - Check that stack of the interrupted context was valid when an interrupt
0078  *     was serviced during the multitasking start.
0079  *
0080  * @{
0081  */
0082 
0083 static uintptr_t interrupted_stack_at_multitasking_start;
0084 
0085 static bool interrupted_stack_at_multitasking_start_is_valid;
0086 
0087 #if defined(__aarch64__)
0088 void __real_bsp_interrupt_dispatch( void );
0089 
0090 void __wrap_bsp_interrupt_dispatch( void );
0091 
0092 void __wrap_bsp_interrupt_dispatch( void )
0093 {
0094   if ( interrupted_stack_at_multitasking_start == 0 ) {
0095     uintptr_t             sp;
0096     rtems_interrupt_level level;
0097 
0098     rtems_interrupt_local_disable( level );
0099     __asm__ volatile (
0100       "msr spsel, #1\n"
0101       "mov %0, sp\n"
0102       "msr spsel, #0"
0103       : "=r" ( sp )
0104     );
0105     rtems_interrupt_local_enable( level );
0106 
0107     interrupted_stack_at_multitasking_start = sp;
0108   }
0109 
0110   __real_bsp_interrupt_dispatch();
0111 }
0112 #endif
0113 
0114 #if defined(ARM_MULTILIB_ARCH_V4)
0115 void __real_bsp_interrupt_dispatch( void );
0116 
0117 void __wrap_bsp_interrupt_dispatch( void );
0118 
0119 void __wrap_bsp_interrupt_dispatch( void )
0120 {
0121   register uintptr_t sp __asm__( "9" );
0122 
0123   if ( interrupted_stack_at_multitasking_start == 0 ) {
0124     interrupted_stack_at_multitasking_start = sp;
0125   }
0126 
0127   __real_bsp_interrupt_dispatch();
0128 }
0129 #endif
0130 
0131 #if defined(__microblaze__)
0132 void __real_bsp_interrupt_dispatch( uint32_t source );
0133 
0134 void __wrap_bsp_interrupt_dispatch( uint32_t source );
0135 
0136 void __wrap_bsp_interrupt_dispatch( uint32_t source )
0137 {
0138   register uintptr_t sp __asm__( "1" );
0139 
0140   if ( interrupted_stack_at_multitasking_start == 0 ) {
0141     interrupted_stack_at_multitasking_start = sp;
0142   }
0143 
0144   __real_bsp_interrupt_dispatch( source );
0145 }
0146 #endif
0147 
0148 #if defined(__PPC__) || defined(__powerpc64__)
0149 void __real_bsp_interrupt_dispatch( void );
0150 
0151 void __wrap_bsp_interrupt_dispatch( void );
0152 
0153 void __wrap_bsp_interrupt_dispatch( void )
0154 {
0155   register uintptr_t sp __asm__( "14" );
0156 
0157   if ( interrupted_stack_at_multitasking_start == 0 ) {
0158     interrupted_stack_at_multitasking_start = sp;
0159   }
0160 
0161   __real_bsp_interrupt_dispatch();
0162 }
0163 #endif
0164 
0165 #if defined(__riscv)
0166 void __real__RISCV_Interrupt_dispatch(
0167   uintptr_t        mcause,
0168   Per_CPU_Control *cpu_self
0169 );
0170 
0171 void __wrap__RISCV_Interrupt_dispatch(
0172   uintptr_t        mcause,
0173   Per_CPU_Control *cpu_self
0174 );
0175 
0176 void __wrap__RISCV_Interrupt_dispatch(
0177   uintptr_t        mcause,
0178   Per_CPU_Control *cpu_self
0179 )
0180 {
0181   register uintptr_t sp __asm__( "s1" );
0182 
0183   if ( interrupted_stack_at_multitasking_start == 0 ) {
0184     interrupted_stack_at_multitasking_start = sp;
0185   }
0186 
0187   __real__RISCV_Interrupt_dispatch( mcause, cpu_self );
0188 }
0189 #endif
0190 
0191 #if defined(__sparc__)
0192 void __real__SPARC_Interrupt_dispatch( uint32_t irq );
0193 
0194 static RTEMS_USED void InterruptDispatch( uint32_t irq, uintptr_t sp )
0195 {
0196   if ( interrupted_stack_at_multitasking_start == 0 ) {
0197     interrupted_stack_at_multitasking_start = sp;
0198   }
0199 
0200   __real__SPARC_Interrupt_dispatch( irq );
0201 }
0202 
0203 __asm__ (
0204   "\t.section\t\".text\"\n"
0205   "\t.align\t4\n"
0206   "\t.globl\t__wrap__SPARC_Interrupt_dispatch\n"
0207   "\t.type\t__wrap__SPARC_Interrupt_dispatch, #function\n"
0208   "__wrap__SPARC_Interrupt_dispatch:\n"
0209   "\tmov\t%fp, %o1\n"
0210   "\tor\t%o7, %g0, %g1\n"
0211   "\tcall\tInterruptDispatch, 0\n"
0212   "\t or\t%g1, %g0, %o7\n"
0213   "\t.previous\n"
0214 );
0215 #endif
0216 
0217 static void ISRHandler( void *arg )
0218 {
0219   uintptr_t begin;
0220   uintptr_t end;
0221 
0222   (void) arg;
0223 
0224 #if defined(RTEMS_SMP) && !(defined(__PPC__) || (__powerpc64__))
0225   Per_CPU_Control *cpu_self;
0226 
0227   cpu_self = _Per_CPU_Get();
0228   begin = (uintptr_t) &cpu_self->Interrupt_frame;
0229   end = begin + sizeof( cpu_self->Interrupt_frame );
0230 #else
0231   Thread_Control *executing;
0232 
0233   executing = GetExecuting();
0234   begin = (uintptr_t) executing->Start.Initial_stack.area;
0235   end = begin + executing->Start.Initial_stack.size;
0236 #endif
0237 
0238   interrupted_stack_at_multitasking_start_is_valid =
0239     ( begin <= interrupted_stack_at_multitasking_start &&
0240       interrupted_stack_at_multitasking_start < end );
0241 }
0242 
0243 static CallWithinISRRequest isr_request = {
0244   .handler = ISRHandler
0245 };
0246 
0247 static void SubmitISRRequest( void )
0248 {
0249   CallWithinISRSubmit( &isr_request );
0250 }
0251 
0252 RTEMS_SYSINIT_ITEM(
0253   SubmitISRRequest,
0254   RTEMS_SYSINIT_DEVICE_DRIVERS,
0255   RTEMS_SYSINIT_ORDER_LAST
0256 );
0257 
0258 /**
0259  * @brief Submit an ISR request during system initialization.  Check the stack
0260  *   of the interrupted context while the ISR request is serviced.  Store the
0261  *   result of the check in interrupted_stack_at_multitasking_start_is_valid.
0262  */
0263 static void ScoreIsrValIsr_Action_0( void )
0264 {
0265   /*
0266    * The actions are performed during system initialization and the
0267    * multitasking start.
0268    */
0269 
0270   /*
0271    * Check that stack of the interrupted context was valid when an interrupt
0272    * was serviced during the multitasking start.
0273    */
0274   T_true( interrupted_stack_at_multitasking_start_is_valid );
0275 }
0276 
0277 /**
0278  * @fn void T_case_body_ScoreIsrValIsr( void )
0279  */
0280 T_TEST_CASE( ScoreIsrValIsr )
0281 {
0282   ScoreIsrValIsr_Action_0();
0283 }
0284 
0285 /** @} */