summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2023-09-21 13:56:37 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2023-09-26 09:54:57 +0200
commitc8fc762ea356e862666d6cc86bee29e8351db079 (patch)
treef253d47cbbba54284020224c5a7fb5f5ff90d89b /spec
parent04106a22cee2d36a8ccd66283fd60bb492d46bfb (diff)
spec: Specify interrupt service detail
Diffstat (limited to 'spec')
-rw-r--r--spec/score/isr/req/stack-at-start-multitasking-heir.yml17
-rw-r--r--spec/score/isr/req/stack-at-start-multitasking-per-cpu.yml16
-rw-r--r--spec/score/isr/val/isr.yml186
3 files changed, 219 insertions, 0 deletions
diff --git a/spec/score/isr/req/stack-at-start-multitasking-heir.yml b/spec/score/isr/req/stack-at-start-multitasking-heir.yml
new file mode 100644
index 00000000..521d1fff
--- /dev/null
+++ b/spec/score/isr/req/stack-at-start-multitasking-heir.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2023 embedded brains GmbH & Co. KG
+enabled-by:
+ not: RTEMS_SMP
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While an interrupt is pending, while multitasking is started, while
+ interrupts are enabled, when the interrupt is serviced, the stack of the
+ interrupted context shall be the stack of the heir thread.
+type: requirement
diff --git a/spec/score/isr/req/stack-at-start-multitasking-per-cpu.yml b/spec/score/isr/req/stack-at-start-multitasking-per-cpu.yml
new file mode 100644
index 00000000..76595289
--- /dev/null
+++ b/spec/score/isr/req/stack-at-start-multitasking-per-cpu.yml
@@ -0,0 +1,16 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2023 embedded brains GmbH & Co. KG
+enabled-by: RTEMS_SMP
+links:
+- role: requirement-refinement
+ uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+ While an interrupt is pending, while multitasking is started, while
+ interrupts are enabled, when the interrupt is serviced, the stack of the
+ interrupted context shall be the temporary stack of the processor.
+type: requirement
diff --git a/spec/score/isr/val/isr.yml b/spec/score/isr/val/isr.yml
new file mode 100644
index 00000000..41046a26
--- /dev/null
+++ b/spec/score/isr/val/isr.yml
@@ -0,0 +1,186 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2023 embedded brains GmbH & Co. KG
+enabled-by: true
+links: []
+test-actions:
+- action-brief: |
+ Submit an ISR request during system initialization. Check the stack of the
+ interrupted context while the ISR request is serviced. Store the result of
+ the check in interrupted_stack_at_multitasking_start_is_valid.
+ action-code: |
+ /*
+ * The actions are performed during system initialization and the
+ * multitasking start.
+ */
+ checks:
+ - brief: |
+ Check that stack of the interrupted context was valid when an interrupt
+ was serviced during the multitasking start.
+ code: |
+ T_true( interrupted_stack_at_multitasking_start_is_valid );
+ links:
+ - role: validation
+ uid: ../req/stack-at-start-multitasking-heir
+ - role: validation
+ uid: ../req/stack-at-start-multitasking-per-cpu
+ links: []
+test-brief: |
+ Tests general interrupt support behaviour.
+test-context: []
+test-context-support: null
+test-description: null
+test-header: null
+test-includes:
+- rtems.h
+- rtems/sysinit.h
+- rtems/score/thread.h
+- rtems/score/percpu.h
+test-local-includes:
+- tx-support.h
+test-setup: null
+test-stop: null
+test-support: |
+ static uintptr_t interrupted_stack_at_multitasking_start;
+
+ static bool interrupted_stack_at_multitasking_start_is_valid;
+
+ #if defined(__aarch64__)
+ void __real_bsp_interrupt_dispatch( void );
+
+ void __wrap_bsp_interrupt_dispatch( void );
+
+ void __wrap_bsp_interrupt_dispatch( void )
+ {
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ uintptr_t sp;
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable( level );
+ __asm__ volatile (
+ "msr spsel, #1\n"
+ "mov %0, sp\n"
+ "msr spsel, #0"
+ : "=r" ( sp )
+ );
+ rtems_interrupt_local_enable( level );
+
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real_bsp_interrupt_dispatch();
+ }
+ #endif
+
+ #if defined(ARM_MULTILIB_ARCH_V4)
+ void __real_bsp_interrupt_dispatch( void );
+
+ void __wrap_bsp_interrupt_dispatch( void );
+
+ void __wrap_bsp_interrupt_dispatch( void )
+ {
+ register uintptr_t sp __asm__( "9" );
+
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real_bsp_interrupt_dispatch();
+ }
+ #endif
+
+ #if defined(__riscv)
+ void __real__RISCV_Interrupt_dispatch(
+ uintptr_t mcause,
+ Per_CPU_Control *cpu_self
+ );
+
+ void __wrap__RISCV_Interrupt_dispatch(
+ uintptr_t mcause,
+ Per_CPU_Control *cpu_self
+ );
+
+ void __wrap__RISCV_Interrupt_dispatch(
+ uintptr_t mcause,
+ Per_CPU_Control *cpu_self
+ )
+ {
+ register uintptr_t sp __asm__( "s1" );
+
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real__RISCV_Interrupt_dispatch( mcause, cpu_self );
+ }
+ #endif
+
+ #if defined(__sparc__)
+ void __real__SPARC_Interrupt_dispatch( uint32_t irq );
+
+ static RTEMS_USED void InterruptDispatch( uint32_t irq, uintptr_t sp )
+ {
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real__SPARC_Interrupt_dispatch( irq );
+ }
+
+ __asm__ (
+ "\t.section\t\".text\"\n"
+ "\t.align\t4\n"
+ "\t.globl\t__wrap__SPARC_Interrupt_dispatch\n"
+ "\t.type\t__wrap__SPARC_Interrupt_dispatch, #function\n"
+ "__wrap__SPARC_Interrupt_dispatch:\n"
+ "\tmov\t%fp, %o1\n"
+ "\tor\t%o7, %g0, %g1\n"
+ "\tcall\tInterruptDispatch, 0\n"
+ "\t or\t%g1, %g0, %o7\n"
+ "\t.previous\n"
+ );
+ #endif
+
+ static void ISRHandler( void *arg )
+ {
+ uintptr_t begin;
+ uintptr_t end;
+
+ (void) arg;
+
+ #if defined(RTEMS_SMP)
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Per_CPU_Get();
+ begin = (uintptr_t) &cpu_self->Interrupt_frame;
+ end = begin + sizeof( cpu_self->Interrupt_frame );
+ #else
+ Thread_Control *executing;
+
+ executing = GetExecuting();
+ begin = (uintptr_t) executing->Start.Initial_stack.area;
+ end = begin + executing->Start.Initial_stack.size;
+ #endif
+
+ interrupted_stack_at_multitasking_start_is_valid =
+ ( begin <= interrupted_stack_at_multitasking_start &&
+ interrupted_stack_at_multitasking_start < end );
+ }
+
+ static CallWithinISRRequest isr_request = {
+ .handler = ISRHandler
+ };
+
+ static void SubmitISRRequest( void )
+ {
+ CallWithinISRSubmit( &isr_request );
+ }
+
+ RTEMS_SYSINIT_ITEM(
+ SubmitISRRequest,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_LAST
+ );
+test-target: testsuites/validation/tc-score-isr.c
+test-teardown: null
+type: test-case