summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2023-10-25 16:27:11 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2023-12-19 08:26:46 +0100
commit029874cbd1c20c9d01eb6c7ffcb5dab52c9fd530 (patch)
treed9fe782af927e9f40e81f2aaad28e6b94f64c86c
parenta97816a798357eed74ec1eb10106f81aee1a4e51 (diff)
testsuites/isvv: New
Import ISVV testsuite from CSW-RTEMSISVV-2022-TSP-05453_1-rtems-smp-isvv-iva-test-procedures.zip with an SHA256 hash of fdbe9ee336fd29da42ea7a0b8de558a369e7b3e0a2009b9a5c500f00fa960b88
-rw-r--r--spec/build/testsuites/grp.yml4
-rw-r--r--spec/build/testsuites/isvv/00_mrsp_omip_uni.yml22
-rw-r--r--spec/build/testsuites/isvv/00_uni_test_reference.yml22
-rw-r--r--spec/build/testsuites/isvv/01_basic_smp_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/02_core_affinity_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/03_semaphores_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/04_messages_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/05_priorities_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/06_rate_monotonic_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/07_timer_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/10_barrier_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/10_barrier_multi_timeout.yml22
-rw-r--r--spec/build/testsuites/isvv/11_mrsp_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/11_mrsp_uni.yml22
-rw-r--r--spec/build/testsuites/isvv/12_omip_multi.yml22
-rw-r--r--spec/build/testsuites/isvv/12_omip_uni.yml22
-rw-r--r--spec/build/testsuites/isvv/13_priority_inheritance_disabled.yml22
-rw-r--r--spec/build/testsuites/isvv/13_priority_inheritance_enabled.yml22
-rw-r--r--spec/build/testsuites/isvv/14_immediate_ceiling_disabled.yml22
-rw-r--r--spec/build/testsuites/isvv/14_immediate_ceiling_enabled.yml22
-rw-r--r--spec/build/testsuites/isvv/15_clock_manager_undefined_behaviour.yml22
-rw-r--r--spec/build/testsuites/isvv/16_task_manager_undefined_behaviour.yml22
-rw-r--r--spec/build/testsuites/isvv/17_barrier_manager_undefined_behaviour.yml22
-rw-r--r--spec/build/testsuites/isvv/18_event_manager_undefined_behaviour.yml22
-rw-r--r--spec/build/testsuites/isvv/19_message_manager_undefined_behaviour.yml22
-rw-r--r--spec/build/testsuites/isvv/20_partition_manager_undefined_behaviour.yml22
-rw-r--r--spec/build/testsuites/isvv/21_semaphore_manager_undefined_behaviour.yml22
-rw-r--r--spec/build/testsuites/isvv/22_base_defs_undefined_behaviour.yml22
-rw-r--r--spec/build/testsuites/isvv/23_10_uni_cache_l2_enabled.yml26
-rw-r--r--spec/build/testsuites/isvv/23_11_multi_cache_l2_enabled.yml26
-rw-r--r--spec/build/testsuites/isvv/23_12_multi_cache_l2_disable.yml26
-rw-r--r--spec/build/testsuites/isvv/23_1_uni_cache_way_locking_disabled.yml27
-rw-r--r--spec/build/testsuites/isvv/23_2_multi_cache_way_locking_disabled.yml26
-rw-r--r--spec/build/testsuites/isvv/23_3_multi_cache_way_locking_enabled.yml26
-rw-r--r--spec/build/testsuites/isvv/23_4_uni_cache_split_transactions_disabled.yml26
-rw-r--r--spec/build/testsuites/isvv/23_5_multi_cache_split_transactions_disabled.yml26
-rw-r--r--spec/build/testsuites/isvv/23_6_multi_cache_split_transactions_enabled.yml26
-rw-r--r--spec/build/testsuites/isvv/23_7_uni_cache_repl_policy_l2_lru.yml26
-rw-r--r--spec/build/testsuites/isvv/23_8_multi_cache_repl_policy_l2_lru.yml26
-rw-r--r--spec/build/testsuites/isvv/23_9_multi_cache_repl_policy_l2_random.yml26
-rw-r--r--spec/build/testsuites/isvv/grp.yml97
-rw-r--r--spec/build/testsuites/isvv/optgr712rc.yml17
-rw-r--r--spec/build/testsuites/isvv/optgr740.yml17
-rw-r--r--spec/build/testsuites/optisvv.yml16
-rw-r--r--testsuites/isvv/00_uni_test_reference/basic_smp_uni.c114
-rw-r--r--testsuites/isvv/00_uni_test_reference/mrsp_omip_uni.c408
-rw-r--r--testsuites/isvv/01_basic_smp_multi/basic_smp_multi.c206
-rw-r--r--testsuites/isvv/02_core_affinity_multi/core_affinity_multi.c211
-rw-r--r--testsuites/isvv/03_semaphores_multi/semaphores_multi.c244
-rw-r--r--testsuites/isvv/04_messages_multi/messages_multi.c273
-rw-r--r--testsuites/isvv/05_priorities_multi/priorities_multi.c283
-rw-r--r--testsuites/isvv/06_rate_monotonic_multi/rate_monotonic_multi.c292
-rw-r--r--testsuites/isvv/07_timer_multi/timer_multi.c291
-rw-r--r--testsuites/isvv/09_timer_server_multi/timer_server_multi.c269
-rw-r--r--testsuites/isvv/10_barrier_multi/barrier_multi.c302
-rw-r--r--testsuites/isvv/10_barrier_multi/barrier_multi_timeout.c337
-rw-r--r--testsuites/isvv/11_MrsP_multi/mrsp_multi.c436
-rw-r--r--testsuites/isvv/12_OMIP_multi/omip_multi.c436
-rw-r--r--testsuites/isvv/13_priority_inheritance/priority_inheritance.c449
-rw-r--r--testsuites/isvv/14_immediate_ceiling_protocol/immediate_ceiling.c468
-rw-r--r--testsuites/isvv/15_clock_manager_undefined_behaviour/clock_manager_undefined_behaviour.c579
-rw-r--r--testsuites/isvv/16_task_manager_undefined_behaviour/task_manager_undefined_behaviour.c468
-rw-r--r--testsuites/isvv/17_barrier_manager_undefined_behaviour/barrier_manager_undefined_behaviour.c445
-rw-r--r--testsuites/isvv/18_event_manager_undefined_behaviour/event_manager_undefined_behaviour.c423
-rw-r--r--testsuites/isvv/19_message_manager_undefined_behaviour/message_manager_undefined_behaviour.c346
-rw-r--r--testsuites/isvv/20_partition_manager_undefined_behaviour/partition_manager_undefined_behaviour.c359
-rw-r--r--testsuites/isvv/21_semaphore_manager_undefined_behaviour/semaphore_manager_undefined_behaviour.c661
-rw-r--r--testsuites/isvv/22_base_defs_undefined_behaviour/base_defs_undefined_behaviour.c338
-rw-r--r--testsuites/isvv/23.10_uni_cache_l2_enabled/uni_cache_l2_enabled.c366
-rw-r--r--testsuites/isvv/23.11_multi_cache_l2_enabled/multi_cache_l2_enabled.c489
-rw-r--r--testsuites/isvv/23.12_multi_cache_l2_disabled/multi_cache_l2_disabled.c491
-rw-r--r--testsuites/isvv/23.1_uni_cache_way_locking_disabled/uni_cache_way_locking_disabled.c538
-rw-r--r--testsuites/isvv/23.2_multi_cache_way_locking_disabled/multi_cache_way_locking_disabled.c699
-rw-r--r--testsuites/isvv/23.3_multi_cache_way_locking_enabled/multi_cache_way_locking_enabled.c713
-rw-r--r--testsuites/isvv/23.4_uni_cache_split_transactions_disabled/uni_cache_split_transactions_disabled.c370
-rw-r--r--testsuites/isvv/23.5_multi_cache_split_transactions_disabled/multi_cache_split_transactions_disabled.c491
-rw-r--r--testsuites/isvv/23.6_multi_cache_split_transactions_enabled/multi_cache_split_transactions_enabled.c495
-rw-r--r--testsuites/isvv/23.7_uni_cache_repl_policy_l2_lru/uni_cache_repl_policy_l2_lru.c535
-rw-r--r--testsuites/isvv/23.8_multi_cache_repl_policy_l2_lru/multi_cache_repl_policy_l2_lru.c722
-rw-r--r--testsuites/isvv/23.9_multi_cache_repl_policy_l2_random/multi_cache_repl_policy_l2_random.c725
-rw-r--r--testsuites/isvv/shared/isvv_rtems_aux.c622
-rw-r--r--testsuites/isvv/shared/isvv_rtems_aux.h176
-rw-r--r--testsuites/isvv/shared/low_level_utils.c464
-rw-r--r--testsuites/isvv/shared/low_level_utils.h126
-rw-r--r--testsuites/isvv/shared/trig_tables.h2091
-rw-r--r--testsuites/isvv/shared/utils.c397
-rw-r--r--testsuites/isvv/shared/utils.h111
87 files changed, 20317 insertions, 0 deletions
diff --git a/spec/build/testsuites/grp.yml b/spec/build/testsuites/grp.yml
index a1fd9c4b84..70ed96f06a 100644
--- a/spec/build/testsuites/grp.yml
+++ b/spec/build/testsuites/grp.yml
@@ -23,6 +23,8 @@ links:
- role: build-dependency
uid: optfs
- role: build-dependency
+ uid: optisvv
+- role: build-dependency
uid: optlib
- role: build-dependency
uid: optlibdl
@@ -55,6 +57,8 @@ links:
- role: build-dependency
uid: fstests/grp
- role: build-dependency
+ uid: isvv/grp
+- role: build-dependency
uid: libtests/grp
- role: build-dependency
uid: membench/grp
diff --git a/spec/build/testsuites/isvv/00_mrsp_omip_uni.yml b/spec/build/testsuites/isvv/00_mrsp_omip_uni.yml
new file mode 100644
index 0000000000..eeba769f41
--- /dev/null
+++ b/spec/build/testsuites/isvv/00_mrsp_omip_uni.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/00_uni_test_reference/mrsp_omip_uni.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/mrsp_omip_uni_reference.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/00_uni_test_reference.yml b/spec/build/testsuites/isvv/00_uni_test_reference.yml
new file mode 100644
index 0000000000..b0c4f8b543
--- /dev/null
+++ b/spec/build/testsuites/isvv/00_uni_test_reference.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/00_uni_test_reference/basic_smp_uni.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/basic_smp_uni.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/01_basic_smp_multi.yml b/spec/build/testsuites/isvv/01_basic_smp_multi.yml
new file mode 100644
index 0000000000..a4f3fb0063
--- /dev/null
+++ b/spec/build/testsuites/isvv/01_basic_smp_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+ - testsuites/isvv/01_basic_smp_multi/basic_smp_multi.c
+ - testsuites/isvv/shared/utils.c
+ - testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/basic_smp_multi.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/02_core_affinity_multi.yml b/spec/build/testsuites/isvv/02_core_affinity_multi.yml
new file mode 100644
index 0000000000..18d5991f7c
--- /dev/null
+++ b/spec/build/testsuites/isvv/02_core_affinity_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+ - testsuites/isvv/02_core_affinity_multi/core_affinity_multi.c
+ - testsuites/isvv/shared/utils.c
+ - testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/core_affinity_multi.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/03_semaphores_multi.yml b/spec/build/testsuites/isvv/03_semaphores_multi.yml
new file mode 100644
index 0000000000..eb63c41999
--- /dev/null
+++ b/spec/build/testsuites/isvv/03_semaphores_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/03_semaphores_multi/semaphores_multi.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/semaphores_multi.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/04_messages_multi.yml b/spec/build/testsuites/isvv/04_messages_multi.yml
new file mode 100644
index 0000000000..291304940b
--- /dev/null
+++ b/spec/build/testsuites/isvv/04_messages_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/04_messages_multi/messages_multi.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/messages_multi.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/05_priorities_multi.yml b/spec/build/testsuites/isvv/05_priorities_multi.yml
new file mode 100644
index 0000000000..97fcbca094
--- /dev/null
+++ b/spec/build/testsuites/isvv/05_priorities_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/05_priorities_multi/priorities_multi.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/priorities_multi.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/06_rate_monotonic_multi.yml b/spec/build/testsuites/isvv/06_rate_monotonic_multi.yml
new file mode 100644
index 0000000000..97bcd0f2d6
--- /dev/null
+++ b/spec/build/testsuites/isvv/06_rate_monotonic_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/06_rate_monotonic_multi/rate_monotonic_multi.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/rate_monotonic_multi.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/07_timer_multi.yml b/spec/build/testsuites/isvv/07_timer_multi.yml
new file mode 100644
index 0000000000..dfbee13909
--- /dev/null
+++ b/spec/build/testsuites/isvv/07_timer_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/07_timer_multi/timer_multi.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/timer_multi.exe
+type: build
+use-after:
+- isvv
+use-before: [] \ No newline at end of file
diff --git a/spec/build/testsuites/isvv/10_barrier_multi.yml b/spec/build/testsuites/isvv/10_barrier_multi.yml
new file mode 100644
index 0000000000..22025f515a
--- /dev/null
+++ b/spec/build/testsuites/isvv/10_barrier_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/10_barrier_multi/barrier_multi.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/barrier_multi.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/10_barrier_multi_timeout.yml b/spec/build/testsuites/isvv/10_barrier_multi_timeout.yml
new file mode 100644
index 0000000000..aefbabeda7
--- /dev/null
+++ b/spec/build/testsuites/isvv/10_barrier_multi_timeout.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/10_barrier_multi/barrier_multi_timeout.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/barrier_multi_timeout.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/11_mrsp_multi.yml b/spec/build/testsuites/isvv/11_mrsp_multi.yml
new file mode 100644
index 0000000000..45b3373f0a
--- /dev/null
+++ b/spec/build/testsuites/isvv/11_mrsp_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/11_MrsP_multi/mrsp_multi.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/mrsp_multi.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/11_mrsp_uni.yml b/spec/build/testsuites/isvv/11_mrsp_uni.yml
new file mode 100644
index 0000000000..ccbe57400b
--- /dev/null
+++ b/spec/build/testsuites/isvv/11_mrsp_uni.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/11_MrsP_uni/mrsp_uni.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/mrsp_uni.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/12_omip_multi.yml b/spec/build/testsuites/isvv/12_omip_multi.yml
new file mode 100644
index 0000000000..bd18511ecc
--- /dev/null
+++ b/spec/build/testsuites/isvv/12_omip_multi.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/12_OMIP_multi/omip_multi.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/omip_multi.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/12_omip_uni.yml b/spec/build/testsuites/isvv/12_omip_uni.yml
new file mode 100644
index 0000000000..a4e12cc65f
--- /dev/null
+++ b/spec/build/testsuites/isvv/12_omip_uni.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/12_OMIP_uni/omip_uni.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/omip_uni.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/13_priority_inheritance_disabled.yml b/spec/build/testsuites/isvv/13_priority_inheritance_disabled.yml
new file mode 100644
index 0000000000..d1d3767791
--- /dev/null
+++ b/spec/build/testsuites/isvv/13_priority_inheritance_disabled.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/13_priority_inheritance/priority_inheritance.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/priority_inheritance_disabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/13_priority_inheritance_enabled.yml b/spec/build/testsuites/isvv/13_priority_inheritance_enabled.yml
new file mode 100644
index 0000000000..dd5a745d3e
--- /dev/null
+++ b/spec/build/testsuites/isvv/13_priority_inheritance_enabled.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [-DPRIO_INHERIT]
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/13_priority_inheritance/priority_inheritance.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/priority_inheritance_enabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/14_immediate_ceiling_disabled.yml b/spec/build/testsuites/isvv/14_immediate_ceiling_disabled.yml
new file mode 100644
index 0000000000..9c8f392e72
--- /dev/null
+++ b/spec/build/testsuites/isvv/14_immediate_ceiling_disabled.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/14_immediate_ceiling_protocol/immediate_ceiling.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/immediate_ceiling_disabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/14_immediate_ceiling_enabled.yml b/spec/build/testsuites/isvv/14_immediate_ceiling_enabled.yml
new file mode 100644
index 0000000000..26ee6a9dab
--- /dev/null
+++ b/spec/build/testsuites/isvv/14_immediate_ceiling_enabled.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [-DPRIO_CEILING]
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/14_immediate_ceiling_protocol/immediate_ceiling.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/immediate_ceiling_enabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/15_clock_manager_undefined_behaviour.yml b/spec/build/testsuites/isvv/15_clock_manager_undefined_behaviour.yml
new file mode 100644
index 0000000000..fd6d1fe081
--- /dev/null
+++ b/spec/build/testsuites/isvv/15_clock_manager_undefined_behaviour.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/15_clock_manager_undefined_behaviour/clock_manager_undefined_behaviour.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/clock_manager_undefined_behaviour.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/16_task_manager_undefined_behaviour.yml b/spec/build/testsuites/isvv/16_task_manager_undefined_behaviour.yml
new file mode 100644
index 0000000000..bc3b0b5ae5
--- /dev/null
+++ b/spec/build/testsuites/isvv/16_task_manager_undefined_behaviour.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/16_task_manager_undefined_behaviour/task_manager_undefined_behaviour.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/task_manager_undefined_behaviour.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/17_barrier_manager_undefined_behaviour.yml b/spec/build/testsuites/isvv/17_barrier_manager_undefined_behaviour.yml
new file mode 100644
index 0000000000..a2274347bf
--- /dev/null
+++ b/spec/build/testsuites/isvv/17_barrier_manager_undefined_behaviour.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/17_barrier_manager_undefined_behaviour/barrier_manager_undefined_behaviour.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/barrier_manager_undefined_behaviour.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/18_event_manager_undefined_behaviour.yml b/spec/build/testsuites/isvv/18_event_manager_undefined_behaviour.yml
new file mode 100644
index 0000000000..43b8ac8f63
--- /dev/null
+++ b/spec/build/testsuites/isvv/18_event_manager_undefined_behaviour.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/18_event_manager_undefined_behaviour/event_manager_undefined_behaviour.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/event_manager_undefined_behaviour.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/19_message_manager_undefined_behaviour.yml b/spec/build/testsuites/isvv/19_message_manager_undefined_behaviour.yml
new file mode 100644
index 0000000000..db2d5fcd89
--- /dev/null
+++ b/spec/build/testsuites/isvv/19_message_manager_undefined_behaviour.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/19_message_manager_undefined_behaviour/message_manager_undefined_behaviour.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/message_manager_undefined_behaviour.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/20_partition_manager_undefined_behaviour.yml b/spec/build/testsuites/isvv/20_partition_manager_undefined_behaviour.yml
new file mode 100644
index 0000000000..d4ffe1c389
--- /dev/null
+++ b/spec/build/testsuites/isvv/20_partition_manager_undefined_behaviour.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/20_partition_manager_undefined_behaviour/partition_manager_undefined_behaviour.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/partition_manager_undefined_behaviour.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/21_semaphore_manager_undefined_behaviour.yml b/spec/build/testsuites/isvv/21_semaphore_manager_undefined_behaviour.yml
new file mode 100644
index 0000000000..a8b40bc43f
--- /dev/null
+++ b/spec/build/testsuites/isvv/21_semaphore_manager_undefined_behaviour.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/21_semaphore_manager_undefined_behaviour/semaphore_manager_undefined_behaviour.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/semaphore_manager_undefined_behaviour.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/22_base_defs_undefined_behaviour.yml b/spec/build/testsuites/isvv/22_base_defs_undefined_behaviour.yml
new file mode 100644
index 0000000000..198fe5512e
--- /dev/null
+++ b/spec/build/testsuites/isvv/22_base_defs_undefined_behaviour.yml
@@ -0,0 +1,22 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: RTEMS_SMP
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/22_base_defs_undefined_behaviour/base_defs_undefined_behaviour.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+stlib: []
+target: testsuites/isvv/base_defs_undefined_behaviour.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_10_uni_cache_l2_enabled.yml b/spec/build/testsuites/isvv/23_10_uni_cache_l2_enabled.yml
new file mode 100644
index 0000000000..dc4a54bb09
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_10_uni_cache_l2_enabled.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.10_uni_cache_l2_enabled/uni_cache_l2_enabled.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/uni_cache_l2_enabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_11_multi_cache_l2_enabled.yml b/spec/build/testsuites/isvv/23_11_multi_cache_l2_enabled.yml
new file mode 100644
index 0000000000..1c411f8e32
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_11_multi_cache_l2_enabled.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.11_multi_cache_l2_enabled/multi_cache_l2_enabled.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/multi_cache_l2_enabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_12_multi_cache_l2_disable.yml b/spec/build/testsuites/isvv/23_12_multi_cache_l2_disable.yml
new file mode 100644
index 0000000000..052e7778c2
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_12_multi_cache_l2_disable.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.12_multi_cache_l2_disabled/multi_cache_l2_disabled.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/multi_cache_l2_disabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_1_uni_cache_way_locking_disabled.yml b/spec/build/testsuites/isvv/23_1_uni_cache_way_locking_disabled.yml
new file mode 100644
index 0000000000..737b085676
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_1_uni_cache_way_locking_disabled.yml
@@ -0,0 +1,27 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.1_uni_cache_way_locking_disabled/uni_cache_way_locking_disabled.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/uni_cache_way_locking_disabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_2_multi_cache_way_locking_disabled.yml b/spec/build/testsuites/isvv/23_2_multi_cache_way_locking_disabled.yml
new file mode 100644
index 0000000000..0f900dc7b0
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_2_multi_cache_way_locking_disabled.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.2_multi_cache_way_locking_disabled/multi_cache_way_locking_disabled.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/multi_cache_way_locking_disabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_3_multi_cache_way_locking_enabled.yml b/spec/build/testsuites/isvv/23_3_multi_cache_way_locking_enabled.yml
new file mode 100644
index 0000000000..14c75f6332
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_3_multi_cache_way_locking_enabled.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.3_multi_cache_way_locking_enabled/multi_cache_way_locking_enabled.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/multi_cache_way_locking_enabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_4_uni_cache_split_transactions_disabled.yml b/spec/build/testsuites/isvv/23_4_uni_cache_split_transactions_disabled.yml
new file mode 100644
index 0000000000..100438beea
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_4_uni_cache_split_transactions_disabled.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.4_uni_cache_split_transactions_disabled/uni_cache_split_transactions_disabled.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/uni_cache_split_transactions_disabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_5_multi_cache_split_transactions_disabled.yml b/spec/build/testsuites/isvv/23_5_multi_cache_split_transactions_disabled.yml
new file mode 100644
index 0000000000..14bd40b58c
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_5_multi_cache_split_transactions_disabled.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.5_multi_cache_split_transactions_disabled/multi_cache_split_transactions_disabled.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/multi_cache_split_transactions_disabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_6_multi_cache_split_transactions_enabled.yml b/spec/build/testsuites/isvv/23_6_multi_cache_split_transactions_enabled.yml
new file mode 100644
index 0000000000..3401998eeb
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_6_multi_cache_split_transactions_enabled.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.6_multi_cache_split_transactions_enabled/multi_cache_split_transactions_enabled.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/multi_cache_split_transactions_enabled.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_7_uni_cache_repl_policy_l2_lru.yml b/spec/build/testsuites/isvv/23_7_uni_cache_repl_policy_l2_lru.yml
new file mode 100644
index 0000000000..df49956ed8
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_7_uni_cache_repl_policy_l2_lru.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.7_uni_cache_repl_policy_l2_lru/uni_cache_repl_policy_l2_lru.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/uni_cache_repl_policy_l2_lru.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_8_multi_cache_repl_policy_l2_lru.yml b/spec/build/testsuites/isvv/23_8_multi_cache_repl_policy_l2_lru.yml
new file mode 100644
index 0000000000..a07f09e4e5
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_8_multi_cache_repl_policy_l2_lru.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.8_multi_cache_repl_policy_l2_lru/multi_cache_repl_policy_l2_lru.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/multi_cache_repl_policy_l2_lru.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/23_9_multi_cache_repl_policy_l2_random.yml b/spec/build/testsuites/isvv/23_9_multi_cache_repl_policy_l2_random.yml
new file mode 100644
index 0000000000..f2b8ec2890
--- /dev/null
+++ b/spec/build/testsuites/isvv/23_9_multi_cache_repl_policy_l2_random.yml
@@ -0,0 +1,26 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: test-program
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: [ -DGR740_ESA_BOARD ]
+cxxflags: []
+enabled-by:
+ and:
+ - RTEMS_SMP
+ - not: sparc/gr712rc
+features: c cprogram
+includes: []
+ldflags: []
+links: []
+source:
+- testsuites/isvv/23.9_multi_cache_repl_policy_l2_random/multi_cache_repl_policy_l2_random.c
+- testsuites/isvv/shared/utils.c
+- testsuites/isvv/shared/isvv_rtems_aux.c
+- testsuites/isvv/shared/low_level_utils.c
+stlib: []
+target: testsuites/isvv/multi_cache_repl_policy_l2_random.exe
+type: build
+use-after:
+- isvv
+use-before: []
diff --git a/spec/build/testsuites/isvv/grp.yml b/spec/build/testsuites/isvv/grp.yml
new file mode 100644
index 0000000000..318626487f
--- /dev/null
+++ b/spec/build/testsuites/isvv/grp.yml
@@ -0,0 +1,97 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+build-type: group
+cflags: []
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+cppflags: []
+cxxflags: []
+enabled-by: BUILD_ISVVTESTS
+includes:
+- ${BSP_INCLUDES}
+install: []
+ldflags: []
+links:
+- role: build-dependency
+ uid: optgr712rc
+- role: build-dependency
+ uid: optgr740
+- role: build-dependency
+ uid: 00_uni_test_reference
+- role: build-dependency
+ uid: 00_mrsp_omip_uni
+- role: build-dependency
+ uid: 01_basic_smp_multi
+- role: build-dependency
+ uid: 02_core_affinity_multi
+- role: build-dependency
+ uid: 03_semaphores_multi
+- role: build-dependency
+ uid: 04_messages_multi
+- role: build-dependency
+ uid: 05_priorities_multi
+- role: build-dependency
+ uid: 06_rate_monotonic_multi
+- role: build-dependency
+ uid: 07_timer_multi
+- role: build-dependency
+ uid: 10_barrier_multi
+- role: build-dependency
+ uid: 10_barrier_multi_timeout
+- role: build-dependency
+ uid: 11_mrsp_multi
+- role: build-dependency
+ uid: 12_omip_multi
+- role: build-dependency
+ uid: 13_priority_inheritance_enabled
+- role: build-dependency
+ uid: 13_priority_inheritance_disabled
+- role: build-dependency
+ uid: 14_immediate_ceiling_enabled
+- role: build-dependency
+ uid: 14_immediate_ceiling_disabled
+- role: build-dependency
+ uid: 15_clock_manager_undefined_behaviour
+- role: build-dependency
+ uid: 16_task_manager_undefined_behaviour
+- role: build-dependency
+ uid: 17_barrier_manager_undefined_behaviour
+- role: build-dependency
+ uid: 18_event_manager_undefined_behaviour
+- role: build-dependency
+ uid: 19_message_manager_undefined_behaviour
+- role: build-dependency
+ uid: 20_partition_manager_undefined_behaviour
+- role: build-dependency
+ uid: 21_semaphore_manager_undefined_behaviour
+- role: build-dependency
+ uid: 22_base_defs_undefined_behaviour
+- role: build-dependency
+ uid: 23_1_uni_cache_way_locking_disabled
+- role: build-dependency
+ uid: 23_2_multi_cache_way_locking_disabled
+- role: build-dependency
+ uid: 23_3_multi_cache_way_locking_enabled
+- role: build-dependency
+ uid: 23_4_uni_cache_split_transactions_disabled
+- role: build-dependency
+ uid: 23_5_multi_cache_split_transactions_disabled
+- role: build-dependency
+ uid: 23_6_multi_cache_split_transactions_enabled
+- role: build-dependency
+ uid: 23_7_uni_cache_repl_policy_l2_lru
+- role: build-dependency
+ uid: 23_8_multi_cache_repl_policy_l2_lru
+- role: build-dependency
+ uid: 23_9_multi_cache_repl_policy_l2_random
+- role: build-dependency
+ uid: 23_10_uni_cache_l2_enabled
+- role: build-dependency
+ uid: 23_11_multi_cache_l2_enabled
+- role: build-dependency
+ uid: 23_12_multi_cache_l2_disable
+type: build
+use-after:
+- rtemstest
+- rtemscpu
+- rtemsbsp
+use-before: []
diff --git a/spec/build/testsuites/isvv/optgr712rc.yml b/spec/build/testsuites/isvv/optgr712rc.yml
new file mode 100644
index 0000000000..84751229f0
--- /dev/null
+++ b/spec/build/testsuites/isvv/optgr712rc.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+actions:
+- set-value: -Dgr712rc=1
+- env-assign: null
+- env-append: CFLAGS
+build-type: option
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+default:
+- enabled-by: true
+ value: null
+description: |
+ Enable flags to configure ISVV tests for gr712rc
+enabled-by: sparc/gr712rc
+links: []
+name: ISVV_FLAGS
+type: build
diff --git a/spec/build/testsuites/isvv/optgr740.yml b/spec/build/testsuites/isvv/optgr740.yml
new file mode 100644
index 0000000000..1ff260d05e
--- /dev/null
+++ b/spec/build/testsuites/isvv/optgr740.yml
@@ -0,0 +1,17 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+actions:
+- set-value: -Dgr740=1
+- env-assign: null
+- env-append: CFLAGS
+build-type: option
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+default:
+- enabled-by: true
+ value: null
+description: |
+ Enable flags to configure ISVV tests for gr740
+enabled-by: sparc/gr740
+links: []
+name: ISVV_FLAGS
+type: build
diff --git a/spec/build/testsuites/optisvv.yml b/spec/build/testsuites/optisvv.yml
new file mode 100644
index 0000000000..b592b348bf
--- /dev/null
+++ b/spec/build/testsuites/optisvv.yml
@@ -0,0 +1,16 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+actions:
+- get-boolean: null
+- env-enable: null
+build-type: option
+copyrights:
+- Copyright (C) 2022 Critical Software SA
+default:
+- enabled-by: true
+ value: false
+description: |
+ Build the ISVV test programs
+enabled-by: true
+links: []
+name: BUILD_ISVVTESTS
+type: build
diff --git a/testsuites/isvv/00_uni_test_reference/basic_smp_uni.c b/testsuites/isvv/00_uni_test_reference/basic_smp_uni.c
new file mode 100644
index 0000000000..89da110ee7
--- /dev/null
+++ b/testsuites/isvv/00_uni_test_reference/basic_smp_uni.c
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+
+/**
+ *
+ * @brief Tests basic symmetric multiprocessing capabilities on multiple cores
+ *
+ * This test case performs the calculation of the Mandelbrot set on 1 core
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 1
+#define TASK_COUNT TEST_PROCESSORS
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ uint32_t start_time, end_time, elapsed_time;
+ char str[ITOA_STR_SIZE];
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ mandelbrot_tile(1,1);
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = (end_time - start_time);
+
+ print_string("\n");
+ print_string("Single Core Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ print_test_results();
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 2)
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MAXIMUM_TIMERS 3
+
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 3
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES TASK_ATTRIBUTES
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE TASK_STORAGE_SIZE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/00_uni_test_reference/mrsp_omip_uni.c b/testsuites/isvv/00_uni_test_reference/mrsp_omip_uni.c
new file mode 100644
index 0000000000..dcfa7eda58
--- /dev/null
+++ b/testsuites/isvv/00_uni_test_reference/mrsp_omip_uni.c
@@ -0,0 +1,408 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+#include <string.h>
+
+/**
+- * @brief Assert RTEMS SMP under the stress of multiple core workloads accessing protected data.
+- *
+- * This test case performs the calculation of orbital frequencies based on readings from sensors
+- * with three periodic tasks, and two binary semaphores. The result is stored as a reference set
+- * and the elapsed time is measured.
+*/
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 1
+#define TASK_COUNT 3
+
+#define END_OF_STREAM UINT8_MAX
+
+#define INCREMENT_AVAILABLE_DATA(x) (x++)
+
+#define DECREMENT_AVAILABLE_DATA(x) ({if (x>0) x--;})
+
+#define TEST_IF_DATA_AVAILABLE_IS_EMPTY(x) (x==0)
+
+#define TEST_IF_DATA_AVAILABLE_IS_NOT_EMPTY(x) (x!=0)
+
+#define EVENT_FINISHED_SENSING RTEMS_EVENT_0
+#define EVENT_CALCULATED_DATA RTEMS_EVENT_1
+#define EVENT_WROTE_DATA RTEMS_EVENT_2
+#define EVENT_SENSOR_READY RTEMS_EVENT_3
+#define EVENT_DATA_READY RTEMS_EVENT_4
+#define EVENT_DATA_OUT RTEMS_EVENT_5
+
+// For this data set, and given lumosity, the total number of planets found should equal 11
+
+#define MAX_ITER (64U)
+#define FFT_SIZE (32768U)
+#define FFT_SIZE_LOG2 (15U)
+#define TC_MAX (16U)
+#define FILTER_REPETITIONS (2U)
+#define SNR_THRESHOLD (1000000.0f)
+
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = { 2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U };
+const float NOISE_FACTOR[TC_MAX] = { 0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f };
+
+static float inSensorDataRe[FFT_SIZE];
+static float inSensorDataIm[FFT_SIZE];
+typedef struct
+{
+ rtems_id main_task_id;
+ rtems_id read_task_id;
+ rtems_id calc_task_id;
+ rtems_id write_task_id;
+ uint8_t m1_data;
+ uint32_t iter;
+ float scaling_fft_factor;
+ float snr_float;
+ rtems_id m1_data_mutex;
+ rtems_id m2_result_mutex;
+ uint8_t planet_count;
+ uint8_t planet_locations[MAX_ITER];
+ uint16_t value_in_watts_flag_counter;
+ uint16_t luminosity_flag_counter;
+ float debug_maxValueIndex;
+ float debug_maxValue;
+ float debug_sig;
+ float debig_noise;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+// * Task 0 - writes sensors data onto shared memory
+static void task_snr_read_sensor_data(rtems_task_argument arg)
+{
+ test_context *ctx;
+ ctx = (test_context *)arg;
+
+ while ( ctx->iter < MAX_ITER)
+ {
+ ObtainMutex(ctx->m1_data_mutex);
+ if TEST_IF_DATA_AVAILABLE_IS_EMPTY(ctx->value_in_watts_flag_counter)
+ {
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = 0.4995f * cos_aprox(i*2.0f*PI*FREQ[ctx->iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[ctx->iter%TC_MAX]);
+ inSensorDataIm[i] = 0.4995f * sin_aprox(i*2.0f*PI*FREQ[ctx->iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[ctx->iter% TC_MAX]);
+ }
+ INCREMENT_AVAILABLE_DATA(ctx->value_in_watts_flag_counter);
+ }
+ ReleaseMutex(ctx->m1_data_mutex);
+ rtems_task_wake_after(1);
+ }
+ SuspendSelf();
+}
+
+// * Task 1 - collects data when ready, calculates, and stores the result on the shared memory
+static void task_snr_process_data(rtems_task_argument arg)
+{
+ test_context *ctx;
+ ctx = (test_context *)arg;
+ float sig = 0.0f;
+ float noise = 0.0f;
+ bool update_luminosity_calc_result = false;
+
+ while ( ctx->iter < MAX_ITER )
+ {
+ ObtainMutex(ctx->m1_data_mutex);
+ if ( TEST_IF_DATA_AVAILABLE_IS_NOT_EMPTY(ctx->value_in_watts_flag_counter) &&
+ (update_luminosity_calc_result == false) )
+ {
+ update_luminosity_calc_result = true;
+
+ //Apply Blackman-Harris Window
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = inSensorDataRe[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ inSensorDataIm[i] = inSensorDataIm[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ }
+ //Calculates FFT
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ //Calculates the magnitude^2 values
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = (inSensorDataRe[i] * inSensorDataRe[i]
+ + inSensorDataIm[i] * inSensorDataIm[i]) / ((float)FFT_SIZE);
+ }
+
+ //Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ int32_t maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if (inSensorDataRe[i] > maxValue)
+ {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ //Calculates the signal and noise power (no DC)
+ sig = 0.0f;
+ noise = 0.0f;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if ((i > maxValueIndex - 8) && (i < maxValueIndex + 8))
+ {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else
+ {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+ ctx->debug_maxValueIndex = maxValueIndex;
+ ctx->debug_maxValue = maxValue;
+ ctx->debig_noise = noise;
+ ctx->debug_sig = sig;
+ }
+
+ ReleaseMutex(ctx->m1_data_mutex);
+
+ if (!(sig > 0.0f)) { sig = 0.0000000001f; }
+ if (!(noise > 0.0f)) { noise = 0.0000000001f; }
+
+ if (update_luminosity_calc_result)
+ {
+ ObtainMutex(ctx->m2_result_mutex);
+ if ( TEST_IF_DATA_AVAILABLE_IS_EMPTY(ctx->luminosity_flag_counter) )
+ {
+ update_luminosity_calc_result = false;
+
+ //Calculates SNR
+ ctx->snr_float = sig/noise;
+ DECREMENT_AVAILABLE_DATA(ctx->value_in_watts_flag_counter);
+ INCREMENT_AVAILABLE_DATA(ctx->luminosity_flag_counter);
+ }
+ ReleaseMutex(ctx->m2_result_mutex);
+ }
+ rtems_task_wake_after(1);
+ }
+ SuspendSelf();
+}
+
+// * Task 2 - reads the results
+static void read_and_output(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+ float result;
+
+ // Luminosity threshold to indicate planet, not e.g. star
+ float luminosity_threshold = 0.005;
+
+ while (ctx->iter < MAX_ITER)
+ {
+ ObtainMutex(ctx->m2_result_mutex);
+ if (TEST_IF_DATA_AVAILABLE_IS_NOT_EMPTY(ctx->luminosity_flag_counter))
+ {
+ if (ctx->snr_float > SNR_THRESHOLD)
+ {
+ ctx->planet_locations[ctx->iter] = 1;
+ ctx->planet_count++;
+ }
+ else
+ {
+ ctx->planet_locations[ctx->iter] = 0;
+ }
+ DECREMENT_AVAILABLE_DATA(ctx->luminosity_flag_counter);
+ ctx->iter++;
+ }
+ ReleaseMutex(ctx->m2_result_mutex);
+ rtems_task_wake_after(1);
+ }
+ rtems_event_send(ctx->main_task_id, EVENT_WROTE_DATA);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+
+ char str[ITOA_STR_SIZE];
+ uint32_t start_time, end_time, multi_core_elapsed_time;
+
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&inSensorDataRe[0], 0, FFT_SIZE);
+ (void) memset(&inSensorDataIm[0], 0, FFT_SIZE);
+
+ // Identify main task for communication between tasks
+ ctx.main_task_id = rtems_task_self();
+ SetSelfPriority( PRIO_NORMAL );
+
+ //Calculates mean of Blackman-Harris terms
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i<FFT_SIZE; i++)
+ {
+ ctx.scaling_fft_factor += blackman_harris( i, FFT_SIZE);
+ }
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor/ ((float) FFT_SIZE);
+
+ // Create the binary semaphores and intialize variables
+ ctx.m1_data_mutex = CreateMutex(rtems_build_name('M', '1', 'M', 'X'));
+ ctx.m2_result_mutex = CreateMutex(rtems_build_name('M', '2', 'M', 'X'));
+
+ ctx.planet_count = 0;
+ memset(&ctx.planet_locations, 0, MAX_ITER);
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ // Setup task for reading data from the sensor
+ calc_task_config.name = rtems_build_name('R', 'E', 'A', 'D');
+ calc_task_config.storage_area = &calc_task_storage[0][0];
+
+ ctx.read_task_id = DoCreateTask(calc_task_config);
+
+ // Setup task for reading from shared memory location
+ // And calculating the new result in lumens
+ calc_task_config.name = rtems_build_name('C', 'A', 'L', 'C');
+ calc_task_config.storage_area = &calc_task_storage[1][0];
+
+ ctx.calc_task_id = DoCreateTask(calc_task_config);
+
+ // Setup task for outputting from shared memory location
+ calc_task_config.name = rtems_build_name('O', 'U', 'T', 'P');
+ calc_task_config.storage_area = &calc_task_storage[2][0];
+
+ ctx.write_task_id = DoCreateTask(calc_task_config);
+
+ // Start all tasks
+ StartTask(ctx.read_task_id, task_snr_read_sensor_data, &ctx);
+ StartTask(ctx.calc_task_id, task_snr_process_data, &ctx);
+ StartTask(ctx.write_task_id, read_and_output, &ctx);
+
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ // Wait for all tasks to be completed
+ ReceiveAllEvents(EVENT_WROTE_DATA);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ // Output the results
+ print_string("Planet count: ");
+ print_string(itoa(ctx.planet_count, &str[0], 10));
+ print_string("\n");
+ print_string("Planets sensed at sensor positions: ");
+ for (uint8_t i=0; i<MAX_ITER; i++)
+ {
+ if (ctx.planet_locations[i] > 0)
+ {
+ print_string(itoa(i, &str[0], 10));
+ print_string(" ");
+ }
+ }
+
+ multi_core_elapsed_time = end_time - start_time;
+ print_string("\n");
+ print_string("Multicore Elapsed Time - ");
+ print_string(itoa(multi_core_elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ rtems_task_delete(ctx.read_task_id);
+ rtems_task_delete(ctx.calc_task_id);
+ rtems_task_delete(ctx.write_task_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 2
+
+#define CONFIGURE_MAXIMUM_TASKS ( TASK_COUNT + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/01_basic_smp_multi/basic_smp_multi.c b/testsuites/isvv/01_basic_smp_multi/basic_smp_multi.c
new file mode 100644
index 0000000000..6d3c8e938f
--- /dev/null
+++ b/testsuites/isvv/01_basic_smp_multi/basic_smp_multi.c
@@ -0,0 +1,206 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+
+/**
+ *
+ * @brief Tests basic symmetric multiprocessing capabilities on multiple cores
+ *
+ * This test case performs the calculation of the Mandelbrot set on 4 cores
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+
+static rtems_id start_barrier;
+static rtems_id TASK_COUNTER_SEMAPHORE;
+
+typedef struct
+{
+ rtems_id task_id[TASK_COUNT];
+ uint32_t processor[TASK_COUNT];
+ uint8_t tile[TASK_COUNT];
+} test_context;
+
+test_context ctx;
+
+/* create storage areas for each worker, using task construct forces
+the user to create these manually*/
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+static void calc_task_function(rtems_task_argument tile)
+{
+ uint8_t tile_n = (uint8_t)tile;
+
+ /* Store tile and processor task is working on */
+ ctx.processor[tile-1] = rtems_scheduler_get_processor();
+ ctx.tile[tile-1] = tile_n;
+
+ // for some reason this loop is needed for the scheduler to distribute tasks to all the cores
+ Loop(4);
+
+ WaitAtBarrier(start_barrier);
+
+ mandelbrot_tile(tile_n, TASK_COUNT);
+
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ // Internal call necessary to free resources for next task processing
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ char str[ITOA_STR_SIZE];
+ uint8_t wait = 0;
+
+ TASK_COUNTER_SEMAPHORE = CreateCounterSemaphore(rtems_build_name('T', 'C', 'S', '0'), 0);
+
+ rtems_task_config calc_task_config = {
+ .name = rtems_build_name('R', 'U', 'N', ' '),
+ .initial_priority = 3,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ start_barrier = CreateAutomaticBarrier(TASK_COUNT);
+
+ // Set Init to have a lower priority than the asynchronous tasks for core distribution
+ SetTaskPriority(RTEMS_SELF, 4);
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ ch = '0' + i;
+
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, (void *)(i + 1));
+ }
+
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ // Wait for all tasks to complete
+ while (wait < TASK_COUNT)
+ {
+ ObtainCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ wait++;
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ /* Identify tile and processor task worked on */
+ print_string("Processor-");
+ print_string(itoa(ctx.processor[i], &str[0], 10));
+ print_string(",Tile-");
+ print_string(itoa(ctx.tile[i], &str[0], 10));
+ print_string("\n");
+ }
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+ print_test_results();
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ }
+
+ DeleteMutex(TASK_COUNTER_SEMAPHORE);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TASKS ( TEST_PROCESSORS + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/02_core_affinity_multi/core_affinity_multi.c b/testsuites/isvv/02_core_affinity_multi/core_affinity_multi.c
new file mode 100644
index 0000000000..112d846443
--- /dev/null
+++ b/testsuites/isvv/02_core_affinity_multi/core_affinity_multi.c
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+
+/**
+ *
+ * @brief Demonstrate that tasks running in parallel will not execute on separate cores of the
+ * processor if the processor affinity is set to the same core for all tasks.
+ *
+ * This test case performs the calculation of the Mandelbrot set on 4 max cores, pinning to 0th core
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+
+static rtems_id start_barrier;
+static rtems_id TASK_COUNTER_SEMAPHORE;
+
+typedef struct
+{
+ rtems_id task_id[TASK_COUNT];
+ uint32_t processor[TASK_COUNT];
+ uint8_t tile[TASK_COUNT];
+} test_context;
+
+test_context ctx;
+
+/* create storage areas for each worker, using task construct forces
+the user to create these manually*/
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+static void calc_task_function(rtems_task_argument tile)
+{
+ uint8_t tile_n = (uint8_t)tile;
+
+ /* Store tile and processor task is working on */
+ ctx.processor[tile-1] = rtems_scheduler_get_processor();
+ ctx.tile[tile-1] = tile_n;
+
+ // for some reason this loop is needed for the scheduler to distribute tasks to all the cores
+ Loop(4);
+
+ WaitAtBarrier(start_barrier);
+
+ mandelbrot_tile(tile_n, TASK_COUNT);
+
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ // Internal call necessary to free resources for next task processing
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ char str[ITOA_STR_SIZE];
+ cpu_set_t cpuset;
+ uint8_t wait = 0;
+
+ TASK_COUNTER_SEMAPHORE = CreateCounterSemaphore(rtems_build_name('T', 'C', 'S', '0'), 0);
+
+ rtems_task_config calc_task_config = {
+ .name = rtems_build_name('R', 'U', 'N', ' '),
+ .initial_priority = 3,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ start_barrier = CreateAutomaticBarrier(TASK_COUNT);
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ ch = '0' + i;
+
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+
+ CPU_ZERO(&cpuset);
+ CPU_SET(0, &cpuset);
+ rtems_task_set_affinity(ctx.task_id[i], sizeof(cpuset), &cpuset);
+
+ StartTask(ctx.task_id[i], calc_task_function, (void *)(i + 1));
+ }
+
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ // Wait for all tasks to complete
+ while (wait < TASK_COUNT)
+ {
+ ObtainCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ wait++;
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ /* Identify tile and processor task worked on */
+ print_string("Processor-");
+ print_string(itoa(ctx.processor[i], &str[0], 10));
+ print_string(",Tile-");
+ print_string(itoa(ctx.tile[i], &str[0], 10));
+ print_string("\n");
+ }
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+ print_test_results();
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ }
+
+ DeleteMutex(TASK_COUNTER_SEMAPHORE);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TASKS ( TEST_PROCESSORS + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/03_semaphores_multi/semaphores_multi.c b/testsuites/isvv/03_semaphores_multi/semaphores_multi.c
new file mode 100644
index 0000000000..b46fce2358
--- /dev/null
+++ b/testsuites/isvv/03_semaphores_multi/semaphores_multi.c
@@ -0,0 +1,244 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+
+/**
+ *
+ * @brief Demonstrate the use of semaphores to protect access to objects.
+ *
+ * For the multi-core calculation, the Mandelbrot set is divided into tiles which are distributed
+ * between the calculation tasks; when a task completes a tile it starts on the next available tile.
+ * There is one task for each core.
+ *
+ * A binary semaphore is used to protect the variable containing the next tile information against
+ * simultaneous modification by multiple tasks.
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4
+ };
+
+uint8_t count_process[64];
+
+typedef struct {
+ rtems_id mutex_id;
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+} test_context;
+
+typedef test_context Context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+static void calc_task_function(rtems_task_argument arg) {
+ Context *ctx;
+
+ ctx = (Context *)arg;
+
+ uint8_t tile;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+
+ for (int i = 0; i < TASK_COUNT; i++) {
+ if (ctx->task_id[i] == local_id) {
+ task_idx = i;
+ break;
+ }
+ }
+
+ ObtainMutex(ctx->mutex_id);
+ tile = ctx->next_tile;
+ ctx->next_tile++;
+ ReleaseMutex(ctx->mutex_id);
+
+ while (tile <= ctx->ntiles) {
+ count_process[tile-1]++;
+ mandelbrot_tile(tile, ctx->ntiles);
+
+ ObtainMutex(ctx->mutex_id);
+ tile = ctx->next_tile;
+ ctx->next_tile++;
+ ReleaseMutex(ctx->mutex_id);
+ }
+
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg) {
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ char str[ITOA_STR_SIZE];
+ rtems_event_set received = 0;
+ rtems_event_set total_events = 0;
+ bool correctly_processed = true;
+
+ ctx.main_task = rtems_task_self();
+ ctx.mutex_id = CreateMutex(rtems_build_name('S', 'E', 'M', '1'));
+ ctx.ntiles = 64;
+ ctx.next_tile = 1;
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++) {
+ count_process[i] = 0;
+ }
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_VERY_HIGH,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES
+ };
+
+ ObtainMutex(ctx.mutex_id);
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++) {
+ ch = '0' + i;
+
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+ ReleaseMutex(ctx.mutex_id);
+
+ while (received != total_events)
+ {
+ received |= ReceiveAllEvents(total_events);
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++)
+ {
+ if (count_process[i] != 1)
+ {
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed)
+ {
+ print_string("Each tile only processed once: true\n");
+ }
+ else
+ {
+ print_string("Each tile only processed once: false\n");
+ }
+
+ print_test_results();
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ }
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 4
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/04_messages_multi/messages_multi.c b/testsuites/isvv/04_messages_multi/messages_multi.c
new file mode 100644
index 0000000000..b63733ed6c
--- /dev/null
+++ b/testsuites/isvv/04_messages_multi/messages_multi.c
@@ -0,0 +1,273 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+
+/**
+ *
+ * @brief Demonstrate the use of messages between different tasks.
+ *
+ * The Mandelbrot calculation of the Mandelbrot set is divided into tiles which are distributed
+ * between the calculation tasks; when a task completes a tile, it sends a message to get the
+ * next tile to be calculated.
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+#define MAX_MESSAGE_QUEUES 5
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10 // TASK_COUNT
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+uint8_t count_process[TOTAL_TILES] = {0};
+
+typedef struct
+{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT];
+} test_context;
+
+typedef test_context Context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ Context *ctx;
+
+ ctx = (Context *)arg;
+
+ uint8_t tile;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+
+ for (int i = 0; i < TASK_COUNT; i++)
+ {
+ if (ctx->task_id[i] == local_id)
+ {
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles)
+ {
+ count_process[tile - 1]++;
+ mandelbrot_tile(tile, ctx->ntiles);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ char str[ITOA_STR_SIZE];
+ int total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ while (ReceiveAvailableEvents() != total_events)
+ {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+
+ ctx.next_tile++;
+ }
+
+ print_string("printing results\n");
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++)
+ {
+ if (count_process[i] != 1)
+ {
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ print_test_results();
+
+ if (correctly_processed)
+ {
+ print_string("Each tile only processed once: true\n");
+ }
+ else
+ {
+ print_string("Each tile only processed once: false\n");
+ }
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+ DeleteMessageQueue(ctx.tile_queue);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_TASKS ( TEST_PROCESSORS + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/05_priorities_multi/priorities_multi.c b/testsuites/isvv/05_priorities_multi/priorities_multi.c
new file mode 100644
index 0000000000..1b6a8fef60
--- /dev/null
+++ b/testsuites/isvv/05_priorities_multi/priorities_multi.c
@@ -0,0 +1,283 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+
+/**
+ *
+ * @brief Demonstrate the use of messages between different tasks with tasks running at
+ * different priorities.
+ *
+ * The Mandelbrot set is divided into tiles which are distributed between the calculation tasks.
+ * When a task completes a tile it sends a message to get the next tile to be calculated.
+ * A separate task receives a request for the next tile to be calculated and sends that information
+ * to the requesting task by means of another message. Two calculation tasks are started for each
+ * core and the calculation tasks are running at a higher priority than the tile allocation task.
+ * This ensures that there are always tasks waiting to receive a tile allocation. It is checked
+ * that the result of the parallel calculation is the same as when generated on a single-core and
+ * that the multi-core calculation is faster than the single-core calculation.
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#define TASK_COUNT (TEST_PROCESSORS * 2)
+#define TOTAL_TILES 64
+
+#define MAX_MESSAGE_QUEUES (TASK_COUNT + 1)
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES TASK_COUNT
+
+rtems_event_set event_send[8] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4,
+ RTEMS_EVENT_5,
+ RTEMS_EVENT_6,
+ RTEMS_EVENT_7,
+ RTEMS_EVENT_8};
+
+uint8_t count_process[TOTAL_TILES] = {0};
+
+typedef struct
+{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT];
+} test_context;
+
+typedef test_context Context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ Context *ctx;
+
+ ctx = (Context *)arg;
+
+ uint8_t tile;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+
+ for (int i = 0; i < TASK_COUNT; i++)
+ {
+ if (ctx->task_id[i] == local_id)
+ {
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles)
+ {
+ count_process[tile - 1]++;
+ mandelbrot_tile(tile, ctx->ntiles);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ char str[ITOA_STR_SIZE];
+ int total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_VERY_HIGH,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ ch = '0' + i;
+
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ while (ReceiveAvailableEvents() != total_events)
+ {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+
+ ctx.next_tile++;
+ }
+
+ print_string("printing results\n");
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ print_test_results();
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++)
+ {
+ if (count_process[i] != 1)
+ {
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed)
+ {
+ print_string("Each tile only processed once: true\n");
+ }
+ else
+ {
+ print_string("Each tile only processed once: false\n");
+ }
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+ DeleteMessageQueue(ctx.tile_queue);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_TASKS (TASK_COUNT + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/06_rate_monotonic_multi/rate_monotonic_multi.c b/testsuites/isvv/06_rate_monotonic_multi/rate_monotonic_multi.c
new file mode 100644
index 0000000000..6f5dc1348f
--- /dev/null
+++ b/testsuites/isvv/06_rate_monotonic_multi/rate_monotonic_multi.c
@@ -0,0 +1,292 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+
+/**
+- * @brief Assert RTEMS SMP under the stress of multiple core workloads with periodic tasks and
+- * accessing protected data.
+- *
+- * This test case performs the calculation of the mandelbrot set divided by tiles and distributed
+- * with periodic tasks. The result is stored as a reference set and the elapsed time is measured.
+*/
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+/* Given the board, define rate monotonic period length
+ to approx. the mean time needed to calculate a single tile */
+#ifdef gr740
+ const rtems_interval PERIOD_LENGTH = 800;
+#endif
+#ifdef gr712rc
+ const rtems_interval PERIOD_LENGTH = 2500;
+#endif
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+uint8_t count_process[TOTAL_TILES] = {0};
+
+typedef struct
+{
+ rtems_id mutex_id;
+ rtems_id main_task;
+ rtems_id monoperiod;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ uint16_t periods_executed;
+ uint16_t deadlines_missed;
+ rtems_id manual_barrier_id;
+} test_context;
+
+typedef test_context Context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ Context *ctx;
+ ctx = (Context *)arg;
+
+ uint8_t tile = 0;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+
+ for (int i = 0; i < TASK_COUNT; i++)
+ {
+ if (ctx->task_id[i] == local_id)
+ {
+ task_idx = i;
+ break;
+ }
+ }
+
+ while (tile < ctx->ntiles)
+ {
+ WaitAtBarrier(ctx->manual_barrier_id);
+
+ ObtainMutex(ctx->mutex_id);
+ tile = ctx->next_tile;
+ count_process[tile - 1]++;
+ ctx->next_tile++;
+ ReleaseMutex(ctx->mutex_id);
+
+ mandelbrot_tile(tile, ctx->ntiles);
+
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ }
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ char str[ITOA_STR_SIZE];
+ int total_events = 0;
+ bool correctly_processed = true;
+
+ rtems_event_set received = 0;
+
+ ctx.main_task = rtems_task_self();
+ ctx.mutex_id = CreateMutex(rtems_build_name('R', 'M', 'O', '1'));
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+ ctx.monoperiod = CreateRateMonotonic();
+ ctx.periods_executed = 0;
+ ctx.deadlines_missed = 0;
+
+ ctx.manual_barrier_id = CreateManualBarrier();
+
+ rtems_id main_sched_id;
+ rtems_task_get_scheduler(ctx.main_task, &main_sched_id);
+
+ rtems_task_priority init_task_priority;
+ rtems_task_get_priority(ctx.main_task, main_sched_id, &init_task_priority);
+
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = init_task_priority,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ObtainMutex(ctx.mutex_id);
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ ch = '0' + i;
+
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ ReleaseMutex(ctx.mutex_id);
+
+ WaitPeriod(ctx.monoperiod, PERIOD_LENGTH);
+ uint8_t tile = 0;
+ while (tile < ctx.ntiles )
+ {
+ ReleaseManualBarrier(ctx.manual_barrier_id, TASK_COUNT);
+
+ while (received != total_events)
+ {
+ received |= ReceiveAllEvents(total_events);
+ }
+
+ if (DoesPeriodTimeOut(ctx.monoperiod, PERIOD_LENGTH))
+ {
+ ctx.deadlines_missed++;
+ }
+
+ ctx.periods_executed++;
+ ObtainMutex(ctx.mutex_id);
+ tile = ctx.next_tile-1;
+ ReleaseMutex(ctx.mutex_id);
+ received = 0;
+ }
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ }
+ DeleteMutex(ctx.mutex_id);
+ DeleteRateMonotonic(ctx.monoperiod);
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time = ");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n\r");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++)
+ {
+ if (count_process[i] != 1)
+ {
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed)
+ {
+ print_string("Each tile only processed once: true\n");
+ }
+ else
+ {
+ print_string("Each tile only processed once: false\n");
+ }
+
+ print_test_results();
+
+ print_string("Number of rate monotonic periods executed: ");
+ print_string(itoa(ctx.periods_executed, &str[0], 10));
+ print_string("\n");
+ print_string("Number of rate monotonic deadlines missed: ");
+ print_string(itoa(ctx.deadlines_missed, &str[0], 10));
+ print_string("\n");
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_PERIODS 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/07_timer_multi/timer_multi.c b/testsuites/isvv/07_timer_multi/timer_multi.c
new file mode 100644
index 0000000000..2848350ca4
--- /dev/null
+++ b/testsuites/isvv/07_timer_multi/timer_multi.c
@@ -0,0 +1,291 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+
+#include <stdlib.h>
+
+/**
+ *
+ * @brief Demonstrate the use of the Timer.
+ *
+ * The Mandelbrot calculation of the Mandelbrot set is divided into tiles which are distributed
+ * between the calculation tasks; when a task completes a tile, it sends a message to get the
+ * next tile to be calculated.
+ *
+ * Two timers are set up to increment counters at different rates. It is checked that the result
+ * of the parallel calculation is the same as when generated on a single-core and that the
+ * multi-core calculation is faster than the single-core calculation. The number of timer service
+ * routines that have been executed is checked.
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+void service_timer(rtems_id timer_id, void *user_data);
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+
+uint8_t count_process[TOTAL_TILES] = {0};
+
+typedef struct
+{
+ rtems_id id;
+ uint16_t counter;
+} timer;
+
+typedef struct
+{
+ rtems_id mutex_id;
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ timer fast_timer;
+ timer slow_timer;
+} test_context;
+
+typedef test_context Context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ Context *ctx;
+
+ ctx = (Context *)arg;
+
+ uint8_t tile;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+
+ for (int i = 0; i < TASK_COUNT; i++)
+ {
+ if (ctx->task_id[i] == local_id)
+ {
+ task_idx = i;
+ break;
+ }
+ }
+
+ ObtainMutex(ctx->mutex_id);
+ tile = ctx->next_tile;
+ ctx->next_tile++;
+ ReleaseMutex(ctx->mutex_id);
+
+ while (tile <= ctx->ntiles)
+ {
+ count_process[tile - 1]++;
+ mandelbrot_tile(tile, ctx->ntiles);
+
+ ObtainMutex(ctx->mutex_id);
+ tile = ctx->next_tile;
+ ctx->next_tile++;
+ ReleaseMutex(ctx->mutex_id);
+ }
+
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+void service_timer(rtems_id timer_id, void *user_data)
+{
+ timer *tmr = user_data;
+
+ tmr->counter++;
+ ResetTimer(timer_id);
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ char str[ITOA_STR_SIZE];
+ int total_events = 0;
+ bool correctly_processed = true;
+
+ ctx.main_task = rtems_task_self();
+ SetSelfPriority(PRIO_HIGH);
+ ctx.mutex_id = CreateMutex(rtems_build_name('T', 'M', 'U', '1'));
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_VERY_HIGH,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ObtainMutex(ctx.mutex_id);
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ ch = '0' + i;
+
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ ctx.fast_timer.id = CreateTimer(rtems_build_name('F', 'T', 'M', 'R'));
+ ctx.fast_timer.counter = 0;
+ ctx.slow_timer.id = CreateTimer(rtems_build_name('S', 'T', 'M', 'R'));
+ ctx.slow_timer.counter = 0;
+
+ LaunchFunctionAfter(ctx.fast_timer.id, 11, service_timer, &ctx.fast_timer);
+ LaunchFunctionAfter(ctx.slow_timer.id, 23, service_timer, &ctx.slow_timer);
+
+ ReleaseMutex(ctx.mutex_id);
+
+ while (ReceiveAvailableEvents() != total_events)
+ {
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ print_string("Fast timer counter: ");
+ print_string(itoa(ctx.fast_timer.counter, &str[0], 10));
+ print_string("\n");
+ print_string("Slow timer counter: ");
+ print_string(itoa(ctx.slow_timer.counter, &str[0], 10));
+ print_string("\n");
+
+ elapsed_time = end_time - start_time;
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ print_test_results();
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++)
+ {
+ if (count_process[i] != 1)
+ {
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed)
+ {
+ print_string("Each tile only processed once: true\n");
+ }
+ else
+ {
+ print_string("Each tile only processed once: false\n");
+ }
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ }
+ DeleteMutex(ctx.mutex_id);
+ DeleteTimer(ctx.fast_timer.id);
+ DeleteTimer(ctx.slow_timer.id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_PERIODS 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TIMERS 2
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/09_timer_server_multi/timer_server_multi.c b/testsuites/isvv/09_timer_server_multi/timer_server_multi.c
new file mode 100644
index 0000000000..02a8d5ddfd
--- /dev/null
+++ b/testsuites/isvv/09_timer_server_multi/timer_server_multi.c
@@ -0,0 +1,269 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/counter.h>
+
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+
+#include <stdlib.h>
+
+/**
+ *
+ * @brief Demonstrate the use of the Timer Service.
+ *
+ * This test case uses a timer server to execute the service routines. The timer server is started
+ * at the default priority so that it interrupts the calculation tasks. This means that the service
+ * routine will not execute until the next calculation task completes.
+ *
+ * The Mandelbrot calculation of the Mandelbrot set is divided into tiles which are distributed
+ * between the calculation tasks; when a task completes a tile, it sends a message to get the
+ * next tile to be calculated.
+ *
+ * Two timers are set up to increment counters at different rates. It is checked that the result
+ * of the parallel calculation is the same as when generated on a single-core and that the
+ * multi-core calculation is faster than the single-core calculation. The number of timer service
+ * routines that have been executed is checked.
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4
+ };
+
+typedef struct {
+ rtems_id id;
+ uint16_t counter;
+} timer;
+
+typedef struct {
+ rtems_id mutex_id;
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ timer fast_timer;
+ timer slow_timer;
+} test_context;
+
+typedef test_context Context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+static void calc_task_function(rtems_task_argument arg) {
+ Context *ctx;
+
+ ctx = (Context *)arg;
+
+ uint8_t tile;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+ char str;
+
+ for (int i = 0; i < TASK_COUNT; i++) {
+ if (ctx->task_id[i] == local_id) {
+ task_idx = i;
+ break;
+ }
+ }
+
+ ObtainMutex(ctx->mutex_id);
+ tile = ctx->next_tile;
+ ctx->next_tile++;
+ ReleaseMutex(ctx->mutex_id);
+
+ while (tile <= ctx->ntiles) {
+ mandelbrot_tile(tile, ctx->ntiles);
+
+ ObtainMutex(ctx->mutex_id);
+ tile = ctx->next_tile;
+ ctx->next_tile++;
+ ReleaseMutex(ctx->mutex_id);
+ }
+
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+
+void service_timer( rtems_id timer_id, void *user_data )
+{
+ timer *tmr = user_data;
+
+ tmr->counter++;
+ ResetTimer(timer_id);
+}
+
+static void Init( rtems_task_argument arg ) {
+ (void)arg;
+ rtems_status_code sc;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ char str[ITOA_STR_SIZE];
+ uint32_t current_cpu;
+ bool allDone;
+ rtems_task_argument tile;
+ rtems_event_set received = 0;
+ int total_events = 0;
+
+ ctx.main_task = rtems_task_self();
+ ctx.mutex_id = CreateMutex(rtems_build_name('T', 'S', 'M', '1'));
+ ctx.ntiles = 64;
+ ctx.next_tile = 1;
+
+ sc = rtems_timer_initiate_server(RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES);
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES
+ };
+
+ ObtainMutex(ctx.mutex_id);
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++) {
+ ch = '0' + i;
+
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+
+
+ ctx.fast_timer.id = CreateTimer(rtems_build_name( 'F', 'T', 'M', 'R' ));
+ ctx.fast_timer.counter = 0;
+ ctx.slow_timer.id = CreateTimer(rtems_build_name( 'S', 'T', 'M', 'R' ));
+ ctx.slow_timer.counter = 0;
+
+ LaunchFunctionAfter(ctx.fast_timer.id, 11, service_timer, &ctx.fast_timer);
+ LaunchFunctionAfter(ctx.slow_timer.id, 23, service_timer, &ctx.slow_timer);
+
+ ReleaseMutex(ctx.mutex_id);
+
+ while (ReceiveAvailableEvents() != total_events) {
+ }
+
+ print_string("printing results");
+ rtems_putc('\n');
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ print_string(itoa(ctx.fast_timer.counter, &str[0], 10));
+ rtems_putc(' ');
+ print_string(itoa(ctx.slow_timer.counter, &str[0], 10));
+ rtems_putc('\n');
+
+
+ elapsed_time = end_time - start_time;
+
+ print_test_results();
+ for (uint32_t i = 0; i < TASK_COUNT; i++) {
+ DeleteTask(ctx.task_id[i]);
+ }
+ DeleteMutex(ctx.mutex_id);
+ DeleteTimer(ctx.fast_timer.id);
+ DeleteTimer(ctx.slow_timer.id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_PERIODS 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TIMERS 2
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/10_barrier_multi/barrier_multi.c b/testsuites/isvv/10_barrier_multi/barrier_multi.c
new file mode 100644
index 0000000000..1c60f62d95
--- /dev/null
+++ b/testsuites/isvv/10_barrier_multi/barrier_multi.c
@@ -0,0 +1,302 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+
+/**
+ *
+ * @brief Demonstrate the use of barriers in SMP context.
+ *
+ * The Mandelbrot set tiles are distributed between worker tasks to perform the calculation.
+ * Before starting each set, worker tasks are freed by a manual barrier owned by a controlling
+ * thread that releases the barrier after distributing the set, one tile per core.
+ *
+ * Then a set of worker tasks perform the tile calculations in parallel. Only when all of them finish
+ * the controlling task will distribute a new set. This is controlled by an automatic barrier that
+ * releases when all of the worker tasks complete calculations.
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+rtems_event_set event_send[] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+#define MAX_MESSAGE_QUEUES 5
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES TASK_COUNT
+
+uint8_t count_process[TOTAL_TILES] = {0};
+
+typedef struct
+{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT];
+ rtems_id auto_barrier_id;
+ rtems_id manual_barrier_id;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ test_context *ctx;
+
+ ctx = (test_context *)arg;
+
+ uint8_t tile = 0;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 0;
+
+ for (int i = 0; i < TASK_COUNT; i++)
+ {
+ if (ctx->task_id[i] == local_id)
+ {
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ while (tile <= ctx->ntiles)
+ {
+ WaitAtBarrier(ctx->manual_barrier_id);
+
+ count_process[tile - 1]++;
+ mandelbrot_tile(tile, ctx->ntiles);
+
+ WaitAtBarrier(ctx->auto_barrier_id);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ uint8_t task = 255;
+ rtems_event_set received = 0;
+ rtems_event_set total_events = 0;
+ bool correctly_processed = true;
+ char str[ITOA_STR_SIZE];
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+ uint8_t nwaiting = TASK_COUNT;
+ ctx.auto_barrier_id = CreateAutomaticBarrier(nwaiting);
+ ctx.manual_barrier_id = CreateManualBarrier();
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ while (ctx.next_tile <= ctx.ntiles + TASK_COUNT)
+ {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+
+ if (ctx.next_tile <= ctx.ntiles)
+ {
+ if (ctx.next_tile % TASK_COUNT == 0)
+ {
+ ReleaseManualBarrier(ctx.manual_barrier_id, TASK_COUNT);
+ }
+ else if (ctx.next_tile == ctx.ntiles)
+ {
+ ReleaseManualBarrier(ctx.manual_barrier_id, ctx.next_tile % TASK_COUNT);
+ }
+ }
+
+ ctx.next_tile++;
+ }
+
+ while (received != total_events)
+ {
+ received |= ReceiveAllEvents(total_events);
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ print_test_results();
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++)
+ {
+ if (count_process[i] != 1)
+ {
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed)
+ {
+ print_string("Each tile only processed once: true\n");
+ }
+ else
+ {
+ print_string("Each tile only processed once: false\n");
+ }
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+ DeleteMessageQueue(ctx.tile_queue);
+ DeleteBarrier(ctx.auto_barrier_id);
+ DeleteBarrier(ctx.manual_barrier_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 2
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/10_barrier_multi/barrier_multi_timeout.c b/testsuites/isvv/10_barrier_multi/barrier_multi_timeout.c
new file mode 100644
index 0000000000..80b48dd7b5
--- /dev/null
+++ b/testsuites/isvv/10_barrier_multi/barrier_multi_timeout.c
@@ -0,0 +1,337 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+
+/**
+ *
+ * @brief Demonstrate the use of barriers in SMP context.
+ *
+ * The Mandelbrot set tiles are distributed between worker tasks to perform the calculation.
+ * Before starting each set, worker tasks are freed by a manual barrier owned by a controlling
+ * thread that releases the barrier after distributing the set, one tile per core.
+ *
+ * Then a set of worker tasks perform the tile calculations in parallel. Only when all of them finish
+ * the controlling task will distribute a new set. This is controlled by an automatic barrier that
+ * releases when all of the worker tasks complete calculations.
+ *
+ * A final step runs the same but induces a lock (e.g. a delay on one of the workers, leading to
+ * the barrier not to be released), to check whether timeout is reached.
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+rtems_event_set event_send[] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+#define MAX_MESSAGE_QUEUES 5
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES TASK_COUNT
+
+uint8_t count_process[TOTAL_TILES] = {0};
+
+typedef struct
+{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT];
+ rtems_id auto_barrier_id;
+ rtems_id manual_barrier_id;
+ rtems_id timeout_mutex;
+ uint8_t timeout_flag;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ test_context *ctx;
+
+ ctx = (test_context *)arg;
+ uint8_t tile = 0;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 0;
+
+ for (int i = 0; i < TASK_COUNT; i++)
+ {
+ if (ctx->task_id[i] == local_id)
+ {
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ while (tile <= ctx->ntiles)
+ {
+ rtems_status_code sc;
+ char *timeout = "RTEMS_TIMEOUT";
+
+ WaitAtBarrier(ctx->manual_barrier_id);
+
+ count_process[tile - 1]++;
+ mandelbrot_tile(tile, ctx->ntiles);
+
+ // Cause infinite loop so that automatic barrier times out.
+ if (task_idx == 3)
+ {
+ while (1);
+ }
+
+ sc = rtems_barrier_wait(ctx->auto_barrier_id, BARRIER_TIMEOUT);
+ if(rtems_status_text(sc) == timeout)
+ {
+ // First thread that registers the timeout reports it.
+ ObtainMutex(ctx->timeout_mutex);
+ if(ctx->timeout_flag == 0)
+ {
+ ctx->timeout_flag = 1;
+ }
+ ReleaseMutex(ctx->timeout_mutex);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ uint8_t task = 255;
+ rtems_event_set received = 0;
+ rtems_event_set total_events = 0;
+ bool correctly_processed = true;
+ char str[ITOA_STR_SIZE];
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+ uint8_t nwaiting = TASK_COUNT;
+ ctx.auto_barrier_id = CreateAutomaticBarrier(nwaiting);
+ ctx.manual_barrier_id = CreateManualBarrier();
+ ctx.timeout_mutex = CreateMutex(rtems_build_name('B', 'M', 'T', '1'));
+ ctx.timeout_flag = 0;
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ while ((ctx.next_tile <= ctx.ntiles + TASK_COUNT) && (ctx.timeout_flag == 0))
+ {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+
+ if (ctx.next_tile <= ctx.ntiles)
+ {
+ if (ctx.next_tile % TASK_COUNT == 0)
+ {
+ ReleaseManualBarrier(ctx.manual_barrier_id, TASK_COUNT);
+ }
+ else if (ctx.next_tile == ctx.ntiles)
+ {
+ ReleaseManualBarrier(ctx.manual_barrier_id, ctx.next_tile % TASK_COUNT);
+ }
+ }
+
+ ctx.next_tile++;
+ }
+
+ while (received != total_events)
+ {
+ received |= ReceiveAllEvents(total_events);
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ print_test_results();
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++)
+ {
+ if (count_process[i] != 1)
+ {
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed)
+ {
+ print_string("Each tile only processed once: true\n");
+ }
+ else
+ {
+ print_string("Each tile only processed once: false\n");
+ }
+
+ if(ctx.timeout_flag == 1)
+ {
+ print_string("RTEMS_TIMEOUT ocurred: true\n");
+ }
+ else
+ {
+ print_string("RTEMS_TIMEOUT ocurred: false\n");
+ }
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+ DeleteMessageQueue(ctx.tile_queue);
+ DeleteBarrier(ctx.auto_barrier_id);
+ DeleteBarrier(ctx.manual_barrier_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 2
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/11_MrsP_multi/mrsp_multi.c b/testsuites/isvv/11_MrsP_multi/mrsp_multi.c
new file mode 100644
index 0000000000..b6253185f0
--- /dev/null
+++ b/testsuites/isvv/11_MrsP_multi/mrsp_multi.c
@@ -0,0 +1,436 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+#include <string.h>
+
+/**
+- * @brief Assert RTEMS SMP under the stress of multiple core workloads accessing protected data.
+- *
+- * This test case performs the calculation of orbital frequencies based on readings from sensors
+- * with three periodic tasks, and two binary semaphores. The result is stored as a reference set
+- * and the elapsed time is measured.
+*/
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 2
+#define TASK_COUNT 3
+
+#define END_OF_STREAM UINT8_MAX
+
+#define INCREMENT_AVAILABLE_DATA(x) (x++)
+
+#define DECREMENT_AVAILABLE_DATA(x) ({if (x>0) x--;})
+
+#define TEST_IF_DATA_AVAILABLE_IS_EMPTY(x) (x==0)
+
+#define TEST_IF_DATA_AVAILABLE_IS_NOT_EMPTY(x) (x!=0)
+
+#define EVENT_FINISHED_SENSING RTEMS_EVENT_0
+#define EVENT_CALCULATED_DATA RTEMS_EVENT_1
+#define EVENT_WROTE_DATA RTEMS_EVENT_2
+#define EVENT_SENSOR_READY RTEMS_EVENT_3
+#define EVENT_DATA_READY RTEMS_EVENT_4
+#define EVENT_DATA_OUT RTEMS_EVENT_5
+
+// For this data set, and given lumosity, the total number of planets found should equal 11
+
+#define MAX_ITER (64U)
+#define FFT_SIZE (32768U)
+#define FFT_SIZE_LOG2 (15U)
+#define TC_MAX (16U)
+#define FILTER_REPETITIONS (2U)
+#define SNR_THRESHOLD (1000000.0f)
+
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = { 2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U };
+const float NOISE_FACTOR[TC_MAX] = { 0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f };
+
+static float inSensorDataRe[FFT_SIZE];
+static float inSensorDataIm[FFT_SIZE];
+typedef struct
+{
+ rtems_id main_task_id;
+ rtems_id read_task_id;
+ rtems_id calc_task_id;
+ rtems_id write_task_id;
+ uint8_t m1_data;
+ uint32_t iter;
+ float scaling_fft_factor;
+ float snr_float;
+ rtems_id m1_data_mutex;
+ rtems_id m2_result_mutex;
+ uint8_t planet_count;
+ uint8_t planet_locations[MAX_ITER];
+ uint16_t value_in_watts_flag_counter;
+ uint16_t luminosity_flag_counter;
+ float debug_maxValueIndex;
+ float debug_maxValue;
+ float debug_sig;
+ float debig_noise;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+// * Task 0 - writes sensors data onto shared memory
+static void task_snr_read_sensor_data(rtems_task_argument arg)
+{
+ test_context *ctx;
+ ctx = (test_context *)arg;
+
+ while ( ctx->iter < MAX_ITER)
+ {
+ ObtainMutex(ctx->m1_data_mutex);
+ if TEST_IF_DATA_AVAILABLE_IS_EMPTY(ctx->value_in_watts_flag_counter)
+ {
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = 0.4995f * cos_aprox(i*2.0f*PI*FREQ[ctx->iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[ctx->iter%TC_MAX]);
+ inSensorDataIm[i] = 0.4995f * sin_aprox(i*2.0f*PI*FREQ[ctx->iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[ctx->iter% TC_MAX]);
+ }
+ INCREMENT_AVAILABLE_DATA(ctx->value_in_watts_flag_counter);
+ }
+ ReleaseMutex(ctx->m1_data_mutex);
+ rtems_task_wake_after(1);
+ }
+ SuspendSelf();
+}
+
+// * Task 1 - collects data when ready, calculates, and stores the result on the shared memory
+static void task_snr_process_data(rtems_task_argument arg)
+{
+ test_context *ctx;
+ ctx = (test_context *)arg;
+ float sig = 0.0f;
+ float noise = 0.0f;
+ bool update_luminosity_calc_result = false;
+
+ while ( ctx->iter < MAX_ITER )
+ {
+ ObtainMutex(ctx->m1_data_mutex);
+ if ( TEST_IF_DATA_AVAILABLE_IS_NOT_EMPTY(ctx->value_in_watts_flag_counter) &&
+ (update_luminosity_calc_result == false) )
+ {
+ update_luminosity_calc_result = true;
+
+ //Apply Blackman-Harris Window
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = inSensorDataRe[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ inSensorDataIm[i] = inSensorDataIm[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ }
+ //Calculates FFT
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ //Calculates the magnitude^2 values
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = (inSensorDataRe[i] * inSensorDataRe[i]
+ + inSensorDataIm[i] * inSensorDataIm[i]) / ((float)FFT_SIZE);
+ }
+
+ //Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ int32_t maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if (inSensorDataRe[i] > maxValue)
+ {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ //Calculates the signal and noise power (no DC)
+ sig = 0.0f;
+ noise = 0.0f;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if ((i > maxValueIndex - 8) && (i < maxValueIndex + 8))
+ {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else
+ {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+ ctx->debug_maxValueIndex = maxValueIndex;
+ ctx->debug_maxValue = maxValue;
+ ctx->debig_noise = noise;
+ ctx->debug_sig = sig;
+ }
+
+ ReleaseMutex(ctx->m1_data_mutex);
+
+ if (!(sig > 0.0f)) { sig = 0.0000000001f; }
+ if (!(noise > 0.0f)) { noise = 0.0000000001f; }
+
+ if (update_luminosity_calc_result)
+ {
+ ObtainMutex(ctx->m2_result_mutex);
+ if ( TEST_IF_DATA_AVAILABLE_IS_EMPTY(ctx->luminosity_flag_counter) )
+ {
+ update_luminosity_calc_result = false;
+
+ //Calculates SNR
+ ctx->snr_float = sig/noise;
+ DECREMENT_AVAILABLE_DATA(ctx->value_in_watts_flag_counter);
+ INCREMENT_AVAILABLE_DATA(ctx->luminosity_flag_counter);
+ }
+ ReleaseMutex(ctx->m2_result_mutex);
+ }
+ rtems_task_wake_after(1);
+ }
+ SuspendSelf();
+}
+
+// * Task 2 - reads the results
+static void read_and_output(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+ float result;
+
+ // Luminosity threshold to indicate planet, not e.g. star
+ float luminosity_threshold = 0.005;
+
+ while (ctx->iter < MAX_ITER)
+ {
+ ObtainMutex(ctx->m2_result_mutex);
+ if (TEST_IF_DATA_AVAILABLE_IS_NOT_EMPTY(ctx->luminosity_flag_counter))
+ {
+ if (ctx->snr_float > SNR_THRESHOLD)
+ {
+ ctx->planet_locations[ctx->iter] = 1;
+ ctx->planet_count++;
+ }
+ else
+ {
+ ctx->planet_locations[ctx->iter] = 0;
+ }
+ DECREMENT_AVAILABLE_DATA(ctx->luminosity_flag_counter);
+ ctx->iter++;
+ }
+ ReleaseMutex(ctx->m2_result_mutex);
+ rtems_task_wake_after(1);
+ }
+ rtems_event_send(ctx->main_task_id, EVENT_WROTE_DATA);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+
+ char str[ITOA_STR_SIZE];
+ uint32_t start_time, end_time, multi_core_elapsed_time;
+
+ rtems_id scsw_core_id;
+ rtems_id aocs_core_id;
+
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&inSensorDataRe[0], 0, FFT_SIZE);
+ (void) memset(&inSensorDataIm[0], 0, FFT_SIZE);
+
+ // Identify main task for communication between tasks
+ ctx.main_task_id = rtems_task_self();
+ SetSelfPriority( PRIO_NORMAL );
+
+ //Calculates mean of Blackman-Harris terms
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i<FFT_SIZE; i++)
+ {
+ ctx.scaling_fft_factor += blackman_harris( i, FFT_SIZE);
+ }
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor/ ((float) FFT_SIZE);
+
+ // Create the binary semaphores and intialize variables
+ ctx.m1_data_mutex = CreateMutexMrsP(rtems_build_name('M', '1', 'M', 'X'));
+ ctx.m2_result_mutex = CreateMutexMrsP(rtems_build_name('M', '2', 'M', 'X'));
+
+ ctx.planet_count = 0;
+ memset(&ctx.planet_locations, 0, MAX_ITER);
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ scsw_core_id = IdentifyScheduler(SCHEDULER_A_NAME);
+ aocs_core_id = IdentifyScheduler(SCHEDULER_B_NAME);
+
+ // Setup task for reading data from the sensor
+ calc_task_config.name = rtems_build_name('R', 'E', 'A', 'D');
+ calc_task_config.storage_area = &calc_task_storage[0][0];
+
+ ctx.read_task_id = DoCreateTask(calc_task_config);
+ SetScheduler(ctx.read_task_id, scsw_core_id, PRIO_LOW);
+
+ // Setup task for reading from shared memory location
+ // And calculating the new result in lumens
+ calc_task_config.name = rtems_build_name('C', 'A', 'L', 'C');
+ calc_task_config.storage_area = &calc_task_storage[1][0];
+
+ ctx.calc_task_id = DoCreateTask(calc_task_config);
+ SetScheduler(ctx.calc_task_id, aocs_core_id, PRIO_NORMAL);
+
+ // Setup task for outputting from shared memory location
+ calc_task_config.name = rtems_build_name('O', 'U', 'T', 'P');
+ calc_task_config.storage_area = &calc_task_storage[2][0];
+
+ ctx.write_task_id = DoCreateTask(calc_task_config);
+ SetScheduler(ctx.write_task_id, scsw_core_id, PRIO_HIGH);
+
+ // Start all tasks
+ StartTask(ctx.read_task_id, task_snr_read_sensor_data, &ctx);
+ StartTask(ctx.calc_task_id, task_snr_process_data, &ctx);
+ StartTask(ctx.write_task_id, read_and_output, &ctx);
+
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ // Wait for all tasks to be completed
+ ReceiveAllEvents(EVENT_WROTE_DATA);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ // Output the results
+ print_string("Planet count: ");
+ print_string(itoa(ctx.planet_count, &str[0], 10));
+ print_string("\n");
+ print_string("Planets sensed at sensor positions: ");
+ for (uint8_t i=0; i<MAX_ITER; i++)
+ {
+ if (ctx.planet_locations[i] > 0)
+ {
+ print_string(itoa(i, &str[0], 10));
+ print_string(" ");
+ }
+ }
+
+ multi_core_elapsed_time = end_time - start_time;
+ print_string("\n");
+ print_string("Multicore Elapsed Time - ");
+ print_string(itoa(multi_core_elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ rtems_task_delete(ctx.read_task_id);
+ rtems_task_delete(ctx.calc_task_id);
+ rtems_task_delete(ctx.write_task_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 2
+
+#define CONFIGURE_MAXIMUM_TASKS ( TASK_COUNT + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_EDF_SMP( a );
+RTEMS_SCHEDULER_EDF_SMP( b );
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP(a, SCHEDULER_A_NAME), \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP(b, SCHEDULER_B_NAME)
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
+ RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
+
+
+#define CONFIGURE_SCHEDULER_NAME SCHEDULER_A_NAME
+
+#define CONFIGURE_SCHEDULER_PRIORITY
+
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/12_OMIP_multi/omip_multi.c b/testsuites/isvv/12_OMIP_multi/omip_multi.c
new file mode 100644
index 0000000000..162a24a46e
--- /dev/null
+++ b/testsuites/isvv/12_OMIP_multi/omip_multi.c
@@ -0,0 +1,436 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+#include <string.h>
+
+/**
+- * @brief Assert RTEMS SMP under the stress of multiple core workloads accessing protected data.
+- *
+- * This test case performs the calculation of orbital frequencies based on readings from sensors
+- * with three periodic tasks, and two binary semaphores. The result is stored as a reference set
+- * and the elapsed time is measured.
+*/
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 2
+#define TASK_COUNT 3
+
+#define END_OF_STREAM UINT8_MAX
+
+#define INCREMENT_AVAILABLE_DATA(x) (x++)
+
+#define DECREMENT_AVAILABLE_DATA(x) ({if (x>0) x--;})
+
+#define TEST_IF_DATA_AVAILABLE_IS_EMPTY(x) (x==0)
+
+#define TEST_IF_DATA_AVAILABLE_IS_NOT_EMPTY(x) (x!=0)
+
+#define EVENT_FINISHED_SENSING RTEMS_EVENT_0
+#define EVENT_CALCULATED_DATA RTEMS_EVENT_1
+#define EVENT_WROTE_DATA RTEMS_EVENT_2
+#define EVENT_SENSOR_READY RTEMS_EVENT_3
+#define EVENT_DATA_READY RTEMS_EVENT_4
+#define EVENT_DATA_OUT RTEMS_EVENT_5
+
+// For this data set, and given lumosity, the total number of planets found should equal 11
+
+#define MAX_ITER (64U)
+#define FFT_SIZE (32768U)
+#define FFT_SIZE_LOG2 (15U)
+#define TC_MAX (16U)
+#define FILTER_REPETITIONS (2U)
+#define SNR_THRESHOLD (1000000.0f)
+
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = { 2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U };
+const float NOISE_FACTOR[TC_MAX] = { 0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f };
+
+static float inSensorDataRe[FFT_SIZE];
+static float inSensorDataIm[FFT_SIZE];
+typedef struct
+{
+ rtems_id main_task_id;
+ rtems_id read_task_id;
+ rtems_id calc_task_id;
+ rtems_id write_task_id;
+ uint8_t m1_data;
+ uint32_t iter;
+ float scaling_fft_factor;
+ float snr_float;
+ rtems_id m1_data_mutex;
+ rtems_id m2_result_mutex;
+ uint8_t planet_count;
+ uint8_t planet_locations[MAX_ITER];
+ uint16_t value_in_watts_flag_counter;
+ uint16_t luminosity_flag_counter;
+ float debug_maxValueIndex;
+ float debug_maxValue;
+ float debug_sig;
+ float debig_noise;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+// * Task 0 - writes sensors data onto shared memory
+static void task_snr_read_sensor_data(rtems_task_argument arg)
+{
+ test_context *ctx;
+ ctx = (test_context *)arg;
+
+ while ( ctx->iter < MAX_ITER)
+ {
+ ObtainMutex(ctx->m1_data_mutex);
+ if TEST_IF_DATA_AVAILABLE_IS_EMPTY(ctx->value_in_watts_flag_counter)
+ {
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = 0.4995f * cos_aprox(i*2.0f*PI*FREQ[ctx->iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[ctx->iter%TC_MAX]);
+ inSensorDataIm[i] = 0.4995f * sin_aprox(i*2.0f*PI*FREQ[ctx->iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[ctx->iter% TC_MAX]);
+ }
+ INCREMENT_AVAILABLE_DATA(ctx->value_in_watts_flag_counter);
+ }
+ ReleaseMutex(ctx->m1_data_mutex);
+ rtems_task_wake_after(1);
+ }
+ SuspendSelf();
+}
+
+// * Task 1 - collects data when ready, calculates, and stores the result on the shared memory
+static void task_snr_process_data(rtems_task_argument arg)
+{
+ test_context *ctx;
+ ctx = (test_context *)arg;
+ float sig = 0.0f;
+ float noise = 0.0f;
+ bool update_luminosity_calc_result = false;
+
+ while ( ctx->iter < MAX_ITER )
+ {
+ ObtainMutex(ctx->m1_data_mutex);
+ if ( TEST_IF_DATA_AVAILABLE_IS_NOT_EMPTY(ctx->value_in_watts_flag_counter) &&
+ (update_luminosity_calc_result == false) )
+ {
+ update_luminosity_calc_result = true;
+
+ //Apply Blackman-Harris Window
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = inSensorDataRe[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ inSensorDataIm[i] = inSensorDataIm[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ }
+ //Calculates FFT
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ //Calculates the magnitude^2 values
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = (inSensorDataRe[i] * inSensorDataRe[i]
+ + inSensorDataIm[i] * inSensorDataIm[i]) / ((float)FFT_SIZE);
+ }
+
+ //Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ int32_t maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if (inSensorDataRe[i] > maxValue)
+ {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ //Calculates the signal and noise power (no DC)
+ sig = 0.0f;
+ noise = 0.0f;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if ((i > maxValueIndex - 8) && (i < maxValueIndex + 8))
+ {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else
+ {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+ ctx->debug_maxValueIndex = maxValueIndex;
+ ctx->debug_maxValue = maxValue;
+ ctx->debig_noise = noise;
+ ctx->debug_sig = sig;
+ }
+
+ ReleaseMutex(ctx->m1_data_mutex);
+
+ if (!(sig > 0.0f)) { sig = 0.0000000001f; }
+ if (!(noise > 0.0f)) { noise = 0.0000000001f; }
+
+ if (update_luminosity_calc_result)
+ {
+ ObtainMutex(ctx->m2_result_mutex);
+ if ( TEST_IF_DATA_AVAILABLE_IS_EMPTY(ctx->luminosity_flag_counter) )
+ {
+ update_luminosity_calc_result = false;
+
+ //Calculates SNR
+ ctx->snr_float = sig/noise;
+ DECREMENT_AVAILABLE_DATA(ctx->value_in_watts_flag_counter);
+ INCREMENT_AVAILABLE_DATA(ctx->luminosity_flag_counter);
+ }
+ ReleaseMutex(ctx->m2_result_mutex);
+ }
+ rtems_task_wake_after(1);
+ }
+ SuspendSelf();
+}
+
+// * Task 2 - reads the results
+static void read_and_output(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+ float result;
+
+ // Luminosity threshold to indicate planet, not e.g. star
+ float luminosity_threshold = 0.005;
+
+ while (ctx->iter < MAX_ITER)
+ {
+ ObtainMutex(ctx->m2_result_mutex);
+ if (TEST_IF_DATA_AVAILABLE_IS_NOT_EMPTY(ctx->luminosity_flag_counter))
+ {
+ if (ctx->snr_float > SNR_THRESHOLD)
+ {
+ ctx->planet_locations[ctx->iter] = 1;
+ ctx->planet_count++;
+ }
+ else
+ {
+ ctx->planet_locations[ctx->iter] = 0;
+ }
+ DECREMENT_AVAILABLE_DATA(ctx->luminosity_flag_counter);
+ ctx->iter++;
+ }
+ ReleaseMutex(ctx->m2_result_mutex);
+ rtems_task_wake_after(1);
+ }
+ rtems_event_send(ctx->main_task_id, EVENT_WROTE_DATA);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+
+ char str[ITOA_STR_SIZE];
+ uint32_t start_time, end_time, multi_core_elapsed_time;
+
+ rtems_id scsw_core_id;
+ rtems_id aocs_core_id;
+
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&inSensorDataRe[0], 0, FFT_SIZE);
+ (void) memset(&inSensorDataIm[0], 0, FFT_SIZE);
+
+ // Identify main task for communication between tasks
+ ctx.main_task_id = rtems_task_self();
+ SetSelfPriority( PRIO_NORMAL );
+
+ //Calculates mean of Blackman-Harris terms
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i<FFT_SIZE; i++)
+ {
+ ctx.scaling_fft_factor += blackman_harris( i, FFT_SIZE);
+ }
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor/ ((float) FFT_SIZE);
+
+ // Create the binary semaphores and intialize variables
+ ctx.m1_data_mutex = CreateMutex(rtems_build_name('M', '1', 'M', 'X'));
+ ctx.m2_result_mutex = CreateMutex(rtems_build_name('M', '2', 'M', 'X'));
+
+ ctx.planet_count = 0;
+ memset(&ctx.planet_locations, 0, MAX_ITER);
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ scsw_core_id = IdentifyScheduler(SCHEDULER_A_NAME);
+ aocs_core_id = IdentifyScheduler(SCHEDULER_B_NAME);
+
+ // Setup task for reading data from the sensor
+ calc_task_config.name = rtems_build_name('R', 'E', 'A', 'D');
+ calc_task_config.storage_area = &calc_task_storage[0][0];
+
+ ctx.read_task_id = DoCreateTask(calc_task_config);
+ SetScheduler(ctx.read_task_id, scsw_core_id, PRIO_LOW);
+
+ // Setup task for reading from shared memory location
+ // And calculating the new result in lumens
+ calc_task_config.name = rtems_build_name('C', 'A', 'L', 'C');
+ calc_task_config.storage_area = &calc_task_storage[1][0];
+
+ ctx.calc_task_id = DoCreateTask(calc_task_config);
+ SetScheduler(ctx.calc_task_id, aocs_core_id, PRIO_NORMAL);
+
+ // Setup task for outputting from shared memory location
+ calc_task_config.name = rtems_build_name('O', 'U', 'T', 'P');
+ calc_task_config.storage_area = &calc_task_storage[2][0];
+
+ ctx.write_task_id = DoCreateTask(calc_task_config);
+ SetScheduler(ctx.write_task_id, scsw_core_id, PRIO_HIGH);
+
+ // Start all tasks
+ StartTask(ctx.read_task_id, task_snr_read_sensor_data, &ctx);
+ StartTask(ctx.calc_task_id, task_snr_process_data, &ctx);
+ StartTask(ctx.write_task_id, read_and_output, &ctx);
+
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ // Wait for all tasks to be completed
+ ReceiveAllEvents(EVENT_WROTE_DATA);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ // Output the results
+ print_string("Planet count: ");
+ print_string(itoa(ctx.planet_count, &str[0], 10));
+ print_string("\n");
+ print_string("Planets sensed at sensor positions: ");
+ for (uint8_t i=0; i<MAX_ITER; i++)
+ {
+ if (ctx.planet_locations[i] > 0)
+ {
+ print_string(itoa(i, &str[0], 10));
+ print_string(" ");
+ }
+ }
+
+ multi_core_elapsed_time = end_time - start_time;
+ print_string("\n");
+ print_string("Multicore Elapsed Time - ");
+ print_string(itoa(multi_core_elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ rtems_task_delete(ctx.read_task_id);
+ rtems_task_delete(ctx.calc_task_id);
+ rtems_task_delete(ctx.write_task_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 2
+
+#define CONFIGURE_MAXIMUM_TASKS ( TASK_COUNT + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_EDF_SMP( a );
+RTEMS_SCHEDULER_EDF_SMP( b );
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP(a, SCHEDULER_A_NAME), \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP(b, SCHEDULER_B_NAME)
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
+ RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY)
+
+
+#define CONFIGURE_SCHEDULER_NAME SCHEDULER_A_NAME
+
+#define CONFIGURE_SCHEDULER_PRIORITY
+
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/13_priority_inheritance/priority_inheritance.c b/testsuites/isvv/13_priority_inheritance/priority_inheritance.c
new file mode 100644
index 0000000000..e8b4484744
--- /dev/null
+++ b/testsuites/isvv/13_priority_inheritance/priority_inheritance.c
@@ -0,0 +1,449 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include <string.h>
+
+/**
+ *
+ * @brief Tests Priority Inheritance protocol of semaphores with two configurations:
+ *
+ * 1. Configured WITH Priority Inheritance
+ * One test case which creates a mutex WITH Priority Inheritance configured,
+ * and shows that our high priority task NEVER overruns the time in its critical region
+ *
+ * 2. Configured WITHOUT Priority Inheritance
+ * One test case which creates a mutex WITHOUT Priority Inheritance configured,
+ * and shows that our high priority task will FREQUENTLY overrun the time in its critical region
+ */
+
+// Different periods for our periodic tasks needed for robustness and reliability as
+// Execution is dependant on processor clock speed i.e 250 MHz for gr740 and 80 MHz for gr712rc
+#ifdef gr740
+#define T0_PERIOD 400
+#define T1_PERIOD 200
+#else
+#define T0_PERIOD 600
+#define T1_PERIOD 300
+#endif
+
+#ifdef PRIO_INHERIT
+#define PRIO_PROTOCOL_SWITCH RTEMS_INHERIT_PRIORITY
+#else
+#define PRIO_PROTOCOL_SWITCH RTEMS_NO_INHERIT_PRIORITY
+#endif
+
+#define MAX_ITER (256U)
+#define FFT_SIZE (1024U)
+#define FFT_SIZE_LOG2 (10U)
+#define TC_MAX (16U)
+#define FILTER_REPETITIONS (2U)
+#define SNR_THRESHOLD (1000000.0f)
+
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = {2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U};
+
+const float NOISE_FACTOR[TC_MAX] = {0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f};
+
+static float inSensorDataRe[FFT_SIZE];
+static float inSensorDataIm[FFT_SIZE];
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 1
+#define TASK_COUNT 3
+#define EVENT_FINISHED_PROCESSING RTEMS_EVENT_0
+
+#define T1_TUNE_REPS 50
+#define T2_COARSE_TUNING_REPS 2
+#define T2_FINE_TUNING_REPS 1300
+
+typedef struct
+{
+ rtems_id main_task;
+ rtems_id task_ids[TASK_COUNT];
+ rtems_id period_0_id;
+ rtems_id period_1_id;
+ int64_t t2_max_ticks;
+ uint16_t priority_inversion_occurrences;
+ float m1_data;
+ rtems_id m1_data_mutex;
+ float scaling_fft_factor;
+} test_context;
+
+/* create storage areas for each worker, using task construct forces
+the user to create these manually*/
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+// TASK 0 - (highest priority w.r.t. the other two) - a SC S/W task
+// Checks data after request for recent evidence of solar flare
+static void solar_flare_analysis(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+
+ uint16_t flare_count = 0;
+ uint32_t start_time, end_time, time_in_critical_region;
+
+ ctx->period_0_id = CreateRateMonotonic();
+
+ while (1)
+ {
+ WaitPeriod(ctx->period_0_id, T0_PERIOD);
+
+ // Timer to see how long it takes to enter and exit critical region
+ start_time = rtems_clock_get_ticks_since_boot();
+ ObtainMutex(ctx->m1_data_mutex);
+
+ if (ctx->m1_data >= SNR_THRESHOLD)
+ flare_count++;
+
+ ReleaseMutex(ctx->m1_data_mutex);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ time_in_critical_region = end_time - start_time;
+
+ // If time spent in critical region is greater than bound for T2 then we know priority inversion has occurred
+ if (time_in_critical_region > ctx->t2_max_ticks)
+ ctx->priority_inversion_occurrences++;
+ }
+
+ // Although this periodic task is executed ad infinitum it is good practice to finalize tasks
+ rtems_task_exit();
+}
+
+// Task 1 - (medium priority w.r.t. the other two) - a COMS task
+// A communication task which periodically receives and has to decode a message
+// To simulate this, we are running the lucas-lehmer primality test
+static void decode_communications(rtems_task_argument arg)
+{
+ uint32_t start_time, end_time, elapsed_time;
+ test_context *ctx = (test_context *)arg;
+
+ uint32_t res = 0;
+
+ ctx->period_1_id = CreateRateMonotonic();
+
+ while (1)
+ {
+ WaitPeriod(ctx->period_1_id, T1_PERIOD);
+
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ for (uint16_t i = 0; i < T1_TUNE_REPS; i++)
+ {
+ for (uint8_t p = 2; p < 100; p++)
+ {
+ if (is_prime(p) && is_mersenne_prime(p))
+ {
+ res = p;
+ }
+ }
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+ // If the execution time is greater than the period, and hence implicit deadline, then
+ // this test cannot sufficiently be completed with the resources and parameters must be changed
+ if (elapsed_time >= T1_PERIOD)
+ print_string("[ERROR] Execution time of T1 is greater than period. Please reduce T1_TUNE_REPS \n");
+ }
+
+ (void)res;
+ // Although this periodic task is executed ad infinitum it is good practice to finalize tasks
+ rtems_task_exit();
+}
+
+// Computes the signal-to-noise ratio for our given data at a given position
+static float compute_snr(float scaling_factor, uint32_t iter)
+{
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = 0.4995f * cos_aprox(i * 2.0f * PI * FREQ[iter % TC_MAX] / FS) + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ inSensorDataIm[i] = 0.4995f * sin_aprox(i * 2.0f * PI * FREQ[iter % TC_MAX] / FS) + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ }
+
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = inSensorDataRe[i] * blackman_harris(i, FFT_SIZE) / scaling_factor;
+ inSensorDataIm[i] = inSensorDataIm[i] * blackman_harris(i, FFT_SIZE) / scaling_factor;
+ }
+
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ // Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ int32_t maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if (inSensorDataRe[i] > maxValue)
+ {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ // Calculates the signal and noise power (no DC)
+ float sig = 0.0f;
+ float noise = 0.0f;
+
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if ((i > maxValueIndex - 8) && (i < maxValueIndex + 8))
+ {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else
+ {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+
+ if (!(sig > 0.0f))
+ {
+ sig = 0.0000000001f;
+ }
+ if (!(noise > 0.0f))
+ {
+ noise = 0.0000000001f;
+ }
+
+ return sig / noise;
+}
+
+// Task 2 - (lowest priority w.r.t. the other two) - a SC S/W task
+// Gathers signal data from sensors, computes the signal to noise ratio, then writes to a shared buffer
+static void gather_meteorological_data(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+
+ uint32_t iter = 0;
+
+ while (iter < MAX_ITER)
+ {
+ ObtainMutex(ctx->m1_data_mutex);
+
+ ctx->m1_data = compute_snr(ctx->scaling_fft_factor, iter);
+
+ ReleaseMutex(ctx->m1_data_mutex);
+
+ iter++;
+ }
+
+ print_string("Finished Processing Data \n");
+ SendEvents(ctx->main_task, EVENT_FINISHED_PROCESSING);
+ rtems_task_exit();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+
+ char str[ITOA_STR_SIZE];
+
+ uint32_t t1_start_time, t1_end_time, t1_elapsed_time;
+ uint32_t t2_start_time, t2_end_time, t2_elapsed_time_in_critical_region;
+
+ rtems_status_code sc;
+ sc = rtems_semaphore_create(rtems_build_name('M', '1', 'M', 'X'), 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ PRIO_PROTOCOL_SWITCH,
+ 0, &ctx.m1_data_mutex);
+ ASSERT_SUCCESS(sc);
+
+ // FFT Initialization
+ (void)memset(&inSensorDataRe[0], 0, FFT_SIZE);
+ (void)memset(&inSensorDataIm[0], 0, FFT_SIZE);
+
+ // Calculates mean of Blackman-Harris terms
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ ctx.scaling_fft_factor += blackman_harris(i, FFT_SIZE);
+ }
+
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor / ((float)FFT_SIZE);
+
+ // Find length of time T1 to execute
+ uint32_t res = 0;
+
+ t1_start_time = rtems_clock_get_ticks_since_boot();
+
+ for (uint16_t i = 0; i < T1_TUNE_REPS; i++)
+ {
+ for (uint8_t p = 2; p < 100; p++)
+ {
+ if (is_prime(p) && is_mersenne_prime(p))
+ {
+ res = p;
+ }
+ }
+ }
+
+ t1_end_time = rtems_clock_get_ticks_since_boot();
+ t1_elapsed_time = t1_end_time - t1_start_time;
+
+ print_string("[DEBUG] e(T1) is: ");
+ print_string(itoa(t1_elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ (void)res;
+
+ // Find the amount of time it takes for T2 to complete its critical region on
+ // an empirical basis of the max, for any of our given data, to find the upper bound
+ // that T0 should wait, enabling us to detect priority inversion
+ ctx.t2_max_ticks = -1;
+
+ for (uint8_t i = 0; i < TC_MAX; i++)
+ {
+ t2_start_time = rtems_clock_get_ticks_since_boot();
+
+ ObtainMutex(ctx.m1_data_mutex);
+
+ ctx.m1_data = compute_snr(ctx.scaling_fft_factor, i);
+
+ ReleaseMutex(ctx.m1_data_mutex);
+
+ t2_end_time = rtems_clock_get_ticks_since_boot();
+ t2_elapsed_time_in_critical_region = t2_end_time - t2_start_time;
+
+ ctx.t2_max_ticks = MAX(ctx.t2_max_ticks, t2_elapsed_time_in_critical_region);
+ }
+
+ print_string("[DEBUG] MAX eCR(T2) is: ");
+ print_string(itoa(ctx.t2_max_ticks, &str[0], 10));
+ print_string("\n");
+
+ // Build up our task configs
+ rtems_task_config configs[TASK_COUNT];
+ for (uint8_t i = 0; i < TASK_COUNT; i++)
+ {
+ configs[i] = (rtems_task_config){
+ .name = rtems_build_name('T', 'S', 'K', (char)i),
+ .storage_size = TASK_STORAGE_SIZE,
+ .storage_area = &task_storage[i][0],
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = RTEMS_FLOATING_POINT};
+ }
+
+ // Initialize relevant test variables
+ ctx.main_task = rtems_task_self();
+ ctx.priority_inversion_occurrences = 0;
+ ctx.period_0_id = INVALID_ID;
+ ctx.period_1_id = INVALID_ID;
+
+ // Explicitly set the priorities of our tasks
+ configs[2].initial_priority = PRIO_VERY_LOW;
+ ctx.task_ids[2] = DoCreateTask(configs[2]);
+
+ configs[1].initial_priority = PRIO_NORMAL;
+ ctx.task_ids[1] = DoCreateTask(configs[1]);
+
+ configs[0].initial_priority = PRIO_VERY_HIGH;
+ ctx.task_ids[0] = DoCreateTask(configs[0]);
+
+ // Start Tasks
+ StartTask(ctx.task_ids[2], gather_meteorological_data, &ctx);
+ StartTask(ctx.task_ids[1], decode_communications, &ctx);
+ StartTask(ctx.task_ids[0], solar_flare_analysis, &ctx);
+
+ // Blocking wait for relevant event until T2 is finished
+ ReceiveAllEvents(EVENT_FINISHED_PROCESSING);
+
+ print_string("Total Priority Inversion occurrences: ");
+ print_string(itoa(ctx.priority_inversion_occurrences, &str[0], 10));
+ print_string("\n");
+
+ rtems_rate_monotonic_delete(ctx.period_0_id);
+ rtems_rate_monotonic_delete(ctx.period_1_id);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_TASKS (TASK_COUNT + 1)
+
+#define CONFIGURE_MAXIMUM_PERIODS 2
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/14_immediate_ceiling_protocol/immediate_ceiling.c b/testsuites/isvv/14_immediate_ceiling_protocol/immediate_ceiling.c
new file mode 100644
index 0000000000..a33b131c06
--- /dev/null
+++ b/testsuites/isvv/14_immediate_ceiling_protocol/immediate_ceiling.c
@@ -0,0 +1,468 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include <string.h>
+
+/**
+ *
+ * @brief Tests ICPP of semaphores with two configurations:
+ *
+ * 1. Configured WITH ICPP
+ * One test case which creates a mutex WITH the priority ceiling configured,
+ * and shows that our high priority task NEVER overruns the time in its critical region
+ *
+ * 2. Configured WITHOUT ICPP
+ * One test case which creates a mutex WITHOUT the priority ceiling configured,
+ * and shows that our high priority task will FREQUENTLY overrun the time in its critical region
+ */
+
+// Different periods for our periodic tasks needed for robustness and reliability as
+// Execution is dependant on processor clock speed i.e 250 MHz for gr740 and 80 MHz for gr712rc
+#ifdef gr740
+#define T0_PERIOD 400
+#define T1_PERIOD 200
+#else
+#define T0_PERIOD 600
+#define T1_PERIOD 300
+#endif
+
+#ifdef PRIO_CEILING
+#define PRIO_PROTOCOL_SWITCH RTEMS_PRIORITY_CEILING
+#else
+#define PRIO_PROTOCOL_SWITCH RTEMS_NO_PRIORITY_CEILING
+#endif
+
+#define MAX_ITER (256U)
+#define FFT_SIZE (1024U)
+#define FFT_SIZE_LOG2 (10U)
+#define TC_MAX (16U)
+#define FILTER_REPETITIONS (2U)
+#define SNR_THRESHOLD (1000000.0f)
+
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = {2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U};
+
+const float NOISE_FACTOR[TC_MAX] = {0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f};
+
+static float inSensorDataRe[FFT_SIZE];
+static float inSensorDataIm[FFT_SIZE];
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 1
+#define TASK_COUNT 3
+#define EVENT_FINISHED_PROCESSING RTEMS_EVENT_0
+
+#define T1_TUNE_REPS 50
+#define T2_COARSE_TUNING_REPS 2
+#define T2_FINE_TUNING_REPS 1300
+
+typedef struct
+{
+ rtems_id main_task;
+ rtems_id task_ids[TASK_COUNT];
+ rtems_id period_0_id;
+ rtems_id period_1_id;
+ int64_t t2_max_ticks;
+ uint16_t priority_inversion_occurrences;
+ float m1_data;
+ rtems_id m1_data_mutex;
+ float scaling_fft_factor;
+} test_context;
+
+/* create storage areas for each worker, using task construct forces
+the user to create these manually*/
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+// TASK 0 - (highest priority w.r.t. the other two) - a SC S/W task
+// Checks data after request for recent evidence of solar flare
+static void solar_flare_analysis(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+
+ uint16_t flare_count = 0;
+ uint32_t start_time, end_time, time_in_critical_region;
+
+ ctx->period_0_id = CreateRateMonotonic();
+
+ while (1)
+ {
+ WaitPeriod(ctx->period_0_id, T0_PERIOD);
+
+ // Timer to see how long it takes to enter and exit critical region
+ start_time = rtems_clock_get_ticks_since_boot();
+ ObtainMutex(ctx->m1_data_mutex);
+
+ if (ctx->m1_data >= SNR_THRESHOLD)
+ flare_count++;
+
+ ReleaseMutex(ctx->m1_data_mutex);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ time_in_critical_region = end_time - start_time;
+
+ // If time spent in critical region is greater than bound for T2 then we know priority inversion has occurred
+ if (time_in_critical_region > ctx->t2_max_ticks)
+ ctx->priority_inversion_occurrences++;
+ }
+
+ // Although this periodic task is executed ad infinitum it is good practice to finalize tasks
+ rtems_task_exit();
+}
+
+// Task 1 - (medium priority w.r.t. the other two) - a COMS task
+// A communication task which periodically receives and has to decode a message
+// To simulate this, we are running the lucas-lehmer primality test
+static void decode_communications(rtems_task_argument arg)
+{
+ uint32_t start_time, end_time, elapsed_time;
+ test_context *ctx = (test_context *)arg;
+
+ uint32_t res = 0;
+
+ ctx->period_1_id = CreateRateMonotonic();
+
+ while (1)
+ {
+ WaitPeriod(ctx->period_1_id, T1_PERIOD);
+
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ for (uint16_t i = 0; i < T1_TUNE_REPS; i++)
+ {
+ for (uint8_t p = 2; p < 100; p++)
+ {
+ if (is_prime(p) && is_mersenne_prime(p))
+ {
+ res = p;
+ }
+ }
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+ // If the execution time is greater than the period, and hence implicit deadline, then
+ // this test cannot sufficiently be completed with the resources and parameters must be changed
+ if (elapsed_time >= T1_PERIOD)
+ print_string("[ERROR] Execution time of T1 is greater than period. Please reduce T1_TUNE_REPS \n");
+ }
+
+ (void)res;
+ // Although this periodic task is executed ad infinitum it is good practice to finalize tasks
+ rtems_task_exit();
+}
+
+// Computes the signal-to-noise ratio for our given data at a given position
+static float compute_snr(float scaling_factor, uint32_t iter)
+{
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ inSensorDataRe[i] = 0.4995f * cos_aprox(i * 2.0f * PI * FREQ[iter % TC_MAX] / FS) + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ inSensorDataIm[i] = 0.4995f * sin_aprox(i * 2.0f * PI * FREQ[iter % TC_MAX] / FS) + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ }
+
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ // Real & Imaginary
+ inSensorDataRe[i] = inSensorDataRe[i] * blackman_harris(i, FFT_SIZE) / scaling_factor;
+ inSensorDataIm[i] = inSensorDataIm[i] * blackman_harris(i, FFT_SIZE) / scaling_factor;
+ }
+
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ // Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ int32_t maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if (inSensorDataRe[i] > maxValue)
+ {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ // Calculates the signal and noise power (no DC)
+ float sig = 0.0f;
+ float noise = 0.0f;
+
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++)
+ {
+ if ((i > maxValueIndex - 8) && (i < maxValueIndex + 8))
+ {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else
+ {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+
+ if (!(sig > 0.0f))
+ {
+ sig = 0.0000000001f;
+ }
+ if (!(noise > 0.0f))
+ {
+ noise = 0.0000000001f;
+ }
+
+ return sig / noise;
+}
+
+// Task 2 - (lowest priority w.r.t. the other two) - a SC S/W task
+// Gathers signal data from sensors, computes the signal to noise ratio, then writes to a shared buffer
+static void gather_meteorological_data(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+
+ uint32_t iter = 0;
+
+ while (iter < MAX_ITER)
+ {
+ ObtainMutex(ctx->m1_data_mutex);
+
+ ctx->m1_data = compute_snr(ctx->scaling_fft_factor, iter);
+
+ ReleaseMutex(ctx->m1_data_mutex);
+
+ iter++;
+ }
+
+ print_string("Finished Processing Data \n");
+ SendEvents(ctx->main_task, EVENT_FINISHED_PROCESSING);
+ rtems_task_exit();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+
+ char str[ITOA_STR_SIZE];
+
+ uint32_t t1_start_time, t1_end_time, t1_elapsed_time;
+ uint32_t t2_start_time, t2_end_time, t2_elapsed_time_in_critical_region;
+
+ // With the ICPP we set the ceiling priority to the highest priority of any task that may hold it,
+ // In this case it should be T0 with priority PRIO_VERY_HIGH.
+ rtems_status_code sc;
+ sc = rtems_semaphore_create(rtems_build_name('M', '1', 'M', 'X'), 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ PRIO_PROTOCOL_SWITCH,
+ PRIO_VERY_HIGH, &ctx.m1_data_mutex);
+ ASSERT_SUCCESS(sc);
+
+ /*
+ * Due to the logic of the ICPP, and the fact that the Init task automatically has a priority
+ * of 1 (PRIO_VERY_ULTRA_HIGH, the highest possible for any user defined task) we must either decrease
+ * the priority of the Init task or increase the priority of the ceiling to be equal to the Init task,
+ * and configure the priorities of our defined tasks (T0, T1, T2)
+ *
+ * For consistency, we will keep our defined tasks with the same priority as in Test Case 13 and reduce the priority
+ * of the Init task, which only needs to acquire the semaphore to find the time T2 spends in its critical region
+ *
+ * See (https://docs.rtems.org/branches/master/c-user/key_concepts.html#immediate-ceiling-priority-protocol-icpp)
+ */
+
+ rtems_task_priority task_prio;
+ sc = rtems_task_set_priority(RTEMS_SELF, PRIO_VERY_HIGH, &task_prio);
+ ASSERT_SUCCESS(sc);
+
+ // FFT Initialization
+ (void)memset(&inSensorDataRe[0], 0, FFT_SIZE);
+ (void)memset(&inSensorDataIm[0], 0, FFT_SIZE);
+
+ // Calculates mean of Blackman-Harris terms
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i < FFT_SIZE; i++)
+ {
+ ctx.scaling_fft_factor += blackman_harris(i, FFT_SIZE);
+ }
+
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor / ((float)FFT_SIZE);
+
+ // Find length of time T1 takes to execute
+ uint32_t res = 0;
+
+ t1_start_time = rtems_clock_get_ticks_since_boot();
+
+ for (uint16_t i = 0; i < T1_TUNE_REPS; i++)
+ {
+ for (uint8_t p = 2; p < 100; p++)
+ {
+ if (is_prime(p) && is_mersenne_prime(p))
+ {
+ res = p;
+ }
+ }
+ }
+
+ t1_end_time = rtems_clock_get_ticks_since_boot();
+ t1_elapsed_time = t1_end_time - t1_start_time;
+
+ print_string("[DEBUG] e(T1) is: ");
+ print_string(itoa(t1_elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ (void)res;
+
+ // Find the amount of time it takes for T2 to complete its critical region on
+ // an empirical basis of the max, for any of our given data, to find the upper bound
+ // that T0 should wait, enabling us to detect priority inversion
+ ctx.t2_max_ticks = -1;
+
+ for (uint8_t i = 0; i < TC_MAX; i++)
+ {
+ t2_start_time = rtems_clock_get_ticks_since_boot();
+
+ ObtainMutex(ctx.m1_data_mutex);
+
+ ctx.m1_data = compute_snr(ctx.scaling_fft_factor, i);
+
+ ReleaseMutex(ctx.m1_data_mutex);
+
+ t2_end_time = rtems_clock_get_ticks_since_boot();
+ t2_elapsed_time_in_critical_region = t2_end_time - t2_start_time;
+
+ ctx.t2_max_ticks = MAX(ctx.t2_max_ticks, t2_elapsed_time_in_critical_region);
+ }
+
+ print_string("[DEBUG] MAX eCR(T2) is: ");
+ print_string(itoa(ctx.t2_max_ticks, &str[0], 10));
+ print_string("\n");
+
+ // Build up our task configs
+ rtems_task_config configs[TASK_COUNT];
+ for (uint8_t i = 0; i < TASK_COUNT; i++)
+ {
+ configs[i] = (rtems_task_config){
+ .name = rtems_build_name('T', 'S', 'K', (char)i),
+ .storage_size = TASK_STORAGE_SIZE,
+ .storage_area = &task_storage[i][0],
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = RTEMS_FLOATING_POINT};
+ }
+
+ // Initialize relevant test variables
+ ctx.main_task = rtems_task_self();
+ ctx.priority_inversion_occurrences = 0;
+ ctx.period_0_id = INVALID_ID;
+ ctx.period_1_id = INVALID_ID;
+
+ // Explicitly set the priorities of our tasks
+ configs[2].initial_priority = PRIO_VERY_LOW;
+ ctx.task_ids[2] = DoCreateTask(configs[2]);
+
+ configs[1].initial_priority = PRIO_NORMAL;
+ ctx.task_ids[1] = DoCreateTask(configs[1]);
+
+ configs[0].initial_priority = PRIO_VERY_HIGH;
+ ctx.task_ids[0] = DoCreateTask(configs[0]);
+
+ // Start Tasks
+ StartTask(ctx.task_ids[2], gather_meteorological_data, &ctx);
+ StartTask(ctx.task_ids[1], decode_communications, &ctx);
+ StartTask(ctx.task_ids[0], solar_flare_analysis, &ctx);
+
+ // Blocking wait for relevant event until T2 is finished
+ ReceiveAllEvents(EVENT_FINISHED_PROCESSING);
+
+ print_string("Total Priority Inversion occurrences: ");
+ print_string(itoa(ctx.priority_inversion_occurrences, &str[0], 10));
+ print_string("\n");
+
+ rtems_rate_monotonic_delete(ctx.period_0_id);
+ rtems_rate_monotonic_delete(ctx.period_1_id);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_TASKS (TASK_COUNT + 1)
+
+#define CONFIGURE_MAXIMUM_PERIODS 2
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/15_clock_manager_undefined_behaviour/clock_manager_undefined_behaviour.c b/testsuites/isvv/15_clock_manager_undefined_behaviour/clock_manager_undefined_behaviour.c
new file mode 100644
index 0000000000..bb69f1b8b2
--- /dev/null
+++ b/testsuites/isvv/15_clock_manager_undefined_behaviour/clock_manager_undefined_behaviour.c
@@ -0,0 +1,579 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include <string.h>
+
+/**
+ *
+ * @brief Tests impact of undefined behaviours
+ *
+ * This test case performs the calculation of the Mandelbrot set in parallel with
+ * execution of various clock-related functions
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+// test specific global vars
+#define TASK_COUNT (TEST_PROCESSORS - 1)
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+// 1 (microsecond) is equal to (2^64 - 1)*10^-6 (64 bit fraction seconds).
+// Using 7 significant figures (enough to preserve microsecond precision) this is 18446740000000.
+#define FRAC_BINTIME_TO_USEC_CONV_FACTOR 18446740000000LLU
+
+#define NUM_TEST_FUNCTIONS 15
+#define RELATIVE_SLEEP 0
+#define FUNCTION_WAIT_MICROSECONDS 100
+#define FUNCTION_WAIT_NANOSECONDS (FUNCTION_WAIT_MICROSECONDS * 1000)
+// Acceptable difference returned by subsequent clock-related function call
+#define MARGIN_USEC 8
+
+static rtems_id start_barrier;
+static rtems_id TASK_COUNTER_SEMAPHORE;
+
+typedef struct timespec timespec_t;
+typedef struct bintime bintime_t;
+typedef struct timeval timeval_t;
+
+typedef enum
+{
+ TIMESPEC,
+ BINTIME,
+ TIMEVAL
+} struct_type;
+
+// Create storage areas for each worker, using task construct forces
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+/* debug
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_processor[TASK_COUNT];
+*/
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_before_mandelbrot[TASK_COUNT];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_after_mandelbrot[TASK_COUNT];
+
+/*
+ * Find whether later time struct is within margin_usec of same type time struct earlier.
+ */
+static bool close_in_time(void *earlier, void *later, uint32_t margin_usec, struct_type type)
+{
+ bool ret = false;
+ uint64_t earlier_total, later_total;
+
+ /*
+ char str[ITOA_STR_SIZE];
+ */
+
+ switch(type)
+ {
+ case TIMESPEC:
+ earlier_total = (uint64_t)(((timespec_t *)earlier)->tv_sec * 1000000 + ((timespec_t *)earlier)->tv_nsec / 1000);
+ later_total = (uint64_t)(((timespec_t *)later)->tv_sec * 1000000 + ((timespec_t *)later)->tv_nsec / 1000);
+ /* debug
+ print_string("timespec earlier: ");
+ print_string(itoa((int)earlier_total, &str[0], 10));
+ print_string("\n");
+ print_string("timespec later: ");
+ print_string(itoa((int)later_total, &str[0], 10));
+ print_string("\n");
+ */
+ break;
+ case BINTIME:
+ earlier_total = (uint64_t)(((bintime_t *)earlier)->sec * 1000000 + ((bintime_t *)earlier)->frac / FRAC_BINTIME_TO_USEC_CONV_FACTOR);
+ later_total = (uint64_t)(((bintime_t *)later)->sec * 1000000 + ((bintime_t *)later)->frac / FRAC_BINTIME_TO_USEC_CONV_FACTOR);
+ /* debug
+ print_string("bintime earlier: ");
+ print_string(itoa((int)earlier_total, &str[0], 10));
+ print_string("\n");
+ print_string("bintime later: ");
+ print_string(itoa((int)later_total, &str[0], 10));
+ print_string("\n");
+ */
+ break;
+ case TIMEVAL:
+ earlier_total = (uint64_t)(((timeval_t *)earlier)->tv_sec * 1000000 + ((timeval_t *)earlier)->tv_usec);
+ later_total = (uint64_t)(((timeval_t *)later)->tv_sec * 1000000 + ((timeval_t *)later)->tv_usec);
+ /* debug
+ print_string("timeval earlier: ");
+ print_string(itoa((int)earlier_total, &str[0], 10));
+ print_string("\n");
+ print_string("timeval later: ");
+ print_string(itoa((int)later_total, &str[0], 10));
+ print_string("\n");
+ */
+ break;
+ default:
+ return ret;
+ }
+
+ if(earlier_total + margin_usec >= later_total)
+ ret = true;
+
+ return ret;
+}
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ uint8_t tile = (uint8_t) arg;
+ struct timespec uptime;
+
+ WaitAtBarrier(start_barrier);
+
+ rtems_clock_get_uptime(&uptime);
+ task_before_mandelbrot[tile - 1] = (uint32_t) (uptime.tv_sec * 1000000 + uptime.tv_nsec/1000);
+
+ mandelbrot_tile(tile, TASK_COUNT);
+
+ rtems_clock_get_uptime(&uptime);
+ task_after_mandelbrot[tile - 1] = (uint32_t) (uptime.tv_sec * 1000000 + uptime.tv_nsec/1000);
+
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ /* debug
+ uint32_t main_task_processor;
+ */
+ uint32_t functions_start, functions_end;
+ rtems_id task_id[TASK_COUNT];
+ char ch;
+ /* debug
+ str[ITOA_STR_SIZE];
+ */
+ struct timespec uptime, function_wait;
+ uint8_t wait = 0;
+ uint8_t unaffected[NUM_TEST_FUNCTIONS];
+
+ function_wait.tv_sec = 0;
+ function_wait.tv_nsec = FUNCTION_WAIT_NANOSECONDS;
+ memset(&unaffected, 0, NUM_TEST_FUNCTIONS);
+
+ TASK_COUNTER_SEMAPHORE = CreateCounterSemaphore(rtems_build_name('T', 'C', 'S', '0'), 0);
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_VERY_HIGH,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ start_barrier = CreateAutomaticBarrier(TASK_COUNT + 1);
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ ch = '0' + i;
+
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(task_id[i], calc_task_function, (void *)(i + 1));
+ }
+
+ /*
+ * Start execution of clock functions following formula of:
+ * Defined behaviour
+ * Undefined behaviour
+ * Defined behaviour
+ */
+
+ timespec_t ts_first, ts_third;
+ timespec_t *ts_null = NULL;
+
+ bintime_t bt_first, bt_third;
+ bintime_t *bt_null = NULL;
+
+ timeval_t tv_first, tv_third;
+ timeval_t *tv_null = NULL;
+
+ WaitAtBarrier(start_barrier);
+
+ /* debug
+ main_task_processor = rtems_scheduler_get_processor();
+ */
+
+ // Wait FUNCTION_WAIT_MICROSECONDS microseconds to ensure function calls are concurrent with mandelbrot calculation
+ clock_nanosleep(CLOCK_MONOTONIC, RELATIVE_SLEEP, &function_wait, NULL);
+
+ rtems_clock_get_uptime(&uptime);
+ functions_start = (uint32_t) (uptime.tv_sec* 1000000 + uptime.tv_nsec/1000);
+
+ /*
+ * Check that BOOT_TIME subsequent call is not affected by undefined call.
+ * Boot time should not change so if the third call does not match the first
+ * an error has been found.
+ */
+ rtems_clock_get_boot_time(&ts_first);
+ rtems_clock_get_boot_time_bintime(&bt_first);
+ rtems_clock_get_boot_time_timeval(&tv_first);
+
+ rtems_clock_get_boot_time(ts_null);
+ rtems_clock_get_boot_time(&ts_third);
+ if ((ts_third.tv_sec == ts_first.tv_sec) && (ts_third.tv_nsec == ts_first.tv_nsec))
+ unaffected[0] = true;
+
+ rtems_clock_get_boot_time_bintime(bt_null);
+ rtems_clock_get_boot_time_bintime(&bt_third);
+ if ((bt_third.sec == bt_first.sec) && (bt_third.frac == bt_first.frac))
+ unaffected[1] = true;
+
+ rtems_clock_get_boot_time_timeval(tv_null);
+ rtems_clock_get_boot_time_timeval(&tv_third);
+ if ((tv_third.tv_sec == tv_first.tv_sec) && (tv_third.tv_usec == tv_first.tv_usec))
+ unaffected[2] = true;
+
+ /*
+ * Check that CLOCK_MONOTONIC subsequent call is not affected by undefined call.
+ * If third call is not close in time to the first call an error has been found.
+ */
+ rtems_clock_get_monotonic(&ts_first);
+ rtems_clock_get_monotonic(ts_null);
+ rtems_clock_get_monotonic(&ts_third);
+ if(close_in_time(&ts_first, &ts_third, MARGIN_USEC, TIMESPEC))
+ unaffected[3] = true;
+
+ /* debug
+ print_string("clock_get_monotonic ts first tv_sec: ");
+ print_string(itoa(ts_first.tv_sec, &str[0], 10));
+ print_string("\n");
+ print_string("clock_get_monotonic ts first tv_nsec: ");
+ print_string(itoa(ts_first.tv_nsec, &str[0], 10));
+ print_string("\n");
+ print_string("clock_get_monotonic ts third tv_sec: ");
+ print_string(itoa(ts_third.tv_sec, &str[0], 10));
+ print_string("\n");
+ print_string("clock_get_monotonic ts third tv_nsec: ");
+ print_string(itoa(ts_third.tv_nsec, &str[0], 10));
+ print_string("\n");
+ */
+
+ rtems_clock_get_monotonic_bintime(&bt_first);
+ rtems_clock_get_monotonic_bintime(bt_null);
+ rtems_clock_get_monotonic_bintime(&bt_third);
+ if(close_in_time(&bt_first, &bt_third, MARGIN_USEC, BINTIME))
+ unaffected[4] = true;
+
+ /* debug
+ print_string("clock_get_monotonic bt first sec: ");
+ print_string(itoa(bt_first.sec, &str[0], 10));
+ print_string("\n");
+ print_string("clock_get_monotonic bt first frac: ");
+ print_string(itoa(bt_first.frac, &str[0], 10));
+ print_string("\n");
+ print_string("clock_get_monotonic bt third sec: ");
+ print_string(itoa(bt_third.sec, &str[0], 10));
+ print_string("\n");
+ print_string("clock_get_monotonic bt third frac: ");
+ print_string(itoa(bt_third.frac, &str[0], 10));
+ print_string("\n");
+ */
+
+ rtems_clock_get_monotonic_timeval(&tv_first);
+ rtems_clock_get_monotonic_timeval(tv_null);
+ rtems_clock_get_monotonic_timeval(&tv_third);
+ if(close_in_time(&tv_first, &tv_third, MARGIN_USEC, TIMEVAL))
+ unaffected[5] = true;
+
+ /* debug
+ print_string("clock_get_monotonic tv first tv_sec: ");
+ print_string(itoa(tv_first.tv_sec, &str[0], 10));
+ print_string("\n");
+ print_string("clock_get_monotonic tv first tv_nsec: ");
+ print_string(itoa(tv_first.tv_usec, &str[0], 10));
+ print_string("\n");
+ print_string("clock_get_monotonic tv third tv_sec: ");
+ print_string(itoa(tv_third.tv_sec, &str[0], 10));
+ print_string("\n");
+ print_string("clock_get_monotonic tv third tv_nsec: ");
+ print_string(itoa(tv_third.tv_usec, &str[0], 10));
+ print_string("\n");
+ */
+
+ /*
+ * Check that coarse CLOCK_MONOTONIC subsequent call is not affected by undefined call.
+ * If third call is not close in time to the first call an error has been found.
+ */
+ rtems_clock_get_monotonic_coarse(&ts_first);
+ rtems_clock_get_monotonic_coarse(ts_null);
+ rtems_clock_get_monotonic_coarse(&ts_third);
+ if(close_in_time(&ts_first, &ts_third, MARGIN_USEC, TIMESPEC))
+ unaffected[6] = true;
+
+ rtems_clock_get_monotonic_coarse_bintime(&bt_first);
+ rtems_clock_get_monotonic_coarse_bintime(bt_null);
+ rtems_clock_get_monotonic_coarse_bintime(&bt_third);
+ if(close_in_time(&bt_first, &bt_third, MARGIN_USEC, BINTIME))
+ unaffected[7] = true;
+
+ rtems_clock_get_monotonic_coarse_timeval(&tv_first);
+ rtems_clock_get_monotonic_coarse_timeval(tv_null);
+ rtems_clock_get_monotonic_coarse_timeval(&tv_third);
+ if(close_in_time(&tv_first, &tv_third, MARGIN_USEC, TIMEVAL))
+ unaffected[8] = true;
+
+ /*
+ * Check that CLOCK_REALTIME subsequent call is not affected by undefined call.
+ * If third call is not close in time to the first call an error has been found.
+ */
+ rtems_clock_get_realtime(&ts_first);
+ rtems_clock_get_realtime(ts_null);
+ rtems_clock_get_realtime(&ts_third);
+ if(close_in_time(&ts_first, &ts_third, MARGIN_USEC, TIMESPEC))
+ unaffected[9] = true;
+
+ rtems_clock_get_realtime_bintime(&bt_first);
+ rtems_clock_get_realtime_bintime(bt_null);
+ rtems_clock_get_realtime_bintime(&bt_third);
+ if(close_in_time(&bt_first, &bt_third, MARGIN_USEC, BINTIME))
+ unaffected[10] = true;
+
+ rtems_clock_get_realtime_timeval(&tv_first);
+ rtems_clock_get_realtime_timeval(tv_null);
+ rtems_clock_get_realtime_timeval(&tv_third);
+ if(close_in_time(&tv_first, &tv_third, MARGIN_USEC, TIMEVAL))
+ unaffected[11] = true;
+
+ /*
+ * Check that coarse CLOCK_REALTIME subsequent call is not affected by undefined call.
+ * If third call is not close in time to the first call an error has been found.
+ */
+ rtems_clock_get_realtime_coarse(&ts_first);
+ rtems_clock_get_realtime_coarse(ts_null);
+ rtems_clock_get_realtime_coarse(&ts_third);
+ if(close_in_time(&ts_first, &ts_third, MARGIN_USEC, TIMESPEC))
+ unaffected[12] = true;
+
+ rtems_clock_get_realtime_coarse_bintime(&bt_first);
+ rtems_clock_get_realtime_coarse_bintime(bt_null);
+ rtems_clock_get_realtime_coarse_bintime(&bt_third);
+ if(close_in_time(&bt_first, &bt_third, MARGIN_USEC, BINTIME))
+ unaffected[13] = true;
+
+ rtems_clock_get_realtime_coarse_timeval(&tv_first);
+ rtems_clock_get_realtime_coarse_timeval(tv_null);
+ rtems_clock_get_realtime_coarse_timeval(&tv_third);
+ if(close_in_time(&tv_first, &tv_third, MARGIN_USEC, TIMEVAL))
+ unaffected[14] = true;
+
+ rtems_clock_get_uptime(&uptime);
+ functions_end = (uint32_t) (uptime.tv_sec* 1000000 + uptime.tv_nsec/1000) ;
+
+ // Wait for all tasks to complete
+ while (wait < TASK_COUNT)
+ {
+ ObtainCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ wait++;
+ }
+
+ // Ensure clock-based functions were executed at the same time as the mandlebrot set
+ uint32_t latest_task_start = 0;
+ uint32_t earliest_task_finish = -1;
+
+ for(uint32_t task = 0; task < TASK_COUNT; task++)
+ {
+ if(task_before_mandelbrot[task] > latest_task_start)
+ latest_task_start = task_before_mandelbrot[task];
+
+ if(task_after_mandelbrot[task] < earliest_task_finish)
+ earliest_task_finish = task_after_mandelbrot[task];
+ }
+
+ if(functions_start > latest_task_start && functions_end < earliest_task_finish)
+ {
+ print_string("Functions and mandelbrot executed concurrently: true\n\n");
+ }
+ else
+ {
+ print_string("Functions and mandelbrot executed concurrently: false\n\n");
+ }
+
+ if(unaffected[0] && unaffected[1] && unaffected[2])
+ {
+ print_string("Boot time subsequent call unaffected: true\n");
+ }
+ else
+ {
+ print_string("Boot time subsequent call unaffected: false\n");
+ }
+
+ if(unaffected[3] && unaffected[4] && unaffected[5])
+ {
+ print_string("Clock monotonic subsequent call unaffected: true\n");
+ }
+ else
+ {
+ print_string("Clock monotonic subsequent call unaffected: false\n");
+ }
+
+ if(unaffected[6] && unaffected[7] && unaffected[8])
+ {
+ print_string("Coarse clock monotonic subsequent call unaffected: true\n");
+ }
+ else
+ {
+ print_string("Coarse clock monotonic subsequent call unaffected: false\n");
+ }
+
+ if(unaffected[9] && unaffected[10] && unaffected[11])
+ {
+ print_string("Clock realtime subsequent call unaffected: true\n");
+ }
+ else
+ {
+ print_string("Clock realtime subsequent call unaffected: false\n");
+ }
+
+ if(unaffected[12] && unaffected[13] && unaffected[14])
+ {
+ print_string("Coarse clock realtime subsequent call unaffected: true\n");
+ }
+ else
+ {
+ print_string("Coarse clock realtime subsequent call unaffected: false\n");
+ }
+
+ print_test_results();
+ /* debug
+ print_string("Functions processor: ");
+ print_string(itoa(main_task_processor, &str[0], 10));
+ print_string("\n");
+ print_string("Functions start time: ");
+ print_string(itoa(functions_start, &str[0], 10));
+ print_string("\n");
+// --------------------------------------------------------------------------------------------
+ print_string("\n\n\n");
+ print_string("CheckPoints:");
+ print_string("\n|TILE |PROC | START | END |TIME SPENT| (us)");
+ print_string("\n");
+ for (uint32_t task = 0; task < TASK_COUNT; task++)
+ {
+ print_string("| ");
+ print_string(itoa(task+1, &str[0], 10));
+ print_string(" | ");
+ print_string(itoa(task_processor[task], &str[0], 10));
+ print_string(" | ");
+ print_string(itoa(task_before_mandelbrot[task], &str[0], 10));
+ print_string(" | ");
+ print_string(itoa(task_after_mandelbrot[task], &str[0], 10));
+ print_string(" | ");
+ print_string(itoa(task_after_mandelbrot[task]-task_before_mandelbrot[task], &str[0], 10));
+ print_string(" |\n");
+ }
+ print_string("\n\nTICKS Per second: ");
+ print_string(itoa(rtems_clock_get_ticks_per_second(), &str[0], 10));
+ print_string("\n\n");
+// --------------------------------------------------------------------------------------------
+ print_string("Functions end time: ");
+ print_string(itoa(functions_end, &str[0], 10));
+ print_string("\n");
+
+ for(uint8_t i = 0; i < NUM_TEST_FUNCTIONS; i++)
+ {
+ print_string("unaffected ");
+ print_string(itoa(i, &str[0], 10));
+ print_string(": ");
+ print_string(itoa(unaffected[i], &str[0], 10));
+ print_string("\n");
+ }
+ */
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++)
+ {
+ DeleteTask(task_id[i]);
+ }
+
+ DeleteMutex(TASK_COUNTER_SEMAPHORE);
+ DeleteBarrier(start_barrier);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/16_task_manager_undefined_behaviour/task_manager_undefined_behaviour.c b/testsuites/isvv/16_task_manager_undefined_behaviour/task_manager_undefined_behaviour.c
new file mode 100644
index 0000000000..1a7cc4f928
--- /dev/null
+++ b/testsuites/isvv/16_task_manager_undefined_behaviour/task_manager_undefined_behaviour.c
@@ -0,0 +1,468 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+
+/**
+ *
+ * @brief Tests impact of undefined behaviour for task manager
+ *
+ * This test case performs the calculation of the Mandelbrot set in parallel with
+ * execution of task related functions with conditions which may lead to
+ * undefined behaviour, and seeks to clarify the impact of them.
+ *
+ */
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+// We want to create mandelbrot executions whilst our task manager functions
+// are executed on another core
+#define TASK_COUNT TEST_PROCESSORS
+#define CALCULATION_TASKS ((TASK_COUNT) - 1)
+
+// Timing related variables to ensure concurrent executions
+#define RELATIVE_SLEEP 0
+#define FUNCTION_WAIT_MICROSECONDS 10
+#define FUNCTION_WAIT_NANOSECONDS (FUNCTION_WAIT_MICROSECONDS * 1000)
+
+static rtems_id start_barrier;
+static rtems_id TASK_COUNTER_SEMAPHORE;
+
+typedef struct
+{
+ rtems_id calc_task_id[CALCULATION_TASKS];
+ rtems_id undefined_task_id;
+ uint32_t functions_start, functions_end;
+ bool expected_timeslice_calls;
+ bool expected_ASR_calls;
+ bool expected_preempt_calls;
+ bool expected_interrupt_calls;
+ bool expected_combination_calls;
+ bool preempt_not_impl;
+ bool interrupts_not_impl;
+} test_context;
+
+// Create storage areas for each worker, using task construct forces
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+// Storage space for timings
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_before_mandelbrot[CALCULATION_TASKS];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_after_mandelbrot[CALCULATION_TASKS];
+
+static void calc_task_function(rtems_task_argument *tile)
+{
+ uint8_t tile_n = (uint8_t) *tile;
+ struct timespec uptime;
+
+ WaitAtBarrier(start_barrier);
+
+ // Check time function begins execution of mandelbrot executions
+ rtems_clock_get_uptime(&uptime);
+ task_before_mandelbrot[tile_n - 1] = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ mandelbrot_tile(tile_n, CALCULATION_TASKS);
+
+ // Check time function finishes execution of mandelbrot executions
+ rtems_clock_get_uptime(&uptime);
+ task_after_mandelbrot[tile_n - 1] = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ rtems_task_exit();
+}
+
+static void undefined_behaviour_task(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+ struct timespec uptime, function_wait;
+
+ WaitAtBarrier(start_barrier);
+
+ // Wait for 10us to ensure concurrent executions
+ function_wait.tv_sec = 0;
+ function_wait.tv_nsec = FUNCTION_WAIT_NANOSECONDS;
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &function_wait, NULL);
+
+ rtems_clock_get_uptime(&uptime);
+ ctx->functions_start = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ /*
+ * Start execution of task-manager related functions following formula of:
+ *
+ * Defined behaviour
+ * Undefined behaviour
+ * Defined behaviour
+ *
+ * NOTE REGARDING SPECIFICATION:
+ * This test of undefined behaviour shall be conducted for:
+ * - rtems_task_mode()
+ * This test of undefined behaviour shall NOT be conducted for:
+ * - rtems_task_create()
+ * As confirmed in RTEMS-SMP-VAL-001 implementation in the space profile for this directive
+ * is not allowed, and therefore testing is defunct.
+ *
+ * To check the current status of the task execution mode, we must call rtems_task_mode
+ * passing in RTEMS_CURRENT_MODE as the mask, which causes the first parameter to be ignored
+ * and returns the state in the third parameter. As such we will use this to check possible
+ * invalidation of state from undefined behaviour calls with appropriate assertions.
+ *
+ * When we set mutually exclusive options which are combined with a bitwise OR, what we see
+ * is the non-default option being applied. Where setting certain options isn't possible due
+ * to the SMP and space profile configuration, we will assert that appropriate errors being
+ * thrown, and that our configuration hasn't been invalidated or corrupted.
+ */
+
+ // Define test specific variables
+ rtems_mode mode_set;
+ rtems_status_code sc;
+
+ const rtems_mode TIMESLICE_MODE = RTEMS_TIMESLICE;
+ const rtems_mode NO_ASR_MODE = RTEMS_NO_ASR;
+ const rtems_mode NO_ASR_TIMESLICE_MODE = RTEMS_TIMESLICE | RTEMS_NO_ASR;
+
+ /*
+ * TIMESLICE
+ */
+
+ SetTaskMode(RTEMS_NO_TIMESLICE, RTEMS_TIMESLICE_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_timeslice_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ // INVALID CALL
+ SetTaskMode(RTEMS_NO_TIMESLICE | RTEMS_TIMESLICE, RTEMS_TIMESLICE_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_timeslice_calls &= ASSERT_TASK_MODES_EQ(mode_set, TIMESLICE_MODE);
+
+ SetTaskMode(RTEMS_NO_TIMESLICE, RTEMS_TIMESLICE_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_timeslice_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ /*
+ * Asynchronous Signal Routine (ASR)
+ */
+
+ // First with ASR being set
+
+ SetTaskMode(RTEMS_ASR, RTEMS_ASR_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_ASR_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ // INVALID CALL
+ SetTaskMode(RTEMS_NO_ASR | RTEMS_ASR, RTEMS_ASR_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_ASR_calls &= ASSERT_TASK_MODES_EQ(mode_set, NO_ASR_MODE);
+
+ SetTaskMode(RTEMS_ASR, RTEMS_ASR_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_ASR_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ // Then with NO_ASR being set
+
+ SetTaskMode(RTEMS_NO_ASR, RTEMS_ASR_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_ASR_calls &= ASSERT_TASK_MODES_EQ(mode_set, NO_ASR_MODE);
+
+ // INVALID CALL
+ SetTaskMode(RTEMS_NO_ASR | RTEMS_ASR, RTEMS_ASR_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_ASR_calls &= ASSERT_TASK_MODES_EQ(mode_set, NO_ASR_MODE);
+
+ SetTaskMode(RTEMS_ASR, RTEMS_ASR_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_ASR_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ /*
+ * PREEMPT
+ *
+ * Disabling Preemption on SMP systems is not possible, and any attempt to do so results in an
+ * RTEMS_NOT_IMPLEMENTED error.
+ */
+
+ SetTaskMode(RTEMS_PREEMPT, RTEMS_PREEMPT_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_preempt_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ // INVALID CALL
+ // We are expecting RTEMS_NOT_IMPLEMENTED due to interrupts not being enabled so don't assert success
+ sc = rtems_task_mode(RTEMS_PREEMPT | RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK, &mode_set);
+ ctx->preempt_not_impl = (RTEMS_NOT_IMPLEMENTED == sc);
+ mode_set = GetTaskMode();
+ ctx->expected_preempt_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ SetTaskMode(RTEMS_PREEMPT, RTEMS_PREEMPT_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_preempt_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ /*
+ * INTERRUPT LEVEL
+ *
+ * RTEMS allows up to 256 values depending on processor architecture to set the interrupt level,
+ * where a level of 0 indicates all interrupts are disabled (identical regardless of architecture)
+ * and progressive levels indicating more and more interrupts enabled.
+ *
+ * According to RTEMS CPU Architecture Documentation, maskable interrupts allowed range for the
+ * LEON3 / LEON4 processors is from 0 to 15 (16 levels, where 0 indicates all interrupts disabled).
+ *
+ * However in the RTEMS Qualification SRS for both GR712 and GR740, there exists a constraint
+ * (spec:/constraint/interrupts-disabled-smp) which states that 'Where the system was built with
+ * SMP support enabled, maskable interrupts are disabled for the executing thread.'
+ *
+ * Therefore as we are using SMP configuration for these tests, trying to combine mutually exclusive
+ * attributes, in this case enabling various interrupt levels through the maskable interrupt passed into
+ * the mode_set for this task with values e.g. 0 | 1 | 2 violates this constant and will result in an
+ * RTEMS_NOT_IMPLEMENTED error. This is the extent to which we can provide
+ * assertions on the correctness of this undefined behaviour.
+ */
+
+ SetTaskMode(RTEMS_INTERRUPT_LEVEL(0), RTEMS_INTERRUPT_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_interrupt_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ // INVALID CALL
+ // We are expecting RTEMS_NOT_IMPLEMENTED due to interrupts not being enabled so don't assert success
+ sc = rtems_task_mode(RTEMS_INTERRUPT_LEVEL(1) | RTEMS_INTERRUPT_LEVEL(2) | RTEMS_INTERRUPT_LEVEL(3), RTEMS_INTERRUPT_MASK, &mode_set);
+ ctx->interrupts_not_impl = (RTEMS_NOT_IMPLEMENTED == sc);
+ mode_set = GetTaskMode();
+ ctx->expected_interrupt_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ SetTaskMode(RTEMS_INTERRUPT_LEVEL(0), RTEMS_INTERRUPT_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_interrupt_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ /*
+ * COMBINATIONS OF MUTUALLY EXCLUSIVE & MUTUALLY INCLUSIVE ATTRIBUTES
+ */
+
+ SetTaskMode(RTEMS_DEFAULT_MODES, RTEMS_ALL_MODE_MASKS, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_combination_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ // INVALID CALL
+ SetTaskMode(RTEMS_NO_ASR | RTEMS_ASR | RTEMS_TIMESLICE | RTEMS_NO_TIMESLICE, RTEMS_ASR_MASK | RTEMS_TIMESLICE_MASK, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_combination_calls &= ASSERT_TASK_MODES_EQ(mode_set, NO_ASR_TIMESLICE_MODE);
+
+ SetTaskMode(RTEMS_DEFAULT_MODES, RTEMS_ALL_MODE_MASKS, mode_set);
+ mode_set = GetTaskMode();
+ ctx->expected_combination_calls &= ASSERT_TASK_MODES_EQ(mode_set, RTEMS_DEFAULT_MODES);
+
+ /*
+ * FINISHED EXECUTION OF TASK RELATED FUNCTIONS
+ */
+
+ rtems_clock_get_uptime(&uptime);
+ ctx->functions_end = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ // Only once this task has finished do we know we can progress
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ rtems_task_exit();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint8_t wait = 0;
+ uint32_t args[CALCULATION_TASKS] = {0};
+
+ TASK_COUNTER_SEMAPHORE = CreateCounterSemaphore(rtems_build_name('T', 'C', 'S', '0'), 0);
+
+ // Config for our mandelbrot tile function
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ // Create our barrier for mandelbrot tasks + undefined behaviour tasks
+ start_barrier = CreateAutomaticBarrier(TASK_COUNT);
+
+ // Finish config for our mandelbrot tile functions and start them
+ for (uint32_t i = 0; i < CALCULATION_TASKS; i++)
+ {
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', (char)i);
+ calc_task_config.storage_area = &task_storage[i][0];
+
+ ctx.calc_task_id[i] = DoCreateTask(calc_task_config);
+ args[i] = (i + 1);
+
+ StartTask(ctx.calc_task_id[i], (void *)calc_task_function, (void *)&args[i]);
+ }
+
+ // Set initial properties to check validity directives and results
+ ctx.expected_timeslice_calls = ctx.expected_ASR_calls = ctx.expected_preempt_calls = ctx.expected_interrupt_calls = ctx.expected_combination_calls = TRUE;
+
+ // Config our undefined behaviour task and start it
+ rtems_task_config undef_task_config = {
+ .name = rtems_build_name('U', 'N', 'D', 'F'),
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES,
+ .storage_area = &task_storage[TASK_COUNT-1][0]};
+
+ ctx.undefined_task_id = DoCreateTask(undef_task_config);
+ StartTask(ctx.undefined_task_id, undefined_behaviour_task, (void *)&ctx);
+
+ // Wait for all tasks to complete
+ while (wait < TASK_COUNT)
+ {
+ ObtainCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ wait++;
+ }
+
+ // Check concurrent executions
+ uint32_t latest_task_start = 0;
+ // Wraps around to effectively be maximum allowed value
+ uint32_t earliest_task_finish = -1;
+
+ for (uint8_t task = 0; task < CALCULATION_TASKS; task++)
+ {
+ latest_task_start = MAX(latest_task_start, task_before_mandelbrot[task]);
+ earliest_task_finish = MIN(earliest_task_finish, task_after_mandelbrot[task]);
+ }
+
+ print_string("\n\n");
+ if ((ctx.functions_start >= latest_task_start && ctx.functions_end <= earliest_task_finish))
+ {
+ print_string("Functions and mandelbrot executed concurrently: true\n\n");
+ }
+ else
+ {
+ print_string("Functions and mandelbrot executed concurrently: false\n\n");
+ }
+
+ // Check all directives yielded expected results
+ if (ctx.expected_timeslice_calls && ctx.expected_ASR_calls && ctx.expected_preempt_calls && ctx.expected_timeslice_calls && ctx.expected_combination_calls)
+ {
+ print_string("Directives all yielded expected results and configuration is valid: true\n");
+ }
+ else
+ {
+ print_string("Directives all yielded expected results and configuration is valid: false\n");
+ }
+
+ // Check individual directives themselves
+ (ctx.expected_timeslice_calls) ? print_string("Timeslice directives: SUCCEEDED\n") : print_string("Timeslice directives: FAILED\n");
+ (ctx.expected_ASR_calls) ? print_string("ASR directives: SUCCEEDED\n") : print_string("ASR directives: FAILED\n");
+ (ctx.expected_preempt_calls) ? print_string("Preempt directives: SUCCEEDED\n") : print_string("Preempt directives: FAILED\n");
+ (ctx.expected_interrupt_calls) ? print_string("Interrupt directives: SUCCEEDED\n") : print_string("Interrupt directives: FAILED\n");
+ (ctx.expected_combination_calls) ? print_string("Combination directives: SUCCEEDED\n") : print_string("Combination directives: FAILED\n");
+
+ // Check status codes returned are expected i.e. disallowed by config
+ if (ctx.preempt_not_impl)
+ {
+ print_string("Status code returned for RTEMS_PREEMPT is expected: true\n");
+ }
+ else
+ {
+ print_string("Status code returned for RTEMS_PREEMPT is expected: false\n");
+ }
+
+ if (ctx.interrupts_not_impl)
+ {
+ print_string("Status code returned for RTEMS_INTERRUPT_LEVEL > 0 is expected: true\n");
+ }
+ else
+ {
+ print_string("Status code returned for RTEMS_INTERRUPT_LEVEL > 0 is expected: false\n");
+ }
+
+ // Print mandelbrot set
+ print_test_results();
+
+ // Perform tidy up operations
+ rtems_barrier_delete(start_barrier);
+ rtems_semaphore_delete(TASK_COUNTER_SEMAPHORE);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+// Reduce the priority of the Init task so all other tasks can be schedules to all other cores
+#define CONFIGURE_INIT_TASK_PRIORITY PRIO_LOW
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/17_barrier_manager_undefined_behaviour/barrier_manager_undefined_behaviour.c b/testsuites/isvv/17_barrier_manager_undefined_behaviour/barrier_manager_undefined_behaviour.c
new file mode 100644
index 0000000000..ddeafe5352
--- /dev/null
+++ b/testsuites/isvv/17_barrier_manager_undefined_behaviour/barrier_manager_undefined_behaviour.c
@@ -0,0 +1,445 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+#include <string.h>
+
+/**
+ *
+ * @brief Tests impact of undefined behaviours
+ *
+ * This test case performs the calculation of the Mandelbrot set in
+ * parallel with execution of calls to barriers configured with
+ * attributes with undefined behaviour.
+ */
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#define TEST_BARRIERS_COUNT 3
+
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+#define EVENT_BARRIER RTEMS_EVENT_5
+
+// Timing related variables to ensure concurrent executions
+#define FUNCTION_WAIT_MICROSECONDS 10
+#define FUNCTION_WAIT_NANOSECONDS (FUNCTION_WAIT_MICROSECONDS * 1000)
+
+rtems_event_set event_send[] = {RTEMS_EVENT_1, RTEMS_EVENT_2, RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+typedef struct
+{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id problem_barrier_id;
+ rtems_id test_barriers[TEST_BARRIERS_COUNT];
+ uint8_t barrier_task_x;
+ uint8_t barrier_results[TEST_BARRIERS_COUNT];
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_before_mandelbrot[TASK_COUNT-1];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_after_mandelbrot[TASK_COUNT-1];
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ test_context *ctx;
+
+ ctx = (test_context *)arg;
+ struct timespec uptime;
+
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 0;
+
+ for (int i = 0; i < TASK_COUNT - 1; i++)
+ {
+ if (ctx->task_id[i] == local_id)
+ {
+ task_idx = i;
+ break;
+ }
+ }
+
+ WaitAtBarrier(ctx->problem_barrier_id);
+
+ rtems_clock_get_uptime(&uptime);
+ task_before_mandelbrot[task_idx] = (uint32_t) (uptime.tv_sec * 1000000 + uptime.tv_nsec/1000);
+
+ mandelbrot_tile(task_idx+1, ctx->ntiles);
+
+ rtems_clock_get_uptime(&uptime);
+ task_after_mandelbrot[task_idx] = (uint32_t) (uptime.tv_sec * 1000000 + uptime.tv_nsec/1000);
+
+ SendEvents(ctx->main_task, event_send[task_idx]);
+
+ SuspendSelf();
+}
+
+static void barrier_test_task(rtems_task_argument arg)
+{
+ test_context *ctx;
+ rtems_status_code sc;
+
+ ctx = (test_context *)arg;
+ /* char str[ITOA_STR_SIZE]; */
+ /* print_string(itoa(ctx->barrier_task_x, &str, 10)); */
+ sc = rtems_barrier_wait(ctx->test_barriers[ctx->barrier_task_x], BARRIER_TIMEOUT);
+ if(sc == RTEMS_SUCCESSFUL)
+ {
+ ctx->barrier_results[ctx->barrier_task_x] = 1;
+ }
+ else
+ {
+ ctx->barrier_results[ctx->barrier_task_x] = 0;
+ }
+
+ SendEvents(ctx->main_task, EVENT_BARRIER);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ rtems_event_set received = 0;
+ rtems_event_set total_events = 0;
+ char str[ITOA_STR_SIZE];
+ rtems_status_code sc;
+ struct timespec uptime;
+ uint32_t functions_start = 0, functions_end = 0;
+ struct timespec function_wait;
+
+ function_wait.tv_sec = 0;
+ function_wait.tv_nsec = FUNCTION_WAIT_NANOSECONDS;
+
+ memset(ctx.barrier_results, 0, sizeof(ctx.barrier_results)/sizeof(ctx.barrier_results[0]));
+ ctx.main_task = rtems_task_self();
+ ctx.ntiles = TASK_COUNT - 1;
+ ctx.next_tile = 1;
+ uint8_t nwaiting = ctx.ntiles;
+ // create a normal automatic barrier
+ ctx.problem_barrier_id = CreateAutomaticBarrier(nwaiting);
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ // create the mandlebrot set using all available cores minus one
+ for (uint32_t i = 0; i < TASK_COUNT - 1; i++)
+ {
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ // Wait for 10us to ensure concurrent executions
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &function_wait, NULL);
+
+ rtems_name barrier_name;
+ rtems_attribute barrier_attributes;
+ // with the last available core test the undefined behaviour barrier
+ for (uint32_t i = 0; i < TEST_BARRIERS_COUNT; i++) {
+
+ ctx.barrier_task_x = i;
+ ch = '0' + i;
+
+ // create a normal automatic barrier, a barrier with undefined behaviour
+ // and again a normal automatic barrier
+ if (i==1) {
+ barrier_attributes = RTEMS_BARRIER_MANUAL_RELEASE | RTEMS_BARRIER_AUTOMATIC_RELEASE;
+ }
+ else {
+ barrier_attributes = RTEMS_BARRIER_AUTOMATIC_RELEASE;
+ }
+
+ barrier_name = rtems_build_name('B', 'A', 'R', ch);
+
+ sc = rtems_barrier_create(barrier_name, barrier_attributes, 1,
+ &ctx.test_barriers[i]);
+ if(sc == RTEMS_SUCCESSFUL)
+ ctx.barrier_results[ctx.barrier_task_x] = 1;
+
+ calc_task_config.name = rtems_build_name('T', 'A', 'B', ch);
+ calc_task_config.storage_area = &calc_task_storage[TASK_COUNT - 1][0];
+
+ ctx.task_id[TASK_COUNT - 1] = DoCreateTask(calc_task_config);
+ // execute task that will be using the created barriers
+ if (i == 0) {
+ rtems_clock_get_uptime(&uptime);
+ functions_start = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+ }
+
+ StartTask(ctx.task_id[TASK_COUNT - 1], barrier_test_task, &ctx);
+ ReceiveAllEvents(EVENT_BARRIER);
+ DeleteTask(ctx.task_id[TASK_COUNT - 1]);
+ DeleteBarrier(ctx.test_barriers[i]);
+ }
+ rtems_clock_get_uptime(&uptime);
+ functions_end = (uint32_t) (uptime.tv_sec* 1000000 + uptime.tv_nsec/1000) ;
+
+ while (received != total_events)
+ {
+ received |= ReceiveAllEvents(total_events);
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ uint32_t latest_task_start = 0;
+ uint32_t earliest_task_finish = -1;
+ for (uint32_t task = 0; task < TASK_COUNT - 1; task++) {
+ if (task_before_mandelbrot[task] > latest_task_start)
+ latest_task_start = task_before_mandelbrot[task];
+ if (task_after_mandelbrot[task] < earliest_task_finish)
+ earliest_task_finish = task_after_mandelbrot[task];
+ }
+
+ print_string("\n\n");
+ if (functions_start > latest_task_start && functions_end < earliest_task_finish) {
+ print_string("Functions and normal Mandelbrot executed concurrently: true\n\n");
+ } else {
+ print_string("Functions and normal Mandelbrot executed concurrently: false\n\n");
+ }
+
+ print_string("Multicore Elapsed Time normal barrier - ");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ if(ctx.barrier_results[0] == 1 && ctx.barrier_results[1] == 1 && ctx.barrier_results[2] == 1)
+ {
+ print_string("Normal Mandelbrot task barrier functions executed correctly: true\n");
+ }
+ else
+ {
+ print_string("Normal Mandelbrot task barrier functions executed correctly: false\n");
+ }
+
+ print_test_results();
+
+ for (uint32_t i = 0; i < TASK_COUNT - 1; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ }
+
+ DeleteBarrier(ctx.problem_barrier_id);
+ // Reset results for second run
+ memset(ctx.barrier_results, 0, sizeof(ctx.barrier_results)/sizeof(ctx.barrier_results[0]));
+ latest_task_start = 0;
+ earliest_task_finish = -1;
+ total_events = 0;
+ received = 0;
+
+ // repeat the previous process, but the main task uses a barrier with undefined behaviour
+ sc = rtems_barrier_create(rtems_build_name('B', 'A', 'R', 'P'),
+ RTEMS_BARRIER_MANUAL_RELEASE | RTEMS_BARRIER_AUTOMATIC_RELEASE,
+ nwaiting, &ctx.problem_barrier_id);
+ ASSERT_SUCCESS(sc);
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ for (uint32_t i = 0; i < TASK_COUNT - 1; i++)
+ {
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ // Wait for 10us to ensure concurrent executions
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &function_wait, NULL);
+
+ for (uint32_t i = 0; i < TEST_BARRIERS_COUNT; i++) {
+
+ ctx.barrier_task_x = i;
+ ch = '0' + i;
+
+ // create a normal automatic barrier, a barrier with undefined behaviour
+ // and again a normal automatic barrier
+ if (i==1) {
+ barrier_attributes = RTEMS_BARRIER_MANUAL_RELEASE | RTEMS_BARRIER_AUTOMATIC_RELEASE;
+ } else {
+ barrier_attributes = RTEMS_BARRIER_AUTOMATIC_RELEASE;
+ }
+
+ barrier_name = rtems_build_name('B', 'A', 'R', ch);
+
+ sc = rtems_barrier_create(barrier_name, barrier_attributes, 1,
+ &ctx.test_barriers[i]);
+ if(sc == RTEMS_SUCCESSFUL)
+ ctx.barrier_results[ctx.barrier_task_x] = 1;
+
+ calc_task_config.name = rtems_build_name('T', 'A', 'B', ch);
+ calc_task_config.storage_area = &calc_task_storage[TASK_COUNT - 1][0];
+
+ ctx.task_id[TASK_COUNT - 1] = DoCreateTask(calc_task_config);
+ // execute task that will be using the created barriers
+ if (i == 0) {
+ rtems_clock_get_uptime(&uptime);
+ functions_start = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+ }
+
+ StartTask(ctx.task_id[TASK_COUNT - 1], barrier_test_task, &ctx);
+ ReceiveAllEvents(EVENT_BARRIER);
+ DeleteTask(ctx.task_id[TASK_COUNT - 1]);
+ DeleteBarrier(ctx.test_barriers[i]);
+ }
+
+ rtems_clock_get_uptime(&uptime);
+ functions_end = (uint32_t) (uptime.tv_sec* 1000000 + uptime.tv_nsec/1000) ;
+
+ while (received != total_events)
+ {
+ received |= ReceiveAllEvents(total_events);
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ for (uint32_t task = 0; task < TASK_COUNT - 1; task++) {
+ if (task_before_mandelbrot[task] > latest_task_start)
+ latest_task_start = task_before_mandelbrot[task];
+ if (task_after_mandelbrot[task] < earliest_task_finish)
+ earliest_task_finish = task_after_mandelbrot[task];
+ }
+
+ print_string("\n\n");
+ if (functions_start > latest_task_start && functions_end < earliest_task_finish) {
+ print_string("Functions and undefined Mandelbrot executed concurrently: true\n\n");
+ } else {
+ print_string("Functions and undefined Mandelbrot executed concurrently: false\n\n");
+ }
+
+ print_string("\n");
+ print_string("Multicore Elapsed Time undefined behaviour barrier - ");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ if(ctx.barrier_results[0] == 1 && ctx.barrier_results[1] == 1 && ctx.barrier_results[2] == 1)
+ {
+ print_string("Undefined Mandelbrot task barrier functions executed correctly: true\n");
+ }
+ else
+ {
+ print_string("Undefined Mandelbrot task barrier functions executed correctly: false\n");
+ }
+
+ print_test_results();
+
+ /* ############################################ */
+ for (uint32_t i = 0; i < TASK_COUNT - 1; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ }
+ DeleteBarrier(ctx.problem_barrier_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 5
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/18_event_manager_undefined_behaviour/event_manager_undefined_behaviour.c b/testsuites/isvv/18_event_manager_undefined_behaviour/event_manager_undefined_behaviour.c
new file mode 100644
index 0000000000..2223b16f77
--- /dev/null
+++ b/testsuites/isvv/18_event_manager_undefined_behaviour/event_manager_undefined_behaviour.c
@@ -0,0 +1,423 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+
+/**
+ *
+ * @brief Tests impact of undefined behaviours for events manager
+ *
+ * This test case performs the calculation of the Mandelbrot set in parallel with
+ * execution of various events-related functions with conditions which lead to
+ * undefined behaviour
+ */
+
+#define ITOA_STR_SIZE (4 * sizeof(int) + 1)
+
+#define NUM_TEST_FUNCTIONS 15
+#define RELATIVE_SLEEP 0
+#define FUNCTION_WAIT_MICROSECONDS 100
+#define FUNCTION_WAIT_NANOSECONDS (FUNCTION_WAIT_MICROSECONDS * 1000)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+// test specific global vars
+#define SEND_EVENTS_PERIOD 2
+
+// One task for sending events, one task for receiving events, and n-1 calculation tasks
+#define TASK_COUNT (TEST_PROCESSORS) + 1
+
+// We want to create mandelbrot executions whilst our events manager functions execute
+#define CALCULATION_TASKS (TEST_PROCESSORS) - 1
+
+#define EVENT_CALLS 15
+const rtems_event_set TEST_EVENTS[EVENT_CALLS] = {RTEMS_EVENT_0,
+ RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4,
+ RTEMS_EVENT_5,
+ RTEMS_EVENT_6,
+ RTEMS_EVENT_7,
+ RTEMS_EVENT_8,
+ RTEMS_EVENT_9,
+ RTEMS_EVENT_10,
+ RTEMS_EVENT_11,
+ RTEMS_EVENT_12,
+ RTEMS_EVENT_13,
+ RTEMS_EVENT_14};
+
+// Barrier to ensure calculation tasks and undefined behaviour tasks occur concurrently
+static rtems_id start_barrier;
+static rtems_id TASK_COUNTER_SEMAPHORE;
+
+typedef struct
+{
+ rtems_id calc_task_id[CALCULATION_TASKS];
+ rtems_id undefined_task_id;
+ rtems_id send_events_task_id;
+ uint32_t functions_start, functions_end;
+ bool is_expected_events;
+ rtems_event_set received_events_set;
+} test_context;
+
+// Create storage areas for each worker, using task construct forces
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+// Storage space for timings
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_before_mandelbrot[CALCULATION_TASKS];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_after_mandelbrot[CALCULATION_TASKS];
+
+static void calc_task_function(rtems_task_argument tile)
+{
+ uint8_t tile_n = (uint8_t)tile;
+ struct timespec uptime;
+
+ WaitAtBarrier(start_barrier);
+
+ // Check time function begins execution of mandelbrot executions
+ rtems_clock_get_uptime(&uptime);
+ task_before_mandelbrot[tile_n - 1] = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ mandelbrot_tile(tile_n, CALCULATION_TASKS);
+
+ // Check time function finishes execution of mandelbrot executions
+ rtems_clock_get_uptime(&uptime);
+ task_after_mandelbrot[tile_n - 1] = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ rtems_task_exit();
+}
+
+// Task to send an event to test the rtems_receive_event directive under scrutiny
+static void send_events_task(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+
+ rtems_id period = CreateRateMonotonic();
+
+ for (uint8_t i = 0; i < EVENT_CALLS; i++)
+ {
+ WaitPeriod(period, SEND_EVENTS_PERIOD);
+ SendEvents(ctx->undefined_task_id, TEST_EVENTS[i]);
+ }
+
+ // Once all the events that should be sent are sent, perform cleanup activities
+ rtems_rate_monotonic_delete(period);
+ rtems_task_exit();
+}
+
+// When using a directive with NO_WAIT, we need to do ensure an event has been provided from our
+// send event task without consuming the event which we want to test with the directive
+inline void WaitUntilPendingEvent(void) {
+ while (!QueryPendingEvents()) {}
+}
+
+static void undefined_behaviour_task(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+ struct timespec uptime, function_wait;
+
+ function_wait.tv_sec = 0;
+ function_wait.tv_nsec = FUNCTION_WAIT_NANOSECONDS;
+
+ WaitAtBarrier(start_barrier);
+
+ // Wait FUNCTION_WAIT_MICROSECONDS microseconds to ensure function calls are concurrent with mandelbrot calculation
+ clock_nanosleep(CLOCK_MONOTONIC, RELATIVE_SLEEP, &function_wait, NULL);
+
+ rtems_clock_get_uptime(&uptime);
+ ctx->functions_start = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ /* Start execution of events related functions following formula of:
+ *
+ * Defined behaviour
+ * Undefined behaviour
+ * Defined behaviour
+ *
+ * Where option_set has certain values combined with a bitwise OR. Some options are mutually exclusive.
+ * If mutually exclusive options are combined, the behaviour is undefined
+ *
+ * What we see when combining these values is the non-default options take precedence and are applied.
+ * When not provided to the directive, default options are applied.
+ * However we will specify these regardless for greater clarity.
+ *
+ * WaitUntilPendingEvent() is used before directives to ensure an event from our periodic send event
+ * is ready to be consumed
+ */
+
+ // Define test relevant variables
+ rtems_status_code sc;
+ rtems_event_set received;
+ rtems_event_set total_events = 0;
+
+ /*
+ * Testing RTEMS_EVENT_ALL | RTEMS_EVENT_ANY with RTEMS_WAIT
+ */
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[0]);
+
+ // INVALID CALL
+ WaitUntilPendingEvent();
+ sc = rtems_event_receive(TEST_EVENTS[1], RTEMS_WAIT | RTEMS_EVENT_ALL | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &received);
+ ASSERT_SUCCESS_WITHOUT_FAILING(sc);
+ total_events |= received;
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[2]);
+
+ /*
+ * Testing RTEMS_EVENT_ALL | RTEMS_EVENT_ANY with RTEMS_NO_WAIT
+ */
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[3]);
+
+ // INVALID CALL
+ WaitUntilPendingEvent();
+ sc = rtems_event_receive(TEST_EVENTS[4], RTEMS_NO_WAIT | RTEMS_EVENT_ALL | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &received);
+ ASSERT_SUCCESS_WITHOUT_FAILING(sc);
+ total_events |= received;
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[5]);
+
+ /*
+ * Testing RTEMS_NO_WAIT | RTEMS_WAIT with RTEMS_EVENT_ALL
+ */
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[6]);
+
+ // INVALID CALL
+ WaitUntilPendingEvent();
+ sc = rtems_event_receive(TEST_EVENTS[7], RTEMS_NO_WAIT | RTEMS_WAIT | RTEMS_EVENT_ALL, RTEMS_NO_TIMEOUT, &received);
+ ASSERT_SUCCESS_WITHOUT_FAILING(sc);
+ total_events |= received;
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[8]);
+
+ /*
+ * Testing RTEMS_NO_WAIT | RTEMS_WAIT with RTEMS_EVENT_ANY
+ */
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[9]);
+
+ // INVALID CALL
+ WaitUntilPendingEvent();
+ sc = rtems_event_receive(TEST_EVENTS[10], RTEMS_NO_WAIT | RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &received);
+ ASSERT_SUCCESS_WITHOUT_FAILING(sc);
+ total_events |= received;
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[11]);
+
+ /*
+ * Testing RTEMS_NO_WAIT | RTEMS_WAIT | RTEMS_EVENT_ALL | RTEMS_EVENT_ANY
+ */
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[12]);
+
+ // INVALID CALL
+ WaitUntilPendingEvent();
+ sc = rtems_event_receive(TEST_EVENTS[13], RTEMS_NO_WAIT | RTEMS_WAIT | RTEMS_EVENT_ALL | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &received);
+ ASSERT_SUCCESS_WITHOUT_FAILING(sc);
+ total_events |= received;
+
+ total_events |= ReceiveAllEvents(TEST_EVENTS[14]);
+
+ // DEBUG
+ // print_string("FINISHED EXECUTION OF EVENTS DIRECTIVES\n");
+
+ // Check total received events against expected events and pass back to main task
+ ctx->is_expected_events = (total_events == (power(2, EVENT_CALLS) - 1));
+ ctx->received_events_set = total_events;
+
+ rtems_clock_get_uptime(&uptime);
+ ctx->functions_end = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ // Only once this task has finished do we know we can progress
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ rtems_task_exit();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ char str[ITOA_STR_SIZE];
+ uint8_t wait = 0;
+
+ TASK_COUNTER_SEMAPHORE = CreateCounterSemaphore(rtems_build_name('T', 'C', 'S', '0'), 0);
+
+ start_barrier = CreateAutomaticBarrier(CALCULATION_TASKS + 1);
+
+ // Config for our mandelbrot tile function, with priority high as we don't want this to be preempted
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_HIGH,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ // Finish config for our mandelbrot tile functions and start them
+ for (uint32_t i = 0; i < CALCULATION_TASKS; i++)
+ {
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', (char)i);
+ calc_task_config.storage_area = &task_storage[i][0];
+
+ ctx.calc_task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.calc_task_id[i], calc_task_function, (void *)(i + 1));
+ }
+
+ // Config our undefined behaviour task and start it
+ rtems_task_config undef_task_config = {
+ .name = rtems_build_name('U', 'N', 'D', 'F'),
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES,
+ .storage_area = &task_storage[TASK_COUNT - 2][0]};
+
+ ctx.undefined_task_id = DoCreateTask(undef_task_config);
+ StartTask(ctx.undefined_task_id, undefined_behaviour_task, (void *)&ctx);
+
+ // Config our event sending task and start it
+ rtems_task_config send_events_task_config = {
+ .name = rtems_build_name('T', 'S', 'T', 'E'),
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES,
+ .storage_area = &task_storage[TASK_COUNT - 1][0]};
+
+ ctx.send_events_task_id = DoCreateTask(send_events_task_config);
+ StartTask(ctx.send_events_task_id, send_events_task, (void *)&ctx);
+
+ // Wait for all tasks to complete
+ while (wait < CALCULATION_TASKS + 1)
+ {
+ ObtainCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ wait++;
+ }
+
+ // Check concurrent executions
+ uint32_t latest_task_start = 0;
+ // Wraps around to effectively be maximum allowed value
+ uint32_t earliest_task_finish = -1;
+
+ for (uint8_t task = 0; task < CALCULATION_TASKS; task++)
+ {
+ latest_task_start = MAX(latest_task_start, task_before_mandelbrot[task]);
+ earliest_task_finish = MIN(earliest_task_finish, task_after_mandelbrot[task]);
+ }
+
+ if ((ctx.functions_start >= latest_task_start && ctx.functions_end <= earliest_task_finish))
+ {
+ print_string("Functions and Mandelbrot executed concurrently: true\n\n");
+ }
+ else
+ {
+ print_string("Functions and Mandelbrot executed concurrently: false\n\n");
+ }
+
+ (ctx.is_expected_events) ? print_string("EXPECTED EVENTS: TRUE\n")
+ : print_string("EXPECTED EVENTS: FALSE\n");
+
+ // Where each binary digit represents a passing / failing test
+ print_string("CUMULATIVE TOTAL OF EVENTS RECEIVED IN BINARY: ");
+ print_string(itoa(ctx.received_events_set, &str[0], 2));
+ print_string("\n");
+
+ print_test_results();
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+// Reduce the priority of the Init task so all other tasks can be scheduled to all other cores
+#define CONFIGURE_INIT_TASK_PRIORITY PRIO_LOW
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_PERIODS 1
+
+// Number of Tasks configured + 1 for the INIT task
+#define CONFIGURE_MAXIMUM_TASKS (TASK_COUNT) + 1
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/19_message_manager_undefined_behaviour/message_manager_undefined_behaviour.c b/testsuites/isvv/19_message_manager_undefined_behaviour/message_manager_undefined_behaviour.c
new file mode 100644
index 0000000000..b13604dc64
--- /dev/null
+++ b/testsuites/isvv/19_message_manager_undefined_behaviour/message_manager_undefined_behaviour.c
@@ -0,0 +1,346 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+
+/**
+ *
+ * @brief Tests impact of undefined behaviours
+ *
+ * This test case performs the calculation of the Mandelbrot set in
+ * parallel with execution of calls to message queues configured with
+ * attributes with undefined behaviour.
+ */
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define TEST_MESSAGE_QUEUES_COUNT 3
+
+#define TASK_COUNT TEST_PROCESSORS
+#define TEST_TASK (TASK_COUNT - 1)
+#define MANDL_TASKS (TASK_COUNT - 1)
+#define TOTAL_TILES 64
+
+#define MAX_MESSAGE_QUEUES 2
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES TASK_COUNT
+
+#define MESSAGE_TEST_SEND 12
+#define MESSAGE_TASK_SEND 24
+
+rtems_event_set event_send[] = {RTEMS_EVENT_1, RTEMS_EVENT_2, RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+typedef struct
+{
+ rtems_id main_task;
+ uint8_t ntiles;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id barrier_id;
+ rtems_id msg_init_queue_id;
+ rtems_id msg_task_queue_id;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_before_mandelbrot[TASK_COUNT-1];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_after_mandelbrot[TASK_COUNT-1];
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ test_context *ctx;
+
+ ctx = (test_context *)arg;
+ struct timespec uptime;
+
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 0;
+
+ rtems_clock_get_uptime(&uptime);
+ task_before_mandelbrot[task_idx] = (uint32_t) (uptime.tv_sec * 1000000 + uptime.tv_nsec/1000);
+
+ for (int i = 0; i < MANDL_TASKS; i++)
+ {
+ if (ctx->task_id[i] == local_id)
+ {
+ task_idx = i;
+ break;
+ }
+ }
+
+ WaitAtBarrier(ctx->barrier_id);
+ mandelbrot_tile(task_idx+1, ctx->ntiles);
+
+ rtems_clock_get_uptime(&uptime);
+ task_after_mandelbrot[task_idx] = (uint32_t) (uptime.tv_sec * 1000000 + uptime.tv_nsec/1000);
+
+ SendEvents(ctx->main_task, event_send[task_idx]);
+
+ SuspendSelf();
+}
+
+static void message_test_task(rtems_task_argument arg)
+{
+ test_context *ctx;
+
+ ctx = (test_context *)arg;
+
+ uint8_t val_receive = 0, val_send = 0;
+
+ ReceiveMessage(ctx->msg_task_queue_id, &val_receive);
+ if (val_receive == MESSAGE_TASK_SEND) {
+ val_send = MESSAGE_TEST_SEND;
+ SendMessage(ctx->msg_init_queue_id, &val_send, sizeof(uint8_t));
+ }
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch;
+ rtems_event_set received = 0;
+ rtems_event_set total_events = 0;
+ bool defined_process = false;
+ bool undefined_process = false;
+ char str[ITOA_STR_SIZE];
+ struct timespec uptime;
+ uint32_t functions_start = 0, functions_end;
+
+ ctx.main_task = rtems_task_self();
+ ctx.ntiles = MANDL_TASKS;
+ uint8_t nwaiting = ctx.ntiles;
+ // create an automatic barrier
+ ctx.barrier_id = CreateAutomaticBarrier(nwaiting);
+
+ start_time = rtems_clock_get_ticks_since_boot();
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ // create the mandlebrot set using all available cores minus one
+ for (uint32_t i = 0; i < MANDL_TASKS; i++)
+ {
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ // with the last available core test the undefined behaviour message queue
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ // create a normal message queue to send messages to the tasks that will
+ // receive messages in the undefined behaviour message queues
+
+ uint8_t val_send = 0, val_receive = 0;
+ for (uint32_t i = 0; i < TEST_MESSAGE_QUEUES_COUNT; i++)
+ {
+ ctx.msg_task_queue_id = CreateMessageQueue(msg_config);
+ // create a normal message queue, a message queue with undefined
+ // behaviour and again a normal message queue
+ if (i==1)
+ {
+ msg_config.name = rtems_build_name('M', 'S', 'G', '0');
+ msg_config.attributes = RTEMS_FIFO | RTEMS_LOCAL | RTEMS_GLOBAL;
+ }
+ else
+ {
+ msg_config.name = rtems_build_name('M', 'S', 'G', '1');
+ msg_config.attributes = RTEMS_FIFO | RTEMS_GLOBAL;
+ }
+
+ ctx.msg_init_queue_id = CreateMessageQueue(msg_config);
+
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('T', 'M', 'S', ch);
+ calc_task_config.storage_area = &calc_task_storage[TEST_TASK][0];
+
+ ctx.task_id[TEST_TASK] = DoCreateTask(calc_task_config);
+ // execute task that receives and sends messages
+ if (i == 0) {
+ rtems_clock_get_uptime(&uptime);
+ functions_start = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+ }
+ StartTask(ctx.task_id[TEST_TASK], message_test_task, &ctx);
+
+ val_send = MESSAGE_TASK_SEND;
+
+ SendMessage(ctx.msg_task_queue_id, &val_send, sizeof(val_send));
+ ReceiveMessage(ctx.msg_init_queue_id, &val_receive);
+
+ if (i==1) {
+ undefined_process = (val_receive == MESSAGE_TEST_SEND);
+ } else {
+ defined_process = (val_receive == MESSAGE_TEST_SEND);
+ }
+
+ DeleteTask(ctx.task_id[TEST_TASK]);
+ DeleteMessageQueue(ctx.msg_init_queue_id);
+ DeleteMessageQueue(ctx.msg_task_queue_id);
+ }
+ rtems_clock_get_uptime(&uptime);
+ functions_end = (uint32_t) (uptime.tv_sec* 1000000 + uptime.tv_nsec/1000) ;
+
+ while (received != total_events)
+ {
+ received |= ReceiveAllEvents(total_events);
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+
+ elapsed_time = end_time - start_time;
+
+ uint32_t latest_task_start = 0;
+ uint32_t earliest_task_finish = -1;
+ for (uint32_t task = 0; task < MANDL_TASKS; task++) {
+ if (task_before_mandelbrot[task] > latest_task_start)
+ latest_task_start = task_before_mandelbrot[task];
+ if (task_after_mandelbrot[task] < earliest_task_finish)
+ earliest_task_finish = task_after_mandelbrot[task];
+ }
+
+ print_string("\n");
+ if (functions_start > latest_task_start && functions_end < earliest_task_finish) {
+ print_string("Functions and mandelbrot executed concurrently: true\n\n");
+ } else {
+ print_string("Functions and mandelbrot executed concurrently: false\n\n");
+ }
+
+ print_string("Mandelbrot task and defined message functions executed correctly: ");
+ if (defined_process) {
+ print_string("true\n");
+ } else {
+ print_string("false\n");
+ }
+
+ print_string("Mandelbrot task and undefined message functions executed correctly: ");
+ if (undefined_process) {
+ print_string("true\n");
+ } else {
+ print_string("false\n");
+ }
+
+ print_string("Multicore Elapsed Time - ");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ print_test_results();
+
+ for (uint32_t i = 0; i < MANDL_TASKS; i++)
+ {
+ DeleteTask(ctx.task_id[i]);
+ }
+ DeleteBarrier(ctx.barrier_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/20_partition_manager_undefined_behaviour/partition_manager_undefined_behaviour.c b/testsuites/isvv/20_partition_manager_undefined_behaviour/partition_manager_undefined_behaviour.c
new file mode 100644
index 0000000000..76d1576dcc
--- /dev/null
+++ b/testsuites/isvv/20_partition_manager_undefined_behaviour/partition_manager_undefined_behaviour.c
@@ -0,0 +1,359 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+
+/**
+ *
+ * @brief Tests impact of undefined behaviour for partition manager
+ *
+ * This test case performs the calculation of the Mandelbrot set in parallel with
+ * execution of partition related functions with conditions which lead to
+ * undefined behaviour
+ * @{
+ */
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+// test specific global vars
+
+// We want to create mandelbrot executions whilst our manager functions
+// Are executed on another core
+#define TASK_COUNT TEST_PROCESSORS
+#define CALCULATION_TASKS ((TEST_PROCESSORS) - 1)
+
+// Timing related variables to ensure concurrent executions
+#define RELATIVE_SLEEP 0
+#define FUNCTION_WAIT_MICROSECONDS 10
+#define FUNCTION_WAIT_NANOSECONDS (FUNCTION_WAIT_MICROSECONDS * 1000)
+
+static rtems_id start_barrier;
+static rtems_id TASK_COUNTER_SEMAPHORE;
+
+typedef struct
+{
+ rtems_id calc_task_id[CALCULATION_TASKS];
+ rtems_id undefined_task_id;
+ uint32_t functions_start, functions_end;
+ bool valid_call_RES_IN_USE_1, valid_call_RES_IN_USE_2, invalid_call_RES_IN_USE;
+} test_context;
+
+// Create storage areas from which to create our partitions
+RTEMS_ALIGNED(CPU_STACK_ALIGNMENT)
+static char partition_storage[65536];
+
+// Create storage areas for each worker, using task construct forces
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+// Storage space for timings
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_before_mandelbrot[CALCULATION_TASKS];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_after_mandelbrot[CALCULATION_TASKS];
+
+static void calc_task_function(rtems_task_argument tile)
+{
+ uint8_t tile_n = (uint8_t)tile;
+ struct timespec uptime;
+
+ WaitAtBarrier(start_barrier);
+
+ // Check time function begins execution of mandelbrot executions
+ rtems_clock_get_uptime(&uptime);
+ task_before_mandelbrot[tile_n - 1] = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ mandelbrot_tile(tile_n, CALCULATION_TASKS);
+
+ // Check time function finishes execution of mandelbrot executions
+ rtems_clock_get_uptime(&uptime);
+ task_after_mandelbrot[tile_n - 1] = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ rtems_task_exit();
+}
+
+static void undefined_behaviour_task(rtems_task_argument arg)
+{
+ test_context *ctx = (test_context *)arg;
+ struct timespec uptime, function_wait;
+
+ WaitAtBarrier(start_barrier);
+
+ // Wait for 10us to ensure concurrent executions
+ function_wait.tv_sec = 0;
+ function_wait.tv_nsec = FUNCTION_WAIT_NANOSECONDS;
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &function_wait, NULL);
+
+ rtems_clock_get_uptime(&uptime);
+ ctx->functions_start = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ /* Start execution of partition related functions following formula of:
+ * Defined behaviour
+ * Undefined behaviour
+ * Defined behaviour
+ *
+ * Where attribute_set has certain values combined with a bitwise OR. Values combined that are mutually
+ * exclusive is categorised as undefined behaviour. What we see when combining these values is the
+ * non-default option takes precedence and is applied, in this case that is the RTEMS_GLOBAL attribute.
+ *
+ * According to the RTEMS documentation, setting the global attribute in a single node system has no effect.
+ * As we are restricted to a single-node system with this qualification pack, and the goal is to assert
+ * SMP functionality (rather than MPCI functionality) we will not be testing multiple nodes when using the
+ * RTEMS_GLOBAL attribute.
+ *
+ * Therefore to check the functionality and correctness for the directive rtems_create_partition, we will
+ * perform an assertion on the returned status code, as well as both request and return a buffer
+ * of a size pre-defined in the _create call. Before returning the buffer, we will attempt to delete
+ * the partition. In correct program function, this should not be allowed, and will allow us to
+ * match correct program behaviour when using undefined behaviour.
+ */
+
+ // Define test relevant variables
+ rtems_status_code sc;
+ rtems_id partition_id;
+ void *starting_address;
+ void *buffer_ptr;
+
+ // We will reuse the same starting address as the memory from previous partition SHOULD have been returned to RTEMS
+ starting_address = &partition_storage;
+
+ /*
+ * VALID CALL - attribute_set = RTEMS_LOCAL
+ */
+
+ // Create our partition in the designated aligned space
+ ASSERT_SUCCESS(rtems_partition_create(rtems_build_name('P', 'R', 'T', '1'), &starting_address, 128, 32, RTEMS_LOCAL, &partition_id));
+ // Try to create a buffer from the partition
+ ASSERT_SUCCESS(rtems_partition_get_buffer(partition_id, &buffer_ptr));
+
+ // Status code returned should indicate action is not allowed
+ sc = rtems_partition_delete(partition_id);
+ ctx->valid_call_RES_IN_USE_1 = (RTEMS_RESOURCE_IN_USE == sc);
+
+ // Now return the buffer and clean up the partition
+ ASSERT_SUCCESS(rtems_partition_return_buffer(partition_id, buffer_ptr));
+ ASSERT_SUCCESS(rtems_partition_delete(partition_id));
+
+ /*
+ * INVALID CALL - attribute_set = RTEMS_LOCAL | RTEMS_GLOBAL
+ */
+
+ ASSERT_SUCCESS(rtems_partition_create(rtems_build_name('P', 'R', 'T', 'I'), &starting_address, 128, 32, RTEMS_LOCAL | RTEMS_GLOBAL, &partition_id));
+ ASSERT_SUCCESS(rtems_partition_get_buffer(partition_id, &buffer_ptr));
+
+ // To assess the effectiveness of the directive in question, we will try to match with known correct program behaviour.
+ // Trying to delete a partition with an unreturned buffer should throw the same error as in the valid call.
+ sc = rtems_partition_delete(partition_id);
+ ctx->invalid_call_RES_IN_USE = (RTEMS_RESOURCE_IN_USE == sc);
+
+ ASSERT_SUCCESS(rtems_partition_return_buffer(partition_id, buffer_ptr));
+ ASSERT_SUCCESS(rtems_partition_delete(partition_id));
+
+ /*
+ * VALID CALL - attribute_set = RTEMS_LOCAL
+ */
+
+ ASSERT_SUCCESS(rtems_partition_create(rtems_build_name('P', 'R', 'T', '2'), &starting_address, 128, 32, RTEMS_LOCAL, &partition_id));
+ ASSERT_SUCCESS(rtems_partition_get_buffer(partition_id, &buffer_ptr));
+
+ sc = rtems_partition_delete(partition_id);
+ ctx->valid_call_RES_IN_USE_2 = (RTEMS_RESOURCE_IN_USE == sc);
+
+ ASSERT_SUCCESS(rtems_partition_return_buffer(partition_id, buffer_ptr));
+ ASSERT_SUCCESS(rtems_partition_delete(partition_id));
+
+ /*
+ * FINISHED EXECUTION OF PARTITION RELATED FUNCTIONS
+ */
+
+ rtems_clock_get_uptime(&uptime);
+ ctx->functions_end = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ // Only once this task has finished do we know we can progress
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ rtems_task_exit();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint8_t wait = 0;
+
+ TASK_COUNTER_SEMAPHORE = CreateCounterSemaphore(rtems_build_name('T', 'C', 'S', '0'), 0);
+
+ // Config for our mandelbrot tile function
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ // Create our barrier for mandelbrot tasks + undefined behaviour task
+ start_barrier = CreateAutomaticBarrier(TASK_COUNT);
+
+ // Finish config for our mandelbrot tile functions and start them
+ for (uint32_t i = 0; i < CALCULATION_TASKS; i++)
+ {
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', (char)i);
+ calc_task_config.storage_area = &task_storage[i][0];
+
+ ctx.calc_task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.calc_task_id[i], calc_task_function, (void *)(i + 1));
+ }
+
+ // Config our undefined behaviour task and start it
+ rtems_task_config undef_task_config = {
+ .name = rtems_build_name('U', 'N', 'D', 'F'),
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES,
+ .storage_area = &task_storage[TASK_COUNT-1][0]};
+
+ // Set properties to check for functionality of directives
+ ctx.valid_call_RES_IN_USE_1 = ctx.invalid_call_RES_IN_USE = ctx.valid_call_RES_IN_USE_2 = FALSE;
+
+ ctx.undefined_task_id = DoCreateTask(undef_task_config);
+ StartTask(ctx.undefined_task_id, undefined_behaviour_task, (void *)&ctx);
+
+ // Wait for all tasks to complete
+ while (wait < TASK_COUNT)
+ {
+ ObtainCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ wait++;
+ }
+
+ // Check RESOURCE_IN_USE errors which should've been thrown
+ if (ctx.valid_call_RES_IN_USE_1 && ctx.invalid_call_RES_IN_USE && ctx.valid_call_RES_IN_USE_2)
+ {
+ print_string("Incorrectly deleting partitions throws expected errors: true\n");
+ }
+ else
+ {
+ print_string("Incorrectly deleting partitions throws expected errors: false\n");
+ (ctx.valid_call_RES_IN_USE_1) ? print_string("1st call - SUCCEEDED\n") : print_string("1st call - FAILED\n");
+ (ctx.invalid_call_RES_IN_USE) ? print_string("2nd call - SUCCEEDED\n") : print_string("2nd call - FAILED\n");
+ (ctx.valid_call_RES_IN_USE_2) ? print_string("3rd call - SUCCEEDED\n") : print_string("3rd call - FAILED\n");
+ }
+
+ // Check concurrent executions
+
+ uint32_t latest_task_start = 0;
+ // Wraps around to effectively be maximum allowed value
+ uint32_t earliest_task_finish = -1;
+
+ for (uint8_t task = 0; task < CALCULATION_TASKS; task++)
+ {
+ latest_task_start = MAX(latest_task_start, task_before_mandelbrot[task]);
+ earliest_task_finish = MIN(earliest_task_finish, task_after_mandelbrot[task]);
+ }
+
+ print_string("\n\n");
+ if ((ctx.functions_start >= latest_task_start && ctx.functions_end <= earliest_task_finish))
+ {
+ print_string("Functions and mandelbrot executed concurrently: true\n\n");
+ }
+ else
+ {
+ print_string("Functions and mandelbrot executed concurrently: false\n\n");
+ }
+
+ print_test_results();
+
+ // Perform tidy up activities and exit application
+ rtems_semaphore_delete(TASK_COUNTER_SEMAPHORE);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+// Reduce the priority of the Init task so all other tasks can be schedules to all other cores
+#define CONFIGURE_INIT_TASK_PRIORITY PRIO_LOW
+
+#define CONFIGURE_MAXIMUM_PARTITIONS 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TASKS ((TEST_PROCESSORS) + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * (TASK_STORAGE_SIZE)
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h> \ No newline at end of file
diff --git a/testsuites/isvv/21_semaphore_manager_undefined_behaviour/semaphore_manager_undefined_behaviour.c b/testsuites/isvv/21_semaphore_manager_undefined_behaviour/semaphore_manager_undefined_behaviour.c
new file mode 100644
index 0000000000..dd12550321
--- /dev/null
+++ b/testsuites/isvv/21_semaphore_manager_undefined_behaviour/semaphore_manager_undefined_behaviour.c
@@ -0,0 +1,661 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/utils.h"
+#include <rtems.h>
+#include <rtems/bspIo.h>
+
+/**
+ *
+ * @brief Tests impact of undefined behaviours
+ *
+ * This test case performs the calculation of the Mandelbrot set in
+ * parallel with execution of calls to semaphores configured with
+ * attributes with undefined behaviour
+ *
+ */
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE(MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+
+#define MANDL_TASKS (TASK_COUNT - 1)
+#define LAST_TASK (TASK_COUNT - 1)
+#define TOTAL_TILES 64
+
+#define NUMBER_OF_SEM_CREATE_TESTS 10
+#define CREATE_TEST_MUTEX_FAILED 0xfffffffe
+#define NUMBER_OF_SEM_SET_PRIO_TESTS 4
+#define LOOPS_PER_TEST 3
+#define RELATIVE_SLEEP 0
+#define FUNCTION_WAIT_MICROSECONDS 8
+#define FUNCTION_WAIT_NANOSECONDS (FUNCTION_WAIT_MICROSECONDS * 1000)
+
+rtems_event_set event_send[] = {RTEMS_EVENT_1, RTEMS_EVENT_2, RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+// MUST NOT overlap event_send[]
+#define FLUSH_EVENT RTEMS_EVENT_8
+
+typedef struct {
+ rtems_attribute att_config;
+ char str_output[133];
+} semaphore_attribute;
+
+typedef struct {
+ rtems_id main_task;
+ uint8_t ntiles;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id barrier_id;
+ rtems_id sem_id;
+ bool sem_obtained;
+ rtems_attribute sem_obtain_attributes;
+} test_context;
+
+static semaphore_attribute sem_create_attributes[NUMBER_OF_SEM_CREATE_TESTS] =
+{
+ {RTEMS_LOCAL | RTEMS_GLOBAL, "RTEMS_LOCAL | RTEMS_GLOBAL"},
+ {RTEMS_BINARY_SEMAPHORE | RTEMS_FIFO | RTEMS_PRIORITY, "RTEMS_BINARY_SEMAPHORE | RTEMS_FIFO | RTEMS_PRIORITY"},
+ {RTEMS_COUNTING_SEMAPHORE | RTEMS_BINARY_SEMAPHORE, "RTEMS_COUNTING_SEMAPHORE | RTEMS_BINARY_SEMAPHORE"},
+ {RTEMS_COUNTING_SEMAPHORE | RTEMS_SIMPLE_BINARY_SEMAPHORE, "RTEMS_COUNTING_SEMAPHORE | RTEMS_SIMPLE_BINARY_SEMAPHORE"},
+ {RTEMS_BINARY_SEMAPHORE | RTEMS_SIMPLE_BINARY_SEMAPHORE, "RTEMS_BINARY_SEMAPHORE | RTEMS_SIMPLE_BINARY_SEMAPHORE"},
+ {RTEMS_COUNTING_SEMAPHORE | RTEMS_BINARY_SEMAPHORE | RTEMS_SIMPLE_BINARY_SEMAPHORE, "RTEMS_COUNTING_SEMAPHORE | RTEMS_BINARY_SEMAPHORE | " "RTEMS_SIMPLE_BINARY_SEMAPHORE"},
+ {RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING | RTEMS_INHERIT_PRIORITY, "RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING | " "RTEMS_INHERIT_PRIORITY"},
+ {RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING | RTEMS_MULTIPROCESSOR_RESOURCE_SHARING, "RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING | " "RTEMS_MULTIPROCESSOR_RESOURCE_SHARING"},
+ {RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY | RTEMS_MULTIPROCESSOR_RESOURCE_SHARING, "RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY | " "RTEMS_MULTIPROCESSOR_RESOURCE_SHARING"},
+ {RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY_CEILING | RTEMS_MULTIPROCESSOR_RESOURCE_SHARING, "RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY | " "RTEMS_PRIORITY_CEILING | RTEMS_MULTIPROCESSOR_RESOURCE_SHARING"}
+};
+
+#define NO_LOCKING_PROTOCOL ( RTEMS_NO_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING )
+// These are the only attribute set configurations that are both allowed by rtems_semaphore_create() and
+// are not explicitly not undefined behaviour for rtems_semaphore_set_priority().
+static semaphore_attribute sem_set_prio_attributes[NUMBER_OF_SEM_SET_PRIO_TESTS] =
+{
+ {RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY | NO_LOCKING_PROTOCOL, "RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY | NO_LOCKING_PROTOCOL"},
+ {RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | NO_LOCKING_PROTOCOL, "RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | NO_LOCKING_PROTOCOL"},
+ {RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, "RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY"},
+ {RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY | NO_LOCKING_PROTOCOL, "RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_PRIORITY | NO_LOCKING_PROTOCOL"}
+};
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_before_mandelbrot[TASK_COUNT - 1];
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static uint32_t task_after_mandelbrot[TASK_COUNT - 1];
+
+static void calc_task_function(rtems_task_argument arg) {
+ test_context *ctx;
+
+ ctx = (test_context *)arg;
+ struct timespec uptime;
+
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 0;
+
+ for (int i = 0; i < MANDL_TASKS; i++) {
+ if (ctx->task_id[i] == local_id) {
+ task_idx = i;
+ break;
+ }
+ }
+
+ WaitAtBarrier(ctx->barrier_id);
+
+ rtems_clock_get_uptime(&uptime);
+ task_before_mandelbrot[task_idx] =
+ (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ mandelbrot_tile(task_idx + 1, ctx->ntiles);
+
+ rtems_clock_get_uptime(&uptime);
+ task_after_mandelbrot[task_idx] =
+ (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ SendEvents(ctx->main_task, event_send[task_idx]);
+
+ SuspendSelf();
+}
+
+static void semaphore_test_task(rtems_task_argument arg)
+{
+ test_context *ctx;
+
+ ctx = (test_context *)arg;
+
+ ObtainMutex(ctx->sem_id);
+ ctx->sem_obtained = true;
+ ReleaseMutex(ctx->sem_id);
+
+ SendEvents(ctx->main_task, event_send[LAST_TASK]);
+ SuspendSelf();
+}
+
+static void semaphore_create_test_task(rtems_task_argument arg)
+{
+ semaphore_test_task(arg);
+}
+
+static void semaphore_set_prio_run_task(rtems_task_argument arg)
+{
+ semaphore_test_task(arg);
+}
+
+static void semaphore_obtain_test_task(rtems_task_argument arg) {
+ test_context *ctx;
+
+ ctx = (test_context *)arg;
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain(ctx->sem_id, ctx->sem_obtain_attributes, RTEMS_NO_TIMEOUT);
+ if(sc == RTEMS_SUCCESSFUL)
+ {
+ ctx->sem_obtained = true;
+ ReleaseMutex(ctx->sem_id);
+ }
+
+ SendEvents(ctx->main_task, event_send[LAST_TASK]);
+ SuspendSelf();
+}
+
+static void semaphore_flush_test_task(rtems_task_argument arg) {
+ test_context *ctx;
+ ctx = (test_context *)arg;
+
+ ObtainMutex(ctx->sem_id);
+ // Let the main task know this task has been started and owns the mutex.
+ SendEvents(ctx->main_task, FLUSH_EVENT);
+ // Wait for event from main task to ensure this function still holds the
+ // mutex when rtems_semaphore_flush() is called.
+ ReceiveAllEvents(FLUSH_EVENT);
+ ReleaseMutex(ctx->sem_id);
+
+ SendEvents(ctx->main_task, event_send[LAST_TASK]);
+
+ SuspendSelf();
+}
+
+static rtems_id CreateTestMutex(rtems_attribute attr) {
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(rtems_build_name('S', 'E', 'M', '0'), 1, attr, 0, &id);
+ if (sc == RTEMS_NOT_DEFINED)
+ return id;
+
+ if(sc != RTEMS_SUCCESSFUL)
+ return CREATE_TEST_MUTEX_FAILED;
+
+ return id;
+}
+
+static void Init(rtems_task_argument arg) {
+ (void)arg;
+ test_context ctx;
+ char ch;
+ rtems_event_set received = 0;
+ rtems_event_set total_events = 0;
+ char str[ITOA_STR_SIZE];
+ struct timespec uptime, function_wait;
+ uint32_t functions_start, functions_end;
+ rtems_status_code sc;
+ bool sem_create_results[NUMBER_OF_SEM_CREATE_TESTS * LOOPS_PER_TEST] = {false};
+ uint8_t sem_create_index = 0;
+ bool sem_obtain_results[LOOPS_PER_TEST] = {false};
+ bool sem_flush_results[LOOPS_PER_TEST] = {false};
+ bool sem_set_prio_results[NUMBER_OF_SEM_SET_PRIO_TESTS * LOOPS_PER_TEST] = {false};
+ uint8_t sem_set_prio_index = 0;
+
+ SetSelfPriority(PRIO_VERY_ULTRA_HIGH);
+
+ function_wait.tv_sec = 0;
+ function_wait.tv_nsec = FUNCTION_WAIT_NANOSECONDS;
+ ctx.main_task = rtems_task_self();
+ ctx.ntiles = MANDL_TASKS;
+ uint8_t nwaiting = ctx.ntiles;
+
+ ctx.barrier_id = CreateAutomaticBarrier(nwaiting);
+
+ rtems_task_config calc_task_config = {.initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size =
+ MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ // create the mandlebrot set using all available cores minus one
+ for (uint32_t i = 0; i < MANDL_TASKS; i++) {
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ // with the last available core test undefined behaviour semaphores
+
+ // Wait FUNCTION_WAIT_MICROSECONDS microseconds to ensure function calls are concurrent with mandelbrot calculation
+ clock_nanosleep(CLOCK_MONOTONIC, RELATIVE_SLEEP, &function_wait, NULL);
+ rtems_clock_get_uptime(&uptime);
+ functions_start = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ // #################### rtems_semaphore_create ####################
+ // run each trio of tests
+ for (uint32_t tested_sem = 0; tested_sem < NUMBER_OF_SEM_CREATE_TESTS; tested_sem++)
+ {
+ // the first and last run are with a normal configuration, the middle run
+ // is with configuration with undefined behaviour
+ for (uint32_t i = 0; i < LOOPS_PER_TEST; i++)
+ {
+ ctx.sem_obtained = false;
+
+ if (i == 1)
+ {
+ ctx.sem_id = CreateTestMutex(sem_create_attributes[tested_sem].att_config);
+ }
+ else
+ {
+ ctx.sem_id = CreateTestMutex(RTEMS_DEFAULT_ATTRIBUTES);
+ }
+
+ if (ctx.sem_id == INVALID_ID)
+ {
+ // If rtems_semaphore_create() returns RTEMS_NOT_DEFINED for a bad
+ // attribute set this is okay.
+ if(i == 1)
+ {
+ sem_create_results[sem_create_index] = true;
+ }
+
+ sem_create_index++;
+ continue;
+ }
+ else if(ctx.sem_id == CREATE_TEST_MUTEX_FAILED)
+ {
+ sem_create_index++;
+ continue;
+ }
+
+ calc_task_config.name = rtems_build_name('T', 'S', 'E', 'M');
+ calc_task_config.storage_area = &calc_task_storage[LAST_TASK][0];
+
+ ctx.task_id[LAST_TASK] = DoCreateTask(calc_task_config);
+ // execute task that uses the created semaphores
+ ObtainMutex(ctx.sem_id);
+ StartTask(ctx.task_id[LAST_TASK], semaphore_create_test_task, &ctx);
+ ReleaseMutex(ctx.sem_id);
+
+ ReceiveAllEvents(event_send[LAST_TASK]);
+ DeleteMutex(ctx.sem_id);
+ DeleteTask(ctx.task_id[LAST_TASK]);
+
+ // If we get to this point the attribute set was usable and we have not
+ // been able to detect an error from previous attribute sets.
+ if(ctx.sem_obtained == true)
+ {
+ sem_create_results[sem_create_index] = true;
+ }
+
+ sem_create_index++;
+ }
+ }
+
+ // #################### rtems_semaphore_obtain ####################
+ for (uint32_t i = 0; i < LOOPS_PER_TEST; i++)
+ {
+ // test the obtain semaphore function with undefined behaviour attributes
+ ctx.sem_obtained = false;
+ ctx.sem_obtain_attributes = RTEMS_WAIT;
+ ctx.sem_id = CreateMutex(rtems_build_name('S', 'E', 'M', '1'));
+
+ if (i == 1)
+ {
+ ctx.sem_obtain_attributes |= RTEMS_NO_WAIT;
+ }
+
+ calc_task_config.name = rtems_build_name('T', 'S', 'E', 'M');
+ calc_task_config.storage_area = &calc_task_storage[LAST_TASK][0];
+
+ ctx.task_id[LAST_TASK] = DoCreateTask(calc_task_config);
+ // execute task that uses the created semaphores
+ StartTask(ctx.task_id[LAST_TASK], semaphore_obtain_test_task, &ctx);
+ ReceiveAllEvents(event_send[LAST_TASK]);
+ if(ctx.sem_obtained == true)
+ {
+ sem_obtain_results[i] = true;
+ }
+
+ DeleteMutex(ctx.sem_id);
+ DeleteTask(ctx.task_id[LAST_TASK]);
+ }
+
+ // #################### rtems_semaphore_flush ####################
+ for (uint32_t i = 0; i < LOOPS_PER_TEST; i++)
+ {
+ if (i == 1) {
+ ctx.sem_id = CreateMutexMrsP(rtems_build_name('S', 'E', 'M', '2'));
+ } else {
+ ctx.sem_id = CreateMutex(rtems_build_name('S', 'E', 'M', '2'));
+ }
+
+ calc_task_config.name = rtems_build_name('T', 'S', 'E', 'M');
+ calc_task_config.storage_area = &calc_task_storage[LAST_TASK][0];
+
+ ctx.task_id[LAST_TASK] = DoCreateTask(calc_task_config);
+ // execute task that uses the created semaphores
+ StartTask(ctx.task_id[LAST_TASK], semaphore_flush_test_task, &ctx);
+
+ // Ensure flush task has the mutex.
+ ReceiveAllEvents(FLUSH_EVENT);
+ sc = rtems_semaphore_flush(ctx.sem_id);
+ // Allow flush task to continue after we have flushed.
+ SendEvents(ctx.task_id[LAST_TASK], FLUSH_EVENT);
+ if(i == 1)
+ {
+ // We expect RTEMS_NOT_DEFINED for MrsP.
+ if(sc == RTEMS_NOT_DEFINED)
+ sem_flush_results[i] = true;
+ }
+ else
+ {
+ if(sc == RTEMS_SUCCESSFUL)
+ sem_flush_results[i] = true;
+ }
+
+ ReceiveAllEvents(event_send[LAST_TASK]);
+ DeleteMutex(ctx.sem_id);
+ DeleteTask(ctx.task_id[LAST_TASK]);
+ }
+
+ rtems_task_priority old_prio;
+ rtems_id sched_id;
+ // #################### rtems_semaphore_set_priority ####################
+ // run each trio of tests
+ for (uint32_t tested_sem = 0; tested_sem < NUMBER_OF_SEM_SET_PRIO_TESTS; tested_sem++)
+ {
+ for (uint32_t i = 0; i < LOOPS_PER_TEST; i++)
+ {
+ ctx.sem_obtained = false;
+ // test the obtain semaphore function with undefined behaviour attributes
+ if(i == 1)
+ {
+ ctx.sem_id = CreateTestMutex(sem_set_prio_attributes[tested_sem].att_config);
+ }
+ else
+ {
+ // Documentation explicitly states this attribute set makes for a semaphore with configurable priority.
+ ctx.sem_id = CreateTestMutex(RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING);
+ }
+
+ if(ctx.sem_id == INVALID_ID || ctx.sem_id == CREATE_TEST_MUTEX_FAILED)
+ {
+ // Failed to create semaphore with given attribute set so it cannot be tested.
+ sem_set_prio_index++;
+ continue;
+ }
+
+ sc = rtems_task_get_scheduler(RTEMS_SELF, &sched_id);
+ ASSERT_SUCCESS(sc);
+
+ calc_task_config.name = rtems_build_name('T', 'S', 'E', 'M');
+ calc_task_config.storage_area = &calc_task_storage[LAST_TASK][0];
+
+ ctx.task_id[LAST_TASK] = DoCreateTask(calc_task_config);
+ SetScheduler(ctx.task_id[LAST_TASK], sched_id, PRIO_LOW);
+
+ sc = rtems_semaphore_set_priority(ctx.sem_id, sched_id, PRIO_ULTRA_HIGH, &old_prio);
+ if(sc == RTEMS_NOT_DEFINED)
+ {
+ if(i == 1)
+ {
+ sem_set_prio_results[sem_set_prio_index] = true;
+ }
+ }
+ else if(sc == RTEMS_SUCCESSFUL)
+ {
+ StartTask(ctx.task_id[LAST_TASK], semaphore_set_prio_run_task, &ctx);
+ ReceiveAllEvents(event_send[LAST_TASK]);
+ if(ctx.sem_obtained == true)
+ {
+ sem_set_prio_results[sem_set_prio_index] = true;
+ }
+ }
+
+ DeleteMutex(ctx.sem_id);
+ DeleteTask(ctx.task_id[LAST_TASK]);
+ sem_set_prio_index++;
+ }
+ }
+
+ rtems_clock_get_uptime(&uptime);
+ functions_end = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ while (received != total_events) {
+ received |= ReceiveAllEvents(total_events);
+ }
+
+ uint32_t latest_task_start = 0;
+ uint32_t earliest_task_finish = -1;
+ for (uint32_t task = 0; task < MANDL_TASKS; task++) {
+ if (task_before_mandelbrot[task] > latest_task_start)
+ latest_task_start = task_before_mandelbrot[task];
+ if (task_after_mandelbrot[task] < earliest_task_finish)
+ earliest_task_finish = task_after_mandelbrot[task];
+ }
+
+ print_string("Functions and mandelbrot executed concurrently: ");
+ if (functions_start > latest_task_start && functions_end < earliest_task_finish)
+ {
+ print_string("true\n");
+ }
+ else
+ {
+ print_string("false\n");
+
+ print_string("functions start (");
+ print_string(itoa(functions_start, &str[0], 10));
+ print_string(") must be greater than latest task start (");
+ print_string(itoa(latest_task_start, &str[0], 10));
+ print_string(") and functions end (");
+ print_string(itoa(functions_end, &str[0], 10));
+ print_string(") must be less than earliest task finish (");
+ print_string(itoa(earliest_task_finish, &str[0], 10));
+ print_string(")\n");
+ }
+
+
+ // If any of the rtems_semaphore_create() calls went wrong the test failed.
+ bool create_success = true;
+ for(uint8_t i = 0; i < sizeof(sem_create_results)/sizeof(sem_create_results[0]); i++)
+ {
+ if(sem_create_results[i] == false)
+ {
+ print_string("First failing sem create index: ");
+ print_string(itoa(i, &str[0], 10));
+ print_string("\n");
+ print_string("Test attribute set of failing trio: ");
+ print_string(sem_create_attributes[i / LOOPS_PER_TEST].str_output);
+ print_string("\n");
+ create_success = false;
+ break;
+ }
+ }
+
+ print_string("rtems_semaphore_create() unaffected: ");
+ if(create_success)
+ {
+ print_string("true\n");
+ }
+ else
+ {
+ print_string("false\n");
+ }
+
+ // If any of the rtems_semaphore_obtain() calls went wrong the test failed.
+ bool obtain_success = true;
+ for(uint8_t i = 0; i < sizeof(sem_obtain_results)/sizeof(sem_obtain_results[0]); i++)
+ {
+ if(sem_obtain_results[i] == false)
+ {
+ print_string("First failing sem obtain index: ");
+ print_string(itoa(i, &str[0], 10));
+ print_string("\n");
+ obtain_success = false;
+ break;
+ }
+ }
+
+ print_string("rtems_semaphore_obtain() unaffected: ");
+ if(obtain_success)
+ {
+ print_string("true\n");
+ }
+ else
+ {
+ print_string("false\n");
+ }
+
+ // If any of the rtems_semaphore_flush() calls went wrong the test failed.
+ bool flush_success = true;
+ for(uint8_t i = 0; i < sizeof(sem_flush_results)/sizeof(sem_flush_results[0]); i++)
+ {
+ if(sem_flush_results[i] == false)
+ {
+ print_string("First failing sem flush index: ");
+ print_string(itoa(i, &str[0], 10));
+ print_string("\n");
+ flush_success = false;
+ break;
+ }
+ }
+
+ print_string("rtems_semaphore_flush() unaffected: ");
+ if(flush_success)
+ {
+ print_string("true\n");
+ }
+ else
+ {
+ print_string("false\n");
+ }
+
+ // If any of the rtems_semaphore_set_priority() calls went wrong the test failed.
+ bool set_prio_success = true;
+ for(uint8_t i = 0; i < sizeof(sem_set_prio_results)/sizeof(sem_set_prio_results[0]); i++)
+ {
+ if(sem_set_prio_results[i] == false)
+ {
+ print_string("First failing sem set priority index: ");
+ print_string(itoa(i, &str[0], 10));
+ print_string("\n");
+ print_string("Test attribute set of failing trio: ");
+ print_string(sem_set_prio_attributes[i / LOOPS_PER_TEST].str_output);
+ print_string("\n");
+ set_prio_success = false;
+ break;
+ }
+ }
+
+ print_string("rtems_semaphore_set_priority() unaffected: ");
+ if(set_prio_success)
+ {
+ print_string("true\n");
+ }
+ else
+ {
+ print_string("false\n");
+ }
+
+ print_test_results();
+
+ for (uint32_t i = 0; i < MANDL_TASKS; i++) {
+ DeleteTask(ctx.task_id[i]);
+ }
+ DeleteBarrier(ctx.barrier_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_TASKS (TEST_PROCESSORS + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/22_base_defs_undefined_behaviour/base_defs_undefined_behaviour.c b/testsuites/isvv/22_base_defs_undefined_behaviour/base_defs_undefined_behaviour.c
new file mode 100644
index 0000000000..a26b881285
--- /dev/null
+++ b/testsuites/isvv/22_base_defs_undefined_behaviour/base_defs_undefined_behaviour.c
@@ -0,0 +1,338 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+
+/**
+ *
+ * @brief Tests impact of undefined behaviour when using RTEMS_ALIGN_DOWN
+ *
+ * This test case performs the calculation of the Mandelbrot set in parallel with
+ * execution of RTEMS_ALIGN_DOWN directive calls with conditions which lead to
+ * undefined behaviour
+ *
+ */
+
+#define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+// One task for undefined task, and n-1 calculation tasks
+#define TASK_COUNT TEST_PROCESSORS
+
+// We want to create mandelbrot executions whilst our undefined calls are executing
+#define CALCULATION_TASKS ((TEST_PROCESSORS)-1)
+
+#define FUNCTION_CALLS 32
+#define UNDEF_FUNC_CALLS (FUNCTION_CALLS / 2)
+
+uint16_t align_value[FUNCTION_CALLS] = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 64, 127, 255, 256, 257, 511, 512, 513, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 10000, 20000, 30000};
+uint16_t size_target[FUNCTION_CALLS] = {1, 4, 2, 2, 2, 2, 2, 4, 8, 8, 2, 4, 8, 8, 8, 8, 16, 16, 16, 32, 32, 32, 32, 64, 64, 64, 128, 128, 128, 2, 4, 8 };
+int64_t expected_results[FUNCTION_CALLS] = {0, 0, 0, 2, 2, 4, 4, 4, 0, 8, 10, 12, 8, 16, 64, 120, 240, 256, 256, 480, 512, 512, 992, 960, 1024, 1024, 1024, 1024, 1024, 10000, 20000, 30000};
+
+int64_t undef_align_value[UNDEF_FUNC_CALLS] = {0, 3, 10, 6, 16, 100, 128, 312, 10, 10, 2, 3 , 4 , 65535, 65537, 4294967295 };
+int64_t undef_size_target[UNDEF_FUNC_CALLS] = {0, 5, 6, 13, -1, -8, 100,-128, 15, -127, -128, (-2147483647 - 1), 2147483647, 65535, 65537, 4294967295 };
+
+// Barrier to ensure calculation tasks and undefined behaviour tasks occur concurrently
+static rtems_id start_barrier;
+static rtems_id TASK_COUNTER_SEMAPHORE;
+
+// Timing related variables to ensure concurrent executions
+#define RELATIVE_SLEEP 0
+#define FUNCTION_WAIT_MICROSECONDS 10
+#define FUNCTION_WAIT_NANOSECONDS (FUNCTION_WAIT_MICROSECONDS * 1000)
+
+typedef struct
+{
+ rtems_id calc_task_id[CALCULATION_TASKS];
+ rtems_id undefined_task_id;
+ int64_t results[FUNCTION_CALLS];
+ uint32_t functions_start, functions_end;
+} test_context;
+
+// Create storage areas for each worker, using task construct forces
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_ALIGNED(CPU_STACK_ALIGNMENT)
+static uint32_t task_before_mandelbrot[CALCULATION_TASKS];
+
+RTEMS_ALIGNED(CPU_STACK_ALIGNMENT)
+static uint32_t task_after_mandelbrot[CALCULATION_TASKS];
+
+static void calc_task_function(rtems_task_argument *tile)
+{
+ uint8_t tile_n = (uint8_t) *tile;
+ struct timespec uptime;
+
+ WaitAtBarrier(start_barrier);
+
+ // Check time function begins execution of mandelbrot executions
+ rtems_clock_get_uptime(&uptime);
+ task_before_mandelbrot[tile_n - 1] = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ mandelbrot_tile(tile_n, CALCULATION_TASKS);
+
+ // Check time function finishes execution of mandelbrot executions
+ rtems_clock_get_uptime(&uptime);
+ task_after_mandelbrot[tile_n - 1] = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ rtems_task_exit();
+}
+
+static void undefined_behaviour_task(rtems_task_argument arg)
+{
+ test_context *ctx;
+ ctx = (test_context *)arg;
+ struct timespec uptime, function_wait;
+
+ WaitAtBarrier(start_barrier);
+
+ // Wait for 10us to ensure concurrent executions
+ function_wait.tv_sec = 0;
+ function_wait.tv_nsec = FUNCTION_WAIT_NANOSECONDS;
+ clock_nanosleep(CLOCK_MONOTONIC, 0, &function_wait, NULL);
+
+ rtems_clock_get_uptime(&uptime);
+ ctx->functions_start = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ /* Start execution of events related functions following formula of:
+ *
+ * Defined behaviour
+ * Undefined behaviour
+ * Defined behaviour
+ *
+ * The alignment shall be a power of two, otherwise the returned value is undefined.
+ *
+ * Check that RTEMS_ALIGN_DOWN() calculates the expected result and is
+ * side-effect free.
+ *
+ * Alignment downwards aligns this value * down to the nearest multiple of a given size.
+ * This is to proper utilization of a given amount of memory and improve performance.
+ *
+ * The target of this alignment is for computer memory, which for RTEMS is always a power of two,
+ * however the result of the function RTEMS_ALIGN_DOWN should be ensured to be used carefully in
+ * actual program construction as other numbers can be used for the size.
+ *
+ * NOTE: There is a comment in the definition of the RTEMS_ALIGN_DOWN which states that 'the
+ * alignment parameter is evaluated twice.' however this is not the case. This is the case, however,
+ * for RTEMS_ALIGN_UP which performs two evaluations of the alignment parameter and therefore
+ * potentially the cause for the miscommunication.
+ */
+
+ int32_t target;
+ int32_t size;
+
+ for (uint8_t i = 0; i < FUNCTION_CALLS; i+=2) {
+ ctx->results[i] = RTEMS_ALIGN_DOWN(align_value[i], size_target[i]);
+
+ target = undef_align_value[i / 2];
+ size = undef_size_target[i / 2];
+ (void)RTEMS_ALIGN_DOWN(target, size);
+
+ ctx->results[i + 1] = RTEMS_ALIGN_DOWN(align_value[i + 1], size_target[i + 1]);
+ }
+
+ rtems_clock_get_uptime(&uptime);
+ ctx->functions_end = (uint32_t)(uptime.tv_sec * 1000000 + uptime.tv_nsec / 1000);
+
+ // Task has finished so increment counter
+ ReleaseCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ rtems_task_exit();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ char str[ITOA_STR_SIZE];
+ uint8_t wait = 0;
+ uint32_t args[CALCULATION_TASKS] = {0};
+
+ TASK_COUNTER_SEMAPHORE = CreateCounterSemaphore(rtems_build_name('T', 'C', 'S', '0'), 0);
+
+ start_barrier = CreateAutomaticBarrier(TASK_COUNT);
+
+ // Config for our mandelbrot tile function, with priority high as we don't want this to be preempted
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_HIGH,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ // Finish config for our mandelbrot tile functions and start them
+ for (uint32_t i = 0; i < CALCULATION_TASKS; i++)
+ {
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', (char)i);
+ calc_task_config.storage_area = &task_storage[i][0];
+
+ ctx.calc_task_id[i] = DoCreateTask(calc_task_config);
+
+ args[i] = (i + 1);
+ StartTask(ctx.calc_task_id[i], (void *) calc_task_function, (void *) &args[i]);
+ }
+
+ // Config our undefined behaviour task and start it
+ rtems_task_config undef_task_config = {
+ .name = rtems_build_name('U', 'N', 'D', 'F'),
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES,
+ .storage_area = &task_storage[TASK_COUNT-1][0]};
+
+ ctx.undefined_task_id = DoCreateTask(undef_task_config);
+ StartTask(ctx.undefined_task_id, undefined_behaviour_task, (void *)&ctx);
+
+ // Wait for all tasks to complete
+ while (wait < TASK_COUNT)
+ {
+ ObtainCounterSemaphore(TASK_COUNTER_SEMAPHORE);
+ wait++;
+ }
+
+ // Check concurrent execution
+ uint32_t latest_task_start = 0;
+ // Wraps around to effectively be maximum allowed value
+ uint32_t earliest_task_finish = -1;
+
+ for (uint8_t task = 0; task < CALCULATION_TASKS; task++)
+ {
+ latest_task_start = MAX(latest_task_start, task_before_mandelbrot[task]);
+ earliest_task_finish = MIN(earliest_task_finish, task_after_mandelbrot[task]);
+ }
+
+ if ((ctx.functions_start >= latest_task_start && ctx.functions_end <= earliest_task_finish))
+ {
+ print_string("Functions and mandelbrot executed concurrently: true\n\n");
+ }
+ else
+ {
+ print_string("Functions and mandelbrot executed concurrently: false\n\n");
+ }
+
+ // Now check validity of all calls
+ bool all_correct_flag = TRUE;
+ for (uint8_t i = 0; i < FUNCTION_CALLS; i++)
+ {
+ // If our result isn't true like we expect, print out which are unexpected
+ if (ctx.results[i] != expected_results[i])
+ {
+ all_correct_flag = FALSE;
+ print_string("RTEMS_ALIGN_DOWN unexpected result detected: #");
+ print_string(itoa(i, &str[0], 10));
+ print_string(" is not correct and what was received was: ");
+ print_string(itoa(ctx.results[i], &str[0], 10));
+ print_string(" and should have been: ");
+ print_string(itoa(expected_results[i], &str[0], 10));
+ print_string(" for given value: ");
+ print_string(itoa(align_value[i], &str[0], 10));
+ print_string(", and size: ");
+ print_string(itoa(size_target[i], &str[0], 10));
+ print_string("\n");
+ }
+ }
+
+ if (all_correct_flag)
+ {
+ print_string("All alignment calls return expected results: true\n\n");
+ }
+ else
+ {
+ print_string("All alignment calls return expected results: false\n\n");
+ }
+
+ // Print results of mandelbrot test
+ print_test_results();
+
+ rtems_barrier_delete(start_barrier);
+ rtems_semaphore_delete(TASK_COUNTER_SEMAPHORE);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+// Reduce the priority of the Init task so all other tasks can be schedules to all other cores
+#define CONFIGURE_INIT_TASK_PRIORITY PRIO_LOW
+
+#define CONFIGURE_MAXIMUM_BARRIERS 1
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+// Number of Tasks configured + 1 for the INIT task
+#define CONFIGURE_MAXIMUM_TASKS ((TASK_COUNT) + 1)
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h> \ No newline at end of file
diff --git a/testsuites/isvv/23.10_uni_cache_l2_enabled/uni_cache_l2_enabled.c b/testsuites/isvv/23.10_uni_cache_l2_enabled/uni_cache_l2_enabled.c
new file mode 100644
index 0000000000..25bba95bd4
--- /dev/null
+++ b/testsuites/isvv/23.10_uni_cache_l2_enabled/uni_cache_l2_enabled.c
@@ -0,0 +1,366 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache disable/enable
+ *
+ * Step 1: Uniprocessor case
+ *
+ * In this step the same set of math equations used by several tasks in the
+ * Multiprocessor version are run in an Uniprocessor and ONE task only environment
+ * in order to achieve a reference output result for comparison.
+ *
+ * There is only one set of math equations processed here:
+ * - named "filter_simulation"
+ *
+ * Result values are obtained for later comparison with multiprocessor
+ * versions. Also some internal cache statistics are shown. Most relevant one is the
+ * Elapsed time and L2 cache misses.
+ *
+ */
+
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 1
+
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ uint64_t accxL2;
+} test_context;
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-----------------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2Mbytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512kbytes
+#define xL2_ELEM (L2_CACHE_SIZE/sizeof(uint32_t)) // 512k elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+//-----------------------------------------------------------------------------------------
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void){
+ uint64_t acc = 0;
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j++)
+ acc += xL2[j];
+ return acc;
+}
+
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems){
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = begin_idx ; j <= end_idx; j ++) {
+ uint32_t i;
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*1/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*2/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*3/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*4/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*5/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*6/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*7/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ // Simulating normalization
+ t3 = ((t1*1000)/(42*137)) + 1;
+ t4 = ((t2*10)/(96*137)) + 1;
+ uint64_t t5 = (uint64_t)t3 * (uint64_t)t3;
+ uint64_t t6 = (uint64_t)t4 * (uint64_t)t4;
+ acc += (t5+t6)/((uint64_t)isqrt(t4+t3));
+ }
+ return acc;
+}
+
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char str[ITOA_STR_SIZE];
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+ SetSelfPriority( PRIO_NORMAL );
+
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Do the work
+//-----------------------------------------------------------------------------
+ start_time = rtems_clock_get_ticks_since_boot();
+ ctx.accxL2 = calc_filter_simulation_equation(0, 1);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Single Core Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_TASKS TEST_PROCESSORS
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.11_multi_cache_l2_enabled/multi_cache_l2_enabled.c b/testsuites/isvv/23.11_multi_cache_l2_enabled/multi_cache_l2_enabled.c
new file mode 100644
index 0000000000..99b2abcf33
--- /dev/null
+++ b/testsuites/isvv/23.11_multi_cache_l2_enabled/multi_cache_l2_enabled.c
@@ -0,0 +1,489 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache enabled/disable
+ *
+ * Step 2: Multiprocessor with L2 cache enabled
+ *
+ * There is one set of math equations processed:
+ * - named "filter_simulation"
+ *
+ * The equations for "filter_simulation" are used by TEST_PROCESSORS tasks that
+ * processes small sections of a "data array" in parallel.
+ *
+ * The locations in memory for acessing the small sections of the "data arrays" do
+ * overlap in terms of cache memory positions, and when acessing one section of the
+ * "data array", or even a smaller part of one, other sections of that "data array"
+ * should be kicked out of the cache. Sometimes that may happen within the same task.
+ *
+ * With the "L2 cache" disabled, every data word missed in l1 cache must be retreived
+ * from the main memory which can be significantly slower that L2 Cache. With the
+ * "L2 cache" enabled, in the case of a l2 cache hit a small number of data words
+ * are transactioned with the L1 cache right away, avoiding acessing the slower main
+ * memory.
+ *
+ * Expected Results:
+ * - The Tiles must be processed only once.
+ * - "Ouput Data Result Value" must match with the Uniprocessor version and with the
+ * Multiprocessor version with L2 cache disabled.
+ * - Elapsed Time should be lower than the Uniprocessor version, and also lower
+ * than Multiprocessor version with L2 cache disable.
+ * - Significant number of L2 cache misses
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+#define MAX_MESSAGE_QUEUES 5
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT];
+ rtems_id mutex_id;
+ uint64_t accxL2;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-----------------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2Mbytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512kbytes
+#define xL2_ELEM (L2_CACHE_SIZE/sizeof(uint32_t)) // 512k elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+//-----------------------------------------------------------------------------------------
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void){
+ uint64_t acc = 0;
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j++)
+ acc += xL2[j];
+ return acc;
+}
+
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems){
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = begin_idx ; j <= end_idx; j ++) {
+ uint32_t i;
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*1/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*2/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*3/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*4/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*5/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*6/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*7/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ // Simulating normalization
+ t3 = ((t1*1000)/(42*137)) + 1;
+ t4 = ((t2*10)/(96*137)) + 1;
+ uint64_t t5 = (uint64_t)t3 * (uint64_t)t3;
+ uint64_t t6 = (uint64_t)t4 * (uint64_t)t4;
+ acc += (t5+t6)/((uint64_t)isqrt(t4+t3));
+ }
+ return acc;
+}
+
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ test_context *ctx;
+ uint64_t acc;
+
+ ctx = (test_context *)arg;
+
+ uint8_t tile;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+
+ for (int i = 0; i < TASK_COUNT; i++){
+ if (ctx->task_id[i] == local_id){
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles) {
+ acc = 0;
+ count_process[tile - 1]++;
+ acc = calc_filter_simulation_equation(tile-1, ctx->ntiles);
+
+ ObtainMutex(ctx->mutex_id);
+ ctx->accxL2 += acc;
+ ReleaseMutex(ctx->mutex_id);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch, str[ITOA_STR_SIZE];
+ uint32_t total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ctx.mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', 'X'));
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+ SetSelfPriority( PRIO_NORMAL );
+
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Do the work: distribute the work through the tasks
+//-----------------------------------------------------------------------------
+ start_time = rtems_clock_get_ticks_since_boot();
+ while (ReceiveAvailableEvents() != total_events)
+ {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+ ctx.next_tile++;
+ }
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ DeleteTask(ctx.task_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+ DeleteMessageQueue(ctx.tile_queue);
+
+ DeleteMutex(ctx.mutex_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_TASKS ( TEST_PROCESSORS + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.12_multi_cache_l2_disabled/multi_cache_l2_disabled.c b/testsuites/isvv/23.12_multi_cache_l2_disabled/multi_cache_l2_disabled.c
new file mode 100644
index 0000000000..dbdcee164f
--- /dev/null
+++ b/testsuites/isvv/23.12_multi_cache_l2_disabled/multi_cache_l2_disabled.c
@@ -0,0 +1,491 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache enabled/disable
+ *
+ * Step 3: Multiprocessor with L2 cache disable
+ *
+ * There is one set of math equations processed:
+ * - named "filter_simulation"
+ *
+ * The equations for "filter_simulation" are used by TEST_PROCESSORS tasks that
+ * processes small sections of a "data array" in parallel.
+ *
+ * The locations in memory for acessing the small sections of the "data arrays" do
+ * overlap in terms of cache memory positions, and when acessing one section of the
+ * "data array", or even a smaller part of one, other sections of that "data array"
+ * should be kicked out of the cache. Sometimes that may happen within the same task.
+ *
+ * With the "L2 cache" disabled, every data word missed in l1 cache must be retreived
+ * from the main memory which can be significantly slower that L2 Cache. With the
+ * "L2 cache" enabled, in the case of a l2 cache hit a small number of data words
+ * are transactioned with the L1 cache right away, avoiding acessing the slower main
+ * memory.
+ *
+ * Expected Results:
+ * - The Tiles must be processed only once.
+ * - "Ouput Data Result Value" must match with the Uniprocessor version with the
+ * Multiprocessor version with L2 cache enabled.
+ * - Elapsed Time should be lower than the Uniprocessor version, but higher
+ * than Multiprocessor version with L2 cache disable.
+ * - Zero L2 cache misses reported
+ *
+ */
+
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+#define MAX_MESSAGE_QUEUES 5
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT];
+ rtems_id mutex_id;
+ uint64_t accxL2;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-----------------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2Mbytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512kbytes
+#define xL2_ELEM (L2_CACHE_SIZE/sizeof(uint32_t)) // 512k elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+//-----------------------------------------------------------------------------------------
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void){
+ uint64_t acc = 0;
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j++)
+ acc += xL2[j];
+ return acc;
+}
+
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems){
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = begin_idx ; j <= end_idx; j ++) {
+ uint32_t i;
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*1/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*2/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*3/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*4/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*5/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*6/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < 128; i++)
+ t2 += xL2[(j+i+L2_CACHE_WAY_SIZE*7/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ // Simulating normalization
+ t3 = ((t1*1000)/(42*137)) + 1;
+ t4 = ((t2*10)/(96*137)) + 1;
+ uint64_t t5 = (uint64_t)t3 * (uint64_t)t3;
+ uint64_t t6 = (uint64_t)t4 * (uint64_t)t4;
+ acc += (t5+t6)/((uint64_t)isqrt(t4+t3));
+ }
+ return acc;
+}
+
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ test_context *ctx;
+ uint64_t acc;
+
+ ctx = (test_context *)arg;
+
+ uint8_t tile;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+
+ for (int i = 0; i < TASK_COUNT; i++){
+ if (ctx->task_id[i] == local_id){
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles) {
+ acc = 0;
+ count_process[tile - 1]++;
+ acc = calc_filter_simulation_equation(tile-1, ctx->ntiles);
+
+ ObtainMutex(ctx->mutex_id);
+ ctx->accxL2 += acc;
+ ReleaseMutex(ctx->mutex_id);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg)
+{
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch, str[ITOA_STR_SIZE];
+ uint32_t total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ctx.mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', 'X'));
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+ SetSelfPriority( PRIO_NORMAL );
+
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Do the work: distribute the work through the tasks
+//-----------------------------------------------------------------------------
+ start_time = rtems_clock_get_ticks_since_boot();
+ while (ReceiveAvailableEvents() != total_events)
+ {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+ ctx.next_tile++;
+ }
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+ print_string("\n");
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ DeleteTask(ctx.task_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+ DeleteMessageQueue(ctx.tile_queue);
+
+ DeleteMutex(ctx.mutex_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_TASKS ( TEST_PROCESSORS + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.1_uni_cache_way_locking_disabled/uni_cache_way_locking_disabled.c b/testsuites/isvv/23.1_uni_cache_way_locking_disabled/uni_cache_way_locking_disabled.c
new file mode 100644
index 0000000000..217e1fa972
--- /dev/null
+++ b/testsuites/isvv/23.1_uni_cache_way_locking_disabled/uni_cache_way_locking_disabled.c
@@ -0,0 +1,538 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache way locking
+ *
+ * Step 1: Uniprocessor case
+ *
+ * In this step the same set of math equations used by several tasks in the
+ * Multiprocessor version are run in an Uniprocessor and ONE task only environment
+ * in order to achieve a reference output result for comparison .
+ *
+ * There are two main sets of math equations processed here:
+ * - one named "filter_simulation"
+ * - and other named "snr_processing"
+ *
+ * For each one, result values are obtained for later comparison with multiprocessor
+ * versions. Also some internal cache statistics are shown. Most relevant one is the number of
+ * L2 cache misses, which when increased significantly, may delay the data processing.
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) use make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) use and declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+
+// test specific global vars
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 1
+
+#define TASK_COUNT (2+2) //2 parallel tasks for "filter simulation" and
+ // another 2 sequential tasks for "snr processing"
+#define TOTAL_TILES 192
+
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+const rtems_event_set event_send[6] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4,
+ RTEMS_EVENT_5,
+ RTEMS_EVENT_6
+ };
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ uint8_t ntiles;
+ uint8_t next_tile;
+ float filter_sim_process_time;
+ uint64_t accxL2;
+ float snr_process_time;
+ float scaling_fft_factor;
+} test_context;
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2M bytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512k bytes
+#define xL2_ELEM (2*L2_CACHE_SIZE/sizeof(uint32_t)) // 1M elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+//-------------------------------------------------------------------------------
+#define MAX_ITER (TOTAL_TILES*1/3)
+#define FFT_SIZE (65536U)
+#define FFT_SIZE_LOG2 (16U)
+#define TC_MAX (16U)
+#define FILTER_REPETITIONS (2U)
+#define SNR_THRESHOLD (1000000.0f)
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = { 2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U };
+const float NOISE_FACTOR[TC_MAX] = { 0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f };
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataRe[FFT_SIZE];
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataIm[FFT_SIZE];
+static uint8_t dsp_result[MAX_ITER];
+
+
+//=======================================================================================
+// Auxiliary Functions
+//=======================================================================================
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void) {
+ uint32_t j;
+ uint64_t volatile acc = 0;
+
+ // This data should be cached in way #1
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += xL2[j];
+
+ // This data should be cached in way #2
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += xL2[j+(L2_CACHE_WAY_SIZE/sizeof(uint32_t))];
+
+ // This data should be cached in way #3
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += inSensorDataRe[j];
+
+ // This data should be cached in way #4
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += inSensorDataIm[j];
+
+ return acc;
+}
+
+
+//=======================================================================================
+// "filter_simulation" Tasks/Functions
+//=======================================================================================
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems) {
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = 0 ; j <= FILTER_REPETITIONS; j++ ) {
+ uint32_t i;
+
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < FFT_SIZE; i++) {
+ t1 += xL2[(j+i+0*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+1*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+2*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+3*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+4*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+5*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+6*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+7*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ }
+
+ // Simulating normalization
+ t3 = ((t1*100)/(42*137)) + xL2[(begin_idx) % xL2_ELEM] ;
+ t4 = ((t2*10)/(96*137)) + xL2[(end_idx) % xL2_ELEM] ;
+ acc += (t3+t4);
+ }
+ return acc;
+}
+
+static uint64_t function_calc_filter_simulation(test_context *ctx) {
+ struct timespec begin_time;
+ struct timespec end_time;
+ static uint64_t acc = 0;
+
+ rtems_clock_get_uptime(&begin_time);
+
+ for (uint32_t i = 0; i < TOTAL_TILES; i++)
+ acc += calc_filter_simulation_equation(i, TOTAL_TILES);
+
+ rtems_clock_get_uptime(&end_time);
+ ctx->filter_sim_process_time +=
+ (float)(end_time.tv_sec - begin_time.tv_sec) +
+ ( (float)((end_time.tv_nsec/1000) - (begin_time.tv_nsec/1000))/1000000.0);
+
+ return acc;
+}
+
+
+//=======================================================================================
+// "snr_processing" Tasks/Functions
+//=======================================================================================
+static void function_snr_read_sensor_data( uint32_t iter) {
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = 0.4995f * cos_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter%TC_MAX]);
+ inSensorDataIm[i] = 0.4995f * sin_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ }
+}
+
+static void function_snr_process_data(test_context *ctx, uint32_t iter) {
+ struct timespec begin_time;
+ struct timespec end_time;
+
+ rtems_clock_get_uptime(&begin_time);
+
+ //Apply Blackman-Harris Window
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = inSensorDataRe[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ inSensorDataIm[i] = inSensorDataIm[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ }
+
+ //Calculates FFT
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ //Calculates the magnitude values
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = (inSensorDataRe[i] * inSensorDataRe[i]
+ + inSensorDataIm[i] * inSensorDataIm[i]) / ((float)FFT_SIZE);
+ }
+
+ //Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ float maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if (inSensorDataRe[i] > maxValue) {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ //Calculates the signal and noise power (no DC)
+ float sig = 0.0f;
+ float noise = 0.0f;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if ((i > maxValueIndex - 8) && (i < maxValueIndex + 8)) {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+
+ if (!(sig > 0.0f)) { sig = 0.0000000001f; }
+ if (!(noise > 0.0f)) { noise = 0.0000000001f; }
+
+ //Calculates SNR
+ float snr_float = sig/noise;
+
+ if (snr_float > SNR_THRESHOLD) {
+ dsp_result[iter] = 1;
+ }
+ else {
+ dsp_result[iter] = 0;
+ }
+ rtems_clock_get_uptime(&end_time);
+
+ ctx->snr_process_time +=
+ (float)(end_time.tv_sec - begin_time.tv_sec) +
+ ( (float)((end_time.tv_nsec/1000) - (begin_time.tv_nsec/1000))/1000000.0);
+}
+
+
+//=======================================================================================
+// INIT/MAIN Task
+//=======================================================================================
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char str[ITOA_STR_SIZE];
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+ (void) memset(&inSensorDataRe[0], 0, FFT_SIZE);
+ (void) memset(&inSensorDataIm[0], 0, FFT_SIZE);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+ SetSelfPriority( PRIO_NORMAL );
+
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_enable_split_responses();
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+ //Calculates mean of Blackman-Harris terms
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i<FFT_SIZE; i++){
+ ctx.scaling_fft_factor += blackman_harris( i, FFT_SIZE);
+ }
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor/ ((float) FFT_SIZE);
+
+//-----------------------------------------------------------------------------
+// Do the work
+//-----------------------------------------------------------------------------
+ start_time = rtems_clock_get_ticks_since_boot();
+ ctx.accxL2 = function_calc_filter_simulation(&ctx);
+
+ uint32_t start_idx = 0;
+ for (uint32_t iter=0; iter<MAX_ITER; iter++, start_idx += FFT_SIZE) {
+ function_snr_read_sensor_data(iter);
+ function_snr_process_data(&ctx, iter) ;
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Single Core Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+ print_string("Time used in filter sim processing : ");
+ print_string(itoa( (int32_t) (ctx.filter_sim_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("Time used in SNR processing : ");
+ print_string(itoa( (int32_t) (ctx.snr_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("SNR triggers found at : ");
+ for (uint32_t j = 0; j < MAX_ITER; j++)
+ if (dsp_result[j] > 0.0){
+ print_string(itoa(j, &str[0], 10));
+ print_string(" ");
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_TASKS TEST_PROCESSORS
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.2_multi_cache_way_locking_disabled/multi_cache_way_locking_disabled.c b/testsuites/isvv/23.2_multi_cache_way_locking_disabled/multi_cache_way_locking_disabled.c
new file mode 100644
index 0000000000..8f88b196ec
--- /dev/null
+++ b/testsuites/isvv/23.2_multi_cache_way_locking_disabled/multi_cache_way_locking_disabled.c
@@ -0,0 +1,699 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache way locking
+ *
+ * Step 2: Multiprocessor with L2 cache way locking disable
+ *
+ * There are two main math set of equations used here:
+ * - one named "filter_simulation"
+ * - and other named "snr_processing"
+ *
+ * The equations for "filter_simulation" are used by TWO tasks that processes small
+ * sections of a "data array" in parallel.
+ * The equations for "snr_processing" are used by TWO tasks that processes small
+ * sections of other "data array" in sequential order, but in parallel with the other
+ * tasks.
+ *
+ * The locations in memory for both "data arrays" do overlap in terms of cache memory
+ * positions, and when acessing one "data array", or part of one, other sections of
+ * the other "data array" should be kicked out of the cache. Sometimes that should
+ * also happen within the same "data array".
+ *
+ * Expected Results:
+ * - The Tiles must be processed only once.
+ * - "Ouput Data Result Value" must match with the Uniprocessor version.
+ * - SNR triggers index positions must match with the ones from the Uniprocessor version.
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) use make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) use and declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+
+// test specific global vars
+#define TASK_COUNT (2+2) //2 parallel tasks for "filter simulation" and
+ // another 2 sequential tasks for "snr processing"
+#define TOTAL_TILES 192
+
+#define MAX_MESSAGE_QUEUES 6
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+const rtems_event_set event_send[6] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4,
+ RTEMS_EVENT_5,
+ RTEMS_EVENT_6
+ };
+
+#define EVENT_GO_READ_SENSOR RTEMS_EVENT_10
+#define EVENT_DATA_READY RTEMS_EVENT_11
+#define EVENT_DATA_WAS_PROCESSED RTEMS_EVENT_12
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_filter_simulation_id[TEST_PROCESSORS];
+ rtems_id tile_queue;
+ rtems_id message_queue[TEST_PROCESSORS];
+ rtems_id filter_mutex_id;
+ float filter_sim_process_time;
+ uint64_t accxL2;
+ rtems_id task_snr_process_data_id;
+ rtems_id task_snr_read_sensor_data_id;
+ rtems_id snr_mutex_id;
+ float snr_process_time;
+ float scaling_fft_factor;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2M bytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512k bytes
+#define xL2_ELEM (2*L2_CACHE_SIZE/sizeof(uint32_t)) // 1M elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+//-------------------------------------------------------------------------------
+#define MAX_ITER (TOTAL_TILES*1/3)
+#define FFT_SIZE (65536U)
+#define FFT_SIZE_LOG2 (16U)
+#define TC_MAX (16U)
+#define FILTER_REPETITIONS (2U)
+#define SNR_THRESHOLD (1000000.0f)
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = { 2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U };
+const float NOISE_FACTOR[TC_MAX] = { 0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f };
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataRe[FFT_SIZE];
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataIm[FFT_SIZE];
+static uint8_t dsp_result[MAX_ITER];
+
+
+//=======================================================================================
+// Auxiliary /Functions
+//=======================================================================================
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void) {
+ uint32_t j;
+ uint64_t volatile acc = 0;
+
+ // This data should be cached in way #1
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += xL2[j];
+
+ // This data should be cached in way #2
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += xL2[j+(L2_CACHE_WAY_SIZE/sizeof(uint32_t))];
+
+ // This data should be cached in way #3
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += inSensorDataRe[j];
+
+ // This data should be cached in way #4
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += inSensorDataIm[j];
+
+ return acc;
+}
+
+
+//=======================================================================================
+// "filter_simulation" Tasks/Functions
+//=======================================================================================
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems) {
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = 0 ; j <= FILTER_REPETITIONS; j++ ) {
+ uint32_t i;
+
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < FFT_SIZE; i++) {
+ t1 += xL2[(j+i+0*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+1*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+2*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+3*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+4*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+5*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+6*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+7*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ }
+
+ // Simulating normalization
+ t3 = ((t1*100)/(42*137)) + xL2[(begin_idx) % xL2_ELEM] ;
+ t4 = ((t2*10)/(96*137)) + xL2[(end_idx) % xL2_ELEM] ;
+ acc += (t3+t4);
+ }
+ return acc;
+}
+
+
+static void calc_task_function(rtems_task_argument arg) {
+ test_context *ctx;
+ uint64_t acc;
+ struct timespec begin_time;
+ struct timespec end_time;
+ uint8_t tile = 0;
+ uint8_t task_idx = 255;
+
+ ctx = (test_context *)arg;
+ rtems_id local_id = TaskSelfId();
+
+ for (int i = 0; i < TASK_COUNT; i++){
+ if (ctx->task_filter_simulation_id[i] == local_id){
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles) {
+ count_process[tile - 1]++;
+ rtems_clock_get_uptime(&begin_time);
+ acc = calc_filter_simulation_equation(tile-1, ctx->ntiles);
+ rtems_clock_get_uptime(&end_time);
+
+ ObtainMutex(ctx->filter_mutex_id);
+ ctx->filter_sim_process_time += (float)(end_time.tv_sec - begin_time.tv_sec)
+ + ( (float)(end_time.tv_nsec/1000 - begin_time.tv_nsec/1000)/1000000.0);
+ ctx->accxL2 += acc;
+ ReleaseMutex(ctx->filter_mutex_id);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+
+//=======================================================================================
+// "snr_processing" Tasks/Functions
+//=======================================================================================
+static void task_snr_read_sensor_data(rtems_task_argument arg){
+ test_context *ctx;
+ uint32_t iter = 0;
+
+ ctx = (test_context *)arg;
+
+ ReceiveAllEvents(EVENT_GO_READ_SENSOR);
+
+ while ( iter < MAX_ITER) {
+ ObtainMutex(ctx->snr_mutex_id);
+
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = 0.4995f * cos_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter%TC_MAX]);
+ inSensorDataIm[i] = 0.4995f * sin_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ }
+
+ ReleaseMutex(ctx->snr_mutex_id);
+ SendEvents(ctx->task_snr_process_data_id, EVENT_DATA_READY);
+
+ iter++;
+ ReceiveAllEvents(EVENT_DATA_WAS_PROCESSED);
+ }
+
+ rtems_event_send(ctx->main_task, event_send[(TASK_COUNT-2)]);
+ SuspendSelf();
+}
+
+static void task_snr_process_data(rtems_task_argument arg) {
+ test_context *ctx;
+ ctx = (test_context *)arg;
+ uint32_t iter = 0;
+ struct timespec begin_time;
+ struct timespec end_time;
+
+ while ( iter < MAX_ITER ) {
+ ReceiveAllEvents(EVENT_DATA_READY);
+ ObtainMutex(ctx->snr_mutex_id);
+ rtems_clock_get_uptime(&begin_time);
+
+ //Apply Blackman-Harris Window
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = inSensorDataRe[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ inSensorDataIm[i] = inSensorDataIm[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ }
+
+ //Calculates FFT
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ //Calculates the magnitude values
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = (inSensorDataRe[i] * inSensorDataRe[i]
+ + inSensorDataIm[i] * inSensorDataIm[i]) / ((float)FFT_SIZE);
+ }
+
+ //Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ float maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if (inSensorDataRe[i] > maxValue) {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ //Calculates the signal and noise power (no DC)
+ float sig = 0.0f;
+ float noise = 0.0f;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if ((i > maxValueIndex - 8) && (i < maxValueIndex + 8)) {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+
+ if (!(sig > 0.0f)) { sig = 0.0000000001f; }
+ if (!(noise > 0.0f)) { noise = 0.0000000001f; }
+
+ //Calculates SNR
+ float snr_float = sig/noise;
+
+ if (snr_float > SNR_THRESHOLD) {
+ dsp_result[iter] = 1;
+ }
+ else {
+ dsp_result[iter] = 0;
+ }
+ rtems_clock_get_uptime(&end_time);
+
+ ctx->snr_process_time +=
+ (float)(end_time.tv_sec - begin_time.tv_sec) +
+ ( (float)((end_time.tv_nsec/1000) - (begin_time.tv_nsec/1000))/1000000.0);
+
+ ReleaseMutex(ctx->snr_mutex_id);
+ iter++;
+ SendEvents(ctx->task_snr_read_sensor_data_id, EVENT_DATA_WAS_PROCESSED);
+ }
+
+ rtems_event_send(ctx->main_task, event_send[(TASK_COUNT-1)]);
+ SuspendSelf();
+}
+
+
+//=======================================================================================
+// INIT/MAIN Task
+//=======================================================================================
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch, str[ITOA_STR_SIZE];
+ uint32_t total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+ (void) memset(&inSensorDataRe[0], 0, FFT_SIZE);
+ (void) memset(&inSensorDataIm[0], 0, FFT_SIZE);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ctx.filter_mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', '0'));
+ ctx.snr_mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', '1'));
+ SetSelfPriority( PRIO_NORMAL );
+
+ for (uint32_t i = 0; i < TASK_COUNT-2; i++){
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_filter_simulation_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_filter_simulation_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ ch = '0' + (TASK_COUNT-2);
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[(TASK_COUNT-2)][0];
+ ctx.task_snr_read_sensor_data_id = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_snr_read_sensor_data_id, task_snr_read_sensor_data, &ctx);
+
+ ch = '0' + (TASK_COUNT-1);
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[(TASK_COUNT-1)][0];
+ ctx.task_snr_process_data_id = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_snr_process_data_id, task_snr_process_data, &ctx);
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_enable_split_responses();
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+ //Calculates mean of Blackman-Harris terms --> to scale a bit the FFT
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i<FFT_SIZE; i++){
+ ctx.scaling_fft_factor += blackman_harris( i, FFT_SIZE);
+ }
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor/ ((float) FFT_SIZE);
+
+//-----------------------------------------------------------------------------
+// Do the work: distribute the work through the tasks
+//-----------------------------------------------------------------------------
+ SendEvents(ctx.task_snr_read_sensor_data_id, EVENT_GO_READ_SENSOR);
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ rtems_event_set revents = ReceiveAvailableEvents();
+ while ( (revents & total_events) != total_events ) {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+ ctx.next_tile++;
+ revents = ReceiveAvailableEvents();
+ }
+ // Wait for the SNR tasks to finish
+ ReceiveAllEvents(event_send[(TASK_COUNT-2)]);
+ ReceiveAllEvents(event_send[(TASK_COUNT-1)]);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+ print_string("Time used in filter sim processing : ");
+ print_string(itoa( (int32_t) (ctx.filter_sim_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("Time used in SNR processing : ");
+ print_string(itoa( (int32_t) (ctx.snr_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("SNR triggers found at : ");
+ for (uint32_t j = 0; j < MAX_ITER; j++)
+ if (dsp_result[j] > 0.0){
+ print_string(itoa(j, &str[0], 10));
+ print_string(" ");
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+ for (uint32_t i = 0; i < (TASK_COUNT-2); i++){
+ DeleteTask(ctx.task_filter_simulation_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+
+ DeleteTask(ctx.task_snr_process_data_id);
+ DeleteTask(ctx.task_snr_read_sensor_data_id);
+
+ DeleteMutex(ctx.filter_mutex_id);
+ DeleteMutex(ctx.snr_mutex_id);
+
+ DeleteMessageQueue(ctx.tile_queue);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 2
+
+#define CONFIGURE_MAXIMUM_TASKS ( TASK_COUNT + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.3_multi_cache_way_locking_enabled/multi_cache_way_locking_enabled.c b/testsuites/isvv/23.3_multi_cache_way_locking_enabled/multi_cache_way_locking_enabled.c
new file mode 100644
index 0000000000..e6efbc9f15
--- /dev/null
+++ b/testsuites/isvv/23.3_multi_cache_way_locking_enabled/multi_cache_way_locking_enabled.c
@@ -0,0 +1,713 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache way locking
+ *
+ * Step 3: Multiprocessor with L2 cache way locking enable
+ *
+ * There are two main math set of equations used here:
+ * - one named "filter_simulation"
+ * - and other named "snr_processing"
+ *
+ * The equations for "filter_simulation" are used by TWO tasks that processes small
+ * sections of a "data array" in parallel.
+ * The equations for "snr_processing" are used by TWO tasks that processes small
+ * sections of other "data array" in sequential order, but in parallel with the other
+ * tasks.
+ *
+ * The locations in memory for both "data arrays" do overlap in terms of cache memory
+ * positions, and when acessing one "data array", or part of one, other sections of
+ * the other "data array" should be kicked out of the cache. Sometimes that should
+ * also happen within the same "data array".
+ *
+ * With the "L2 cache way locking" enabled for 2 of the 4 cache ways, the data array
+ * associated with the "snr_processing" is never kicked out the L2 cache. But in other
+ * hand but there is less ways available for the "filter_simulation" processing, and
+ * its stumbles a lot during the processing of its "data array".
+ *
+ * Expected Results:
+ * - The Tiles must be processed only once.
+ * - "Ouput Data Result Value" must match with the Uniprocessor version
+ * and Multiprocessor version with L2 cache way locking disable.
+ * - SNR triggers index positions must match with the ones from the Multiprocessor
+ * version with L2 cache way locking disable version and with the Uniprocessor
+ * version.
+ * - Time spent for "snr_processing" should be slightly lower than the Multiprocessor
+ * version with L2 cache way locking disable (due to the L2 cache way locking
+ * enabled for the arrays associated to way#3 and way#4).
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) use make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) use and declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+
+// test specific global vars
+#define TASK_COUNT (2+2) //2 parallel tasks for "filter simulation" and
+ // another 2 sequential tasks for "snr processing"
+#define TOTAL_TILES 192
+
+#define MAX_MESSAGE_QUEUES 6
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+const rtems_event_set event_send[6] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4,
+ RTEMS_EVENT_5,
+ RTEMS_EVENT_6
+ };
+
+#define EVENT_GO_READ_SENSOR RTEMS_EVENT_10
+#define EVENT_DATA_READY RTEMS_EVENT_11
+#define EVENT_DATA_WAS_PROCESSED RTEMS_EVENT_12
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_filter_simulation_id[TEST_PROCESSORS];
+ rtems_id tile_queue;
+ rtems_id message_queue[TEST_PROCESSORS];
+ rtems_id filter_mutex_id;
+ float filter_sim_process_time;
+ uint64_t accxL2;
+ rtems_id task_snr_process_data_id;
+ rtems_id task_snr_read_sensor_data_id;
+ rtems_id snr_mutex_id;
+ float snr_process_time;
+ float scaling_fft_factor;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2M bytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512k bytes
+#define xL2_ELEM (2*L2_CACHE_SIZE/sizeof(uint32_t)) // 1M elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+//-------------------------------------------------------------------------------
+#define MAX_ITER (TOTAL_TILES*1/3)
+#define FFT_SIZE (65536U)
+#define FFT_SIZE_LOG2 (16U)
+#define TC_MAX (16U)
+#define FILTER_REPETITIONS (2U)
+#define SNR_THRESHOLD (1000000.0f)
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = { 2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U };
+const float NOISE_FACTOR[TC_MAX] = { 0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f };
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataRe[FFT_SIZE];
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataIm[FFT_SIZE];
+static uint8_t dsp_result[MAX_ITER];
+
+
+//=======================================================================================
+// Auxiliary /Functions
+//=======================================================================================
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void) {
+ uint32_t j;
+ uint64_t volatile acc = 0;
+
+ // This data should be cached in way #1
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += xL2[j];
+
+ // This data should be cached in way #2
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += xL2[j+(L2_CACHE_WAY_SIZE/sizeof(uint32_t))];
+
+ // This data should be cached in way #3
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += inSensorDataRe[j];
+
+ // This data should be cached in way #4
+ for ( j = 0 ; j < FFT_SIZE; j++)
+ acc += inSensorDataIm[j];
+
+ return acc;
+}
+
+
+//=======================================================================================
+// "filter_simulation" Tasks/Functions
+//=======================================================================================
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems) {
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = 0 ; j <= FILTER_REPETITIONS; j++ ) {
+ uint32_t i;
+
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < FFT_SIZE; i++) {
+ t1 += xL2[(j+i+0*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+1*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+2*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+3*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+4*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+5*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+6*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ t1 += xL2[(j+i+7*(L2_CACHE_WAY_SIZE/sizeof(uint32_t))) % xL2_ELEM] * coefs[i % COEFS_SIZE];
+ }
+
+ // Simulating normalization
+ t3 = ((t1*100)/(42*137)) + xL2[(begin_idx) % xL2_ELEM] ;
+ t4 = ((t2*10)/(96*137)) + xL2[(end_idx) % xL2_ELEM] ;
+ acc += (t3+t4);
+ }
+ return acc;
+}
+
+
+static void calc_task_function(rtems_task_argument arg) {
+ test_context *ctx;
+ uint64_t acc;
+ struct timespec begin_time;
+ struct timespec end_time;
+ uint8_t tile = 0;
+ uint8_t task_idx = 255;
+
+ ctx = (test_context *)arg;
+ rtems_id local_id = TaskSelfId();
+
+ for (int i = 0; i < TASK_COUNT; i++){
+ if (ctx->task_filter_simulation_id[i] == local_id){
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles) {
+ count_process[tile - 1]++;
+ rtems_clock_get_uptime(&begin_time);
+ acc = calc_filter_simulation_equation(tile-1, ctx->ntiles);
+ rtems_clock_get_uptime(&end_time);
+
+ ObtainMutex(ctx->filter_mutex_id);
+ ctx->filter_sim_process_time += (float)(end_time.tv_sec - begin_time.tv_sec)
+ + ( (float)(end_time.tv_nsec/1000 - begin_time.tv_nsec/1000)/1000000.0);
+ ctx->accxL2 += acc;
+ ReleaseMutex(ctx->filter_mutex_id);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+
+//=======================================================================================
+// "snr_processing" Tasks/Functions
+//=======================================================================================
+static void task_snr_read_sensor_data(rtems_task_argument arg){
+ test_context *ctx;
+ uint32_t iter = 0;
+
+ ctx = (test_context *)arg;
+
+ ReceiveAllEvents(EVENT_GO_READ_SENSOR);
+
+ while ( iter < MAX_ITER) {
+ ObtainMutex(ctx->snr_mutex_id);
+
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = 0.4995f * cos_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter%TC_MAX]);
+ inSensorDataIm[i] = 0.4995f * sin_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ }
+
+ ReleaseMutex(ctx->snr_mutex_id);
+ SendEvents(ctx->task_snr_process_data_id, EVENT_DATA_READY);
+
+ iter++;
+ ReceiveAllEvents(EVENT_DATA_WAS_PROCESSED);
+ }
+
+ rtems_event_send(ctx->main_task, event_send[(TASK_COUNT-2)]);
+ SuspendSelf();
+}
+
+static void task_snr_process_data(rtems_task_argument arg) {
+ test_context *ctx;
+ ctx = (test_context *)arg;
+ uint32_t iter = 0;
+ struct timespec begin_time;
+ struct timespec end_time;
+
+ while ( iter < MAX_ITER ) {
+ ReceiveAllEvents(EVENT_DATA_READY);
+ ObtainMutex(ctx->snr_mutex_id);
+ rtems_clock_get_uptime(&begin_time);
+
+ //Apply Blackman-Harris Window
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = inSensorDataRe[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ inSensorDataIm[i] = inSensorDataIm[i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ }
+
+ //Calculates FFT
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ //Calculates the magnitude values
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = (inSensorDataRe[i] * inSensorDataRe[i]
+ + inSensorDataIm[i] * inSensorDataIm[i]) / ((float)FFT_SIZE);
+ }
+
+ //Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ float maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if (inSensorDataRe[i] > maxValue) {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ //Calculates the signal and noise power (no DC)
+ float sig = 0.0f;
+ float noise = 0.0f;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if ((i > maxValueIndex - 8) && (i < maxValueIndex + 8)) {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+
+ if (!(sig > 0.0f)) { sig = 0.0000000001f; }
+ if (!(noise > 0.0f)) { noise = 0.0000000001f; }
+
+ //Calculates SNR
+ float snr_float = sig/noise;
+
+ if (snr_float > SNR_THRESHOLD) {
+ dsp_result[iter] = 1;
+ }
+ else {
+ dsp_result[iter] = 0;
+ }
+ rtems_clock_get_uptime(&end_time);
+
+ ctx->snr_process_time +=
+ (float)(end_time.tv_sec - begin_time.tv_sec) +
+ ( (float)((end_time.tv_nsec/1000) - (begin_time.tv_nsec/1000))/1000000.0);
+
+ ReleaseMutex(ctx->snr_mutex_id);
+ iter++;
+ SendEvents(ctx->task_snr_read_sensor_data_id, EVENT_DATA_WAS_PROCESSED);
+ }
+
+ rtems_event_send(ctx->main_task, event_send[(TASK_COUNT-1)]);
+ SuspendSelf();
+}
+
+
+//=======================================================================================
+// INIT/MAIN Task
+//=======================================================================================
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch, str[ITOA_STR_SIZE];
+ uint32_t total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+ (void) memset(&inSensorDataRe[0], 0, FFT_SIZE);
+ (void) memset(&inSensorDataIm[0], 0, FFT_SIZE);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ctx.filter_mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', '0'));
+ ctx.snr_mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', '1'));
+ SetSelfPriority( PRIO_NORMAL );
+
+ for (uint32_t i = 0; i < TASK_COUNT-2; i++){
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_filter_simulation_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_filter_simulation_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ ch = '0' + (TASK_COUNT-2);
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[(TASK_COUNT-2)][0];
+ ctx.task_snr_read_sensor_data_id = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_snr_read_sensor_data_id, task_snr_read_sensor_data, &ctx);
+
+ ch = '0' + (TASK_COUNT-1);
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[(TASK_COUNT-1)][0];
+ ctx.task_snr_process_data_id = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_snr_process_data_id, task_snr_process_data, &ctx);
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ // Locking cache way #3 and #4
+ l2_cache_set_way_lock(2);
+ l2_cache_enable_split_responses();
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+ //Calculates mean of Blackman-Harris terms --> to scale a bit the FFT
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i<FFT_SIZE; i++){
+ ctx.scaling_fft_factor += blackman_harris( i, FFT_SIZE);
+ }
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor/ ((float) FFT_SIZE);
+
+//-----------------------------------------------------------------------------
+// Do the work: distribute the work through the tasks
+//-----------------------------------------------------------------------------
+ SendEvents(ctx.task_snr_read_sensor_data_id, EVENT_GO_READ_SENSOR);
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ rtems_event_set revents = ReceiveAvailableEvents();
+ while ( (revents & total_events) != total_events ) {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+ ctx.next_tile++;
+ revents = ReceiveAvailableEvents();
+ }
+ // Wait for the SNR tasks to finish
+ ReceiveAllEvents(event_send[(TASK_COUNT-2)]);
+ ReceiveAllEvents(event_send[(TASK_COUNT-1)]);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+ print_string("Time used in filter sim processing : ");
+ print_string(itoa( (int32_t) (ctx.filter_sim_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("Time used in SNR processing : ");
+ print_string(itoa( (int32_t) (ctx.snr_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("SNR triggers found at : ");
+ for (uint32_t j = 0; j < MAX_ITER; j++)
+ if (dsp_result[j] > 0.0){
+ print_string(itoa(j, &str[0], 10));
+ print_string(" ");
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+ for (uint32_t i = 0; i < (TASK_COUNT-2); i++){
+ DeleteTask(ctx.task_filter_simulation_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+
+ DeleteTask(ctx.task_snr_process_data_id);
+ DeleteTask(ctx.task_snr_read_sensor_data_id);
+
+ DeleteMutex(ctx.filter_mutex_id);
+ DeleteMutex(ctx.snr_mutex_id);
+
+ DeleteMessageQueue(ctx.tile_queue);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 2
+
+#define CONFIGURE_MAXIMUM_TASKS ( TASK_COUNT + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.4_uni_cache_split_transactions_disabled/uni_cache_split_transactions_disabled.c b/testsuites/isvv/23.4_uni_cache_split_transactions_disabled/uni_cache_split_transactions_disabled.c
new file mode 100644
index 0000000000..4e73adeaac
--- /dev/null
+++ b/testsuites/isvv/23.4_uni_cache_split_transactions_disabled/uni_cache_split_transactions_disabled.c
@@ -0,0 +1,370 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache split transactions
+ *
+ * Step 1: Uniprocessor case
+ *
+ * In this step the same set of math equations used by several tasks in the
+ * Multiprocessor version are run in an Uniprocessor and ONE task only environment
+ * in order to achieve a reference output result for comparison.
+ *
+ * There is only one set of math equations processed here:
+ * - named "filter_simulation"
+ *
+ * Result values are obtained for later comparison with multiprocessor
+ * versions. Also some internal cache statistics are shown. Most relevant ones are the
+ * number of L2 cache misses, which when increased significantly, may delay the data
+ * processing and the number of split transactions which when enable should lower
+ * the number of time wasted in waiting for other bus transactions to finish.
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) use make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 1
+
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ uint64_t accxL2;
+} test_context;
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-----------------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2Mbytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512kbytes
+#define xL2_ELEM (8*L2_CACHE_SIZE/sizeof(uint32_t)) // 4M elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+//-----------------------------------------------------------------------------------------
+#define FILTER_TAPS (16U)
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void){
+ uint64_t acc = 0;
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j++)
+ acc += xL2[j];
+ return acc;
+}
+
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems){
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = begin_idx ; j <= end_idx; j ++) {
+ uint32_t i;
+
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+xL2_ELEM*1/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+xL2_ELEM*2/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+xL2_ELEM*3/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*4/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*5/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*6/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*7/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ // Simulating normalization
+ t3 = ((t1*1000)/(42*137)) + 1;
+ t4 = ((t2*10)/(96*137)) + 1;
+ uint64_t t5 = (uint64_t)t3 * (uint64_t)t3;
+ uint64_t t6 = (uint64_t)t4 * (uint64_t)t4;
+ acc += (t5+t6)/((uint64_t)isqrt(t4+t3));
+ }
+ return acc;
+}
+
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char str[ITOA_STR_SIZE];
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+ SetSelfPriority( PRIO_NORMAL );
+
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable_split_responses();
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Do the work
+//-----------------------------------------------------------------------------
+ start_time = rtems_clock_get_ticks_since_boot();
+ ctx.accxL2 = calc_filter_simulation_equation(0, 1);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Single Core Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_TASKS TEST_PROCESSORS
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.5_multi_cache_split_transactions_disabled/multi_cache_split_transactions_disabled.c b/testsuites/isvv/23.5_multi_cache_split_transactions_disabled/multi_cache_split_transactions_disabled.c
new file mode 100644
index 0000000000..9e02c793a0
--- /dev/null
+++ b/testsuites/isvv/23.5_multi_cache_split_transactions_disabled/multi_cache_split_transactions_disabled.c
@@ -0,0 +1,491 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache split transactions
+ *
+ * Step 2: Multiprocessor with L2 cache split transactions disabled
+ *
+ * There is one set of math equations processed:
+ * - named "filter_simulation"
+ *
+ * The equations for "filter_simulation" are used by TEST_PROCESSORS tasks that
+ * processes small sections of a "data array" in parallel.
+ *
+ * The locations in memory for acessing the small sections of the "data arrays" do
+ * overlap in terms of cache memory positions, and when acessing one section of the
+ * "data array", or even a smaller part of one, other sections of that "data array"
+ * should be kicked out of the cache. Sometimes that may happen within the same task.
+ *
+ * With the "L2 cache split transactions" disabled, everytime a data word is required
+ * by the CPU from L2 cache, it may happen that the L2 cache is busy retrieving other
+ * data from the main memory, and the first transaction related to the first data word
+ * needs to wait for the other transaction to finish, wasting processing time in these
+ * cases.
+ *
+ * Expected Results:
+ * - The Tiles must be processed only once.
+ * - "Ouput Data Result Value" must match in the Uniprocessor version with the
+ * Multiprocessor version with L2 cache split transactions disabled.
+ * - Elapsed Time should be lower than the Uniprocessor version, but slightly higher
+ * than Multiprocessor version with L2 cache split transactions enabled.
+ * - The number of AHB Splits transactions reported must be 0
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) use make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+#define MAX_MESSAGE_QUEUES 5
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct
+{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT];
+ rtems_id mutex_id;
+ uint64_t accxL2;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-----------------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2Mbytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512kbytes
+#define xL2_ELEM (8*L2_CACHE_SIZE/sizeof(uint32_t)) // 4M elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+//-----------------------------------------------------------------------------------------
+#define FILTER_TAPS (16U)
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void){
+ uint64_t acc = 0;
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j++)
+ acc += xL2[j];
+ return acc;
+}
+
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems){
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = begin_idx ; j <= end_idx; j ++) {
+ uint32_t i;
+
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+xL2_ELEM*1/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+xL2_ELEM*2/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+xL2_ELEM*3/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*4/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*5/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*6/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*7/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ // Simulating normalization
+ t3 = ((t1*1000)/(42*137)) + 1;
+ t4 = ((t2*10)/(96*137)) + 1;
+ uint64_t t5 = (uint64_t)t3 * (uint64_t)t3;
+ uint64_t t6 = (uint64_t)t4 * (uint64_t)t4;
+ acc += (t5+t6)/((uint64_t)isqrt(t4+t3));
+ }
+ return acc;
+}
+
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ test_context *ctx;
+ uint64_t acc;
+
+ ctx = (test_context *)arg;
+
+ uint8_t tile;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+
+ for (int i = 0; i < TASK_COUNT; i++){
+ if (ctx->task_id[i] == local_id){
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles) {
+ acc = 0;
+ count_process[tile - 1]++;
+ acc = calc_filter_simulation_equation(tile-1, ctx->ntiles);
+
+ ObtainMutex(ctx->mutex_id);
+ ctx->accxL2 += acc;
+ ReleaseMutex(ctx->mutex_id);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch, str[ITOA_STR_SIZE];
+ uint32_t total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ctx.mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', 'X'));
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+ SetSelfPriority( PRIO_NORMAL );
+
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable_split_responses();
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Do the work: distribute the work through the tasks
+//-----------------------------------------------------------------------------
+ start_time = rtems_clock_get_ticks_since_boot();
+ while (ReceiveAvailableEvents() != total_events) {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+ ctx.next_tile++;
+ }
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ DeleteTask(ctx.task_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+ DeleteMessageQueue(ctx.tile_queue);
+
+ DeleteMutex(ctx.mutex_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_TASKS ( TEST_PROCESSORS + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.6_multi_cache_split_transactions_enabled/multi_cache_split_transactions_enabled.c b/testsuites/isvv/23.6_multi_cache_split_transactions_enabled/multi_cache_split_transactions_enabled.c
new file mode 100644
index 0000000000..dcaa534c6c
--- /dev/null
+++ b/testsuites/isvv/23.6_multi_cache_split_transactions_enabled/multi_cache_split_transactions_enabled.c
@@ -0,0 +1,495 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache split transactions
+ *
+ * Step 2: Multiprocessor with L2 cache split transactions enabled
+ *
+ * There is one set of math equations processed:
+ * - named "filter_simulation"
+ *
+ * The equations for "filter_simulation" are used by TEST_PROCESSORS tasks that
+ * processes small sections of a "data array" in parallel.
+ *
+ * The locations in memory for acessing the small sections of the "data arrays" do
+ * overlap in terms of cache memory positions, and when acessing one section of the
+ * "data array", or even a smaller part of one, other sections of that "data array"
+ * should be kicked out of the cache. Sometimes that may happen within the same task.
+ *
+ * With the "L2 cache split transactions" enabled, everytime a data word is required
+ * by the CPU from L2 and it may happen that the L2 cache is busy retrieving other other data
+ * from the main memory, and the data word would need to wait for the other transaction to
+ * finish if L2 cache split transactions enabled.
+ *
+ * With L2 cache split transactions enabled, L2 cache can issue a split transactation to
+ * the other data transaction, and becomes free to attend the data word that was required by CPU.
+ * For the other data transaction, the master of the bus that requested it must issue a Retry
+ * transaction.
+ *
+ * Expected Results:
+ * - The Tiles must be processed only once.
+ * - "Ouput Data Result Value" must match in the Uniprocessor version with the
+ * Multiprocessor version with L2 cache split transactions disabled.
+ * - Elapsed Time should be lower than the Uniprocessor version, and slightly lower
+ * than Multiprocessor version with L2 cache split transactions disabled.
+ * - The number of AHB Splits transactions reported must be significant
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) use make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+// test specific global vars
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 64
+
+#define MAX_MESSAGE_QUEUES 5
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+rtems_event_set event_send[4] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4};
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct
+{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_id[TASK_COUNT];
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT];
+ rtems_id mutex_id;
+ uint64_t accxL2;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT][MAX_PENDING_MESSAGES];
+
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-----------------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2Mbytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512kbytes
+#define xL2_ELEM (8*L2_CACHE_SIZE/sizeof(uint32_t)) // 4M elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+//-----------------------------------------------------------------------------------------
+#define FILTER_TAPS (16U)
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void){
+ uint64_t acc = 0;
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j++)
+ acc += xL2[j];
+ return acc;
+}
+
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems){
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = begin_idx ; j <= end_idx; j ++) {
+ uint32_t i;
+
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+xL2_ELEM*1/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+xL2_ELEM*2/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+xL2_ELEM*3/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*4/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*5/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*6/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t2 += xL2[(j+i+xL2_ELEM*7/8/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ // Simulating normalization
+ t3 = ((t1*1000)/(42*137)) + 1;
+ t4 = ((t2*10)/(96*137)) + 1;
+ uint64_t t5 = (uint64_t)t3 * (uint64_t)t3;
+ uint64_t t6 = (uint64_t)t4 * (uint64_t)t4;
+ acc += (t5+t6)/((uint64_t)isqrt(t4+t3));
+ }
+ return acc;
+}
+
+
+static void calc_task_function(rtems_task_argument arg)
+{
+ test_context *ctx;
+ uint64_t acc;
+
+ ctx = (test_context *)arg;
+
+ uint8_t tile;
+ rtems_id local_id = TaskSelfId();
+ uint8_t task_idx = 255;
+
+ for (int i = 0; i < TASK_COUNT; i++){
+ if (ctx->task_id[i] == local_id){
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles) {
+ acc = 0;
+ count_process[tile - 1]++;
+ acc = calc_filter_simulation_equation(tile-1, ctx->ntiles);
+
+ ObtainMutex(ctx->mutex_id);
+ ctx->accxL2 += acc;
+ ReleaseMutex(ctx->mutex_id);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ SuspendSelf();
+}
+
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch, str[ITOA_STR_SIZE];
+ uint32_t total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ctx.mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', 'X'));
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+ SetSelfPriority( PRIO_NORMAL );
+
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_enable_split_responses();
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Do the work: distribute the work through the tasks
+//-----------------------------------------------------------------------------
+ start_time = rtems_clock_get_ticks_since_boot();
+ while (ReceiveAvailableEvents() != total_events) {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+ ctx.next_tile++;
+ }
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ DeleteTask(ctx.task_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+ DeleteMessageQueue(ctx.tile_queue);
+
+ DeleteMutex(ctx.mutex_id);
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 1
+
+#define CONFIGURE_MAXIMUM_TASKS ( TEST_PROCESSORS + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.7_uni_cache_repl_policy_l2_lru/uni_cache_repl_policy_l2_lru.c b/testsuites/isvv/23.7_uni_cache_repl_policy_l2_lru/uni_cache_repl_policy_l2_lru.c
new file mode 100644
index 0000000000..0315036a28
--- /dev/null
+++ b/testsuites/isvv/23.7_uni_cache_repl_policy_l2_lru/uni_cache_repl_policy_l2_lru.c
@@ -0,0 +1,535 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache replacement policy
+ *
+ * Step 1: Uniprocessor case
+ *
+ * In this step the same set of math equations used by several tasks in the
+ * Multiprocessor version are run in an Uniprocessor and ONE task only environment
+ * in order to achieve a reference output result for comparison.
+ *
+ * There are two main sets of math equations processed here:
+ * - one named "filter_simulation"
+ * - and other named "snr_processing"
+ *
+ * For each one, result values are obtained for later comparison with multiprocessor
+ * versions. Also some internal cache statistics are shown. Most relevant one is the number of
+ * L2 cache misses, which when increased significantly, may delay the data processing.
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) use make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+
+// test specific global vars
+#undef TEST_PROCESSORS
+#define TEST_PROCESSORS 1
+
+#define TASK_COUNT TEST_PROCESSORS
+#define TOTAL_TILES 128
+
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+const rtems_event_set event_send[6] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4,
+ RTEMS_EVENT_5,
+ RTEMS_EVENT_6
+ };
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ uint8_t ntiles;
+ uint8_t next_tile;
+ float filter_sim_process_time;
+ uint64_t accxL2;
+ float snr_process_time;
+ float scaling_fft_factor;
+} test_context;
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2M bytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512k bytes
+#define xL2_ELEM (4*L2_CACHE_SIZE/sizeof(uint32_t)) // 2M elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+//-------------------------------------------------------------------------------
+#define SENSOR_DATA_ELEM (6*L2_CACHE_WAY_SIZE/sizeof(uint32_t))
+#define MAX_ITER (SENSOR_DATA_ELEM / FFT_SIZE)
+#define FFT_SIZE (8192U)
+#define FFT_SIZE_LOG2 (13U)
+#define TC_MAX (16U)
+#define FILTER_TAPS (64U)
+#define SNR_THRESHOLD (1000000.0f)
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = { 2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U };
+const float NOISE_FACTOR[TC_MAX] = { 0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f };
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataRe[SENSOR_DATA_ELEM];
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataIm[SENSOR_DATA_ELEM];
+static uint8_t dsp_result[MAX_ITER];
+
+
+//=======================================================================================
+// Auxiliary Functions
+//=======================================================================================
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void){
+ uint64_t acc = 0;
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j++)
+ acc += xL2[j];
+ return acc;
+}
+
+
+//=======================================================================================
+// "filter_simulation" Tasks/Functions
+//=======================================================================================
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems) {
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = begin_idx ; j <= end_idx; j++ ) {
+ uint32_t i;
+
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*1/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*2/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*3/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*4/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*5/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*6/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*7/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ // Simulating normalization
+ t3 = ((t1*1000)/(42*137)) + 1;
+ t4 = ((t2*10)/(96*137)) + 1;
+ uint64_t t5 = (uint64_t)t3 * (uint64_t)t3;
+ uint64_t t6 = (uint64_t)t4 * (uint64_t)t4;
+ acc += (t5+t6)/((uint64_t)isqrt(t4+t3));
+ }
+ return acc;
+}
+
+static uint64_t function_calc_filter_simulation(test_context *ctx, uint8_t tile, uint32_t total_elems) {
+ struct timespec begin_time;
+ struct timespec end_time;
+ static uint64_t acc;
+
+ rtems_clock_get_uptime(&begin_time);
+
+ acc = calc_filter_simulation_equation(tile, total_elems);
+
+ rtems_clock_get_uptime(&end_time);
+ ctx->filter_sim_process_time +=
+ (float)(end_time.tv_sec - begin_time.tv_sec) +
+ ( (float)((end_time.tv_nsec/1000) - (begin_time.tv_nsec/1000))/1000000.0);
+
+ return acc;
+}
+
+
+//=======================================================================================
+// "snr_processing" Tasks/Functions
+//=======================================================================================
+static void function_snr_read_sensor_data( uint32_t start_idx, uint32_t iter) {
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[start_idx + i] = 0.4995f * cos_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter%TC_MAX]);
+ inSensorDataIm[start_idx + i] = 0.4995f * sin_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ }
+}
+
+static void function_snr_process_data(test_context *ctx, uint32_t start_idx, uint32_t iter) {
+ struct timespec begin_time;
+ struct timespec end_time;
+
+ rtems_clock_get_uptime(&begin_time);
+
+ //Apply Blackman-Harris Window
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = inSensorDataRe[start_idx+i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ inSensorDataIm[i] = inSensorDataIm[start_idx+i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ }
+
+ //Calculates FFT
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ //Calculates the magnitude values
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = (inSensorDataRe[i] * inSensorDataRe[i]
+ + inSensorDataIm[i] * inSensorDataIm[i]) / ((float)FFT_SIZE);
+ }
+
+ //Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ float maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if (inSensorDataRe[i] > maxValue) {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ //Calculates the signal and noise power (no DC)
+ float sig = 0.0f;
+ float noise = 0.0f;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if ((i > maxValueIndex - 4) && (i < maxValueIndex + 4)) {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+
+ if (!(sig > 0.0f)) { sig = 0.0000000001f; }
+ if (!(noise > 0.0f)) { noise = 0.0000000001f; }
+
+ //Calculates SNR
+ float snr_float = sig/noise;
+
+ if (snr_float > SNR_THRESHOLD) {
+ dsp_result[iter] = 1;
+ }
+ else {
+ dsp_result[iter] = 0;
+ }
+ rtems_clock_get_uptime(&end_time);
+
+ ctx->snr_process_time +=
+ (float)(end_time.tv_sec - begin_time.tv_sec) +
+ ( (float)((end_time.tv_nsec/1000) - (begin_time.tv_nsec/1000))/1000000.0);
+}
+
+
+//=======================================================================================
+// INIT/MAIN Task
+//=======================================================================================
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char str[ITOA_STR_SIZE];
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+ (void) memset(&inSensorDataRe[0], 0, SENSOR_DATA_ELEM);
+ (void) memset(&inSensorDataIm[0], 0, SENSOR_DATA_ELEM);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+ SetSelfPriority( PRIO_NORMAL );
+
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_set_replacement_policy(L2_CACHE_REPL_LRU, 0);
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+ //Calculates mean of Blackman-Harris terms
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i<FFT_SIZE; i++){
+ ctx.scaling_fft_factor += blackman_harris( i, FFT_SIZE);
+ }
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor/ ((float) FFT_SIZE);
+
+//-----------------------------------------------------------------------------
+// Do the work: distribute the work through the tasks
+//-----------------------------------------------------------------------------
+ start_time = rtems_clock_get_ticks_since_boot();
+ ctx.accxL2 = function_calc_filter_simulation(&ctx, 0, 1);
+
+ uint32_t start_idx = 0;
+ for (uint32_t iter=0; iter<MAX_ITER; iter++, start_idx += FFT_SIZE) {
+ function_snr_read_sensor_data(start_idx, iter);
+ function_snr_process_data(&ctx, start_idx, iter) ;
+ }
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Single Core Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+ print_string("Time used in filter sim processing : ");
+ print_string(itoa( (int32_t) (ctx.filter_sim_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("Time used in SNR processing : ");
+ print_string(itoa( (int32_t) (ctx.snr_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("SNR triggers found at : ");
+ for (uint32_t j = 0; j < MAX_ITER; j++)
+ if (dsp_result[j] > 0.0){
+ print_string(itoa(j, &str[0], 10));
+ print_string(" ");
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_TASKS TEST_PROCESSORS
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.8_multi_cache_repl_policy_l2_lru/multi_cache_repl_policy_l2_lru.c b/testsuites/isvv/23.8_multi_cache_repl_policy_l2_lru/multi_cache_repl_policy_l2_lru.c
new file mode 100644
index 0000000000..c755516f63
--- /dev/null
+++ b/testsuites/isvv/23.8_multi_cache_repl_policy_l2_lru/multi_cache_repl_policy_l2_lru.c
@@ -0,0 +1,722 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache replacement policy
+ *
+ * Step 2: Multiprocessor with L2 cache replacement policy LRU
+ *
+ * There are two main set of math equations used here:
+ * - one named "filter_simulation"
+ * - and other named "snr_processing"
+ *
+ * The equations for "filter_simulation" are used by TWO tasks that processes small
+ * sections of a "data array" in parallel.
+ * The equations for "snr_processing" are used by TWO tasks that processes small
+ * sections of other "data array" in sequential order, but in parallel with the other
+ * tasks.
+ *
+ * The locations in memory for both "data arrays" do overlap in terms of cache memory
+ * positions, and when acessing one "data array", or part of one, other sections of
+ * the other "data array" should be kicked out of the cache. Sometimes that may
+ * also happen within the same "data array".
+ *
+ * Expected Results:
+ * - The Tiles must be processed only once.
+ * - "Ouput Data Result Value" must match with the Uniprocessor version.
+ * - SNR triggers index positions must match with the ones of the Uniprocessor
+ * version.
+ * - L2 cache misses should be significantly higher than the Uniprocessor version.
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) use make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+
+// test specific global vars
+#define TASK_COUNT_FILTER (2U ) //2 parallel tasks for "filter simulation"
+#define TASK_COUNT_SNR (2U) //2 sequential tasks for "snr processing"
+#define TASK_COUNT (TASK_COUNT_FILTER+TASK_COUNT_SNR)
+
+#define TOTAL_TILES 128
+#define PERIOD_IN_TICKS 100
+
+#define MAX_MESSAGE_QUEUES 6
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+const rtems_event_set event_send[6] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4,
+ RTEMS_EVENT_5,
+ RTEMS_EVENT_6
+ };
+
+#define EVENT_DATA_READY RTEMS_EVENT_10
+#define GO_READ_SENSOR RTEMS_EVENT_11
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_filter_simulation_id[TASK_COUNT_FILTER];
+ rtems_id task_snr_process_data_id;
+ rtems_id task_snr_read_sensor_data_id;
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT_FILTER];
+ rtems_id filter_mutex_id;
+ float filter_sim_process_time;
+ uint64_t accxL2;
+ rtems_id snr_mutex_id;
+ float snr_process_time;
+ float scaling_fft_factor;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT_FILTER][MAX_PENDING_MESSAGES];
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2M bytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512k bytes
+#define xL2_ELEM (4*L2_CACHE_SIZE/sizeof(uint32_t)) // 2M elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+//-------------------------------------------------------------------------------
+#define SENSOR_DATA_ELEM (6*L2_CACHE_WAY_SIZE/sizeof(uint32_t))
+#define MAX_ITER (SENSOR_DATA_ELEM / FFT_SIZE)
+#define FFT_SIZE (8192U)
+#define FFT_SIZE_LOG2 (13U)
+#define TC_MAX (16U)
+#define FILTER_TAPS (64U)
+#define SNR_THRESHOLD (1000000.0f)
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = { 2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U };
+const float NOISE_FACTOR[TC_MAX] = { 0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f };
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataRe[SENSOR_DATA_ELEM];
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataIm[SENSOR_DATA_ELEM];
+static uint8_t dsp_result[MAX_ITER];
+
+
+//=======================================================================================
+// Auxiliary Functions
+//=======================================================================================
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void){
+ uint64_t acc = 0;
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j++)
+ acc += xL2[j];
+ return acc;
+}
+
+
+//=======================================================================================
+// "filter_simulation" Tasks/Functions
+//=======================================================================================
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems) {
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = begin_idx ; j <= end_idx; j++ ) {
+ uint32_t i;
+
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*1/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*2/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*3/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*4/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*5/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*6/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*7/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ // Simulating normalization
+ t3 = ((t1*1000)/(42*137)) + 1;
+ t4 = ((t2*10)/(96*137)) + 1;
+ uint64_t t5 = (uint64_t)t3 * (uint64_t)t3;
+ uint64_t t6 = (uint64_t)t4 * (uint64_t)t4;
+ acc += (t5+t6)/((uint64_t)isqrt(t4+t3));
+ }
+ return acc;
+}
+
+
+static void calc_task_function(rtems_task_argument arg){
+ test_context *ctx;
+ uint64_t acc;
+ rtems_id calc_task_period;
+ struct timespec begin_time;
+ struct timespec end_time;
+ uint8_t tile = 0;
+ uint8_t task_idx = 255;
+
+ ctx = (test_context *)arg;
+ rtems_id local_id = TaskSelfId();
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ if (ctx->task_filter_simulation_id[i] == local_id){
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+ calc_task_period = CreateRateMonotonic();
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles) {
+
+#ifdef GR740_ESA_BOARD
+ WaitPeriod(calc_task_period, 8*PERIOD_IN_TICKS);
+#endif
+
+ count_process[tile - 1]++;
+ rtems_clock_get_uptime(&begin_time);
+ acc = calc_filter_simulation_equation(tile-1, ctx->ntiles);
+ rtems_clock_get_uptime(&end_time);
+
+ ObtainMutex(ctx->filter_mutex_id);
+ ctx->filter_sim_process_time += (float)(end_time.tv_sec - begin_time.tv_sec)
+ + ( (float)(end_time.tv_nsec/1000 - begin_time.tv_nsec/1000)/1000000.0);
+ ctx->accxL2 += acc;
+ ReleaseMutex(ctx->filter_mutex_id);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ DeleteRateMonotonic(calc_task_period);
+ SuspendSelf();
+}
+
+//=======================================================================================
+// "snr_processing" Tasks/Functions
+//=======================================================================================
+static void task_snr_read_sensor_data(rtems_task_argument arg){
+ test_context *ctx;
+ rtems_id read_sensor_data_period;
+ uint32_t start_idx = 0;
+ uint32_t iter = 0;
+
+ ctx = (test_context *)arg;
+
+ ReceiveAllEvents(GO_READ_SENSOR);
+ read_sensor_data_period = CreateRateMonotonic();
+
+ while ( start_idx < SENSOR_DATA_ELEM) {
+
+#ifdef GR740_ESA_BOARD
+ WaitPeriod(read_sensor_data_period, 5*PERIOD_IN_TICKS);
+#endif
+
+ ObtainMutex(ctx->snr_mutex_id);
+
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[start_idx + i] = 0.4995f * cos_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter%TC_MAX]);
+ inSensorDataIm[start_idx + i] = 0.4995f * sin_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ }
+
+ ReleaseMutex(ctx->snr_mutex_id);
+ SendEvents(ctx->task_snr_process_data_id, EVENT_DATA_READY);
+
+ start_idx += FFT_SIZE;
+ iter++;
+
+ }
+
+ rtems_event_send(ctx->main_task, event_send[(TASK_COUNT-2)]);
+ DeleteRateMonotonic(read_sensor_data_period);
+ SuspendSelf();
+}
+
+static void task_snr_process_data(rtems_task_argument arg) {
+ test_context *ctx;
+ ctx = (test_context *)arg;
+ uint32_t start_idx = 0;
+ uint32_t iter = 0;
+ struct timespec begin_time;
+ struct timespec end_time;
+
+ while ( start_idx < SENSOR_DATA_ELEM ) {
+ ReceiveAllEvents(EVENT_DATA_READY);
+ ObtainMutex(ctx->snr_mutex_id);
+ rtems_clock_get_uptime(&begin_time);
+
+ //Apply Blackman-Harris Window
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = inSensorDataRe[start_idx+i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ inSensorDataIm[i] = inSensorDataIm[start_idx+i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ }
+
+ //Calculates FFT
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ //Calculates the magnitude values
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = (inSensorDataRe[i] * inSensorDataRe[i]
+ + inSensorDataIm[i] * inSensorDataIm[i]) / ((float)FFT_SIZE);
+ }
+
+ //Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ float maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if (inSensorDataRe[i] > maxValue) {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ //Calculates the signal and noise power (no DC)
+ float sig = 0.0f;
+ float noise = 0.0f;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if ((i > maxValueIndex - 4) && (i < maxValueIndex + 4)) {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+
+ if (!(sig > 0.0f)) { sig = 0.0000000001f; }
+ if (!(noise > 0.0f)) { noise = 0.0000000001f; }
+
+ //Calculates SNR
+ float snr_float = sig/noise;
+
+ if (snr_float > SNR_THRESHOLD) {
+ dsp_result[iter] = 1;
+ }
+ else {
+ dsp_result[iter] = 0;
+ }
+ rtems_clock_get_uptime(&end_time);
+
+ ctx->snr_process_time +=
+ (float)(end_time.tv_sec - begin_time.tv_sec) +
+ ( (float)((end_time.tv_nsec/1000) - (begin_time.tv_nsec/1000))/1000000.0);
+
+ ReleaseMutex(ctx->snr_mutex_id);
+ start_idx += FFT_SIZE;
+ iter++;
+ }
+
+ rtems_event_send(ctx->main_task, event_send[(TASK_COUNT-1)]);
+ SuspendSelf();
+}
+
+
+//=======================================================================================
+// INIT/MAIN Task
+//=======================================================================================
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch, str[ITOA_STR_SIZE];
+ uint32_t total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+ (void) memset(&inSensorDataRe[0], 0, SENSOR_DATA_ELEM);
+ (void) memset(&inSensorDataIm[0], 0, SENSOR_DATA_ELEM);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ctx.filter_mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', '0'));
+ ctx.snr_mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', '1'));
+ SetSelfPriority( PRIO_NORMAL );
+
+ for (uint32_t i = 0; i < TASK_COUNT-2; i++){
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_filter_simulation_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_filter_simulation_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ ch = '0' + (TASK_COUNT-2);
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[(TASK_COUNT-2)][0];
+ ctx.task_snr_read_sensor_data_id = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_snr_read_sensor_data_id, task_snr_read_sensor_data, &ctx);
+
+ ch = '0' + (TASK_COUNT-1);
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[(TASK_COUNT-1)][0];
+ ctx.task_snr_process_data_id = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_snr_process_data_id, task_snr_process_data, &ctx);
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_set_replacement_policy(L2_CACHE_REPL_LRU, 0);
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+ //Calculates mean of Blackman-Harris terms
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i<FFT_SIZE; i++){
+ ctx.scaling_fft_factor += blackman_harris( i, FFT_SIZE);
+ }
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor/ ((float) FFT_SIZE);
+
+//-----------------------------------------------------------------------------
+// Do the work: distribute the work through the tasks
+//-----------------------------------------------------------------------------
+ SendEvents(ctx.task_snr_read_sensor_data_id, GO_READ_SENSOR);
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ rtems_event_set revents = ReceiveAvailableEvents();
+ while ( (revents & total_events) != total_events ) {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+ ctx.next_tile++;
+ revents = ReceiveAvailableEvents();
+
+ }
+ // Wait for the SNR processing tasks to finish
+ ReceiveAllEvents(event_send[(TASK_COUNT-2)]);
+ ReceiveAllEvents(event_send[(TASK_COUNT-1)]);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+ print_string("Time used in filter sim processing : ");
+ print_string(itoa( (int32_t) (ctx.filter_sim_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("Time used in SNR processing : ");
+ print_string(itoa( (int32_t) (ctx.snr_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("SNR triggers found at : ");
+ for (uint32_t j = 0; j < MAX_ITER; j++)
+ if (dsp_result[j] > 0.0){
+ print_string(itoa(j, &str[0], 10));
+ print_string(" ");
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+ for (uint32_t i = 0; i < (TASK_COUNT-2); i++){
+ DeleteTask(ctx.task_filter_simulation_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+
+ DeleteTask(ctx.task_snr_process_data_id);
+ DeleteTask(ctx.task_snr_read_sensor_data_id);
+
+ DeleteMutex(ctx.filter_mutex_id);
+ DeleteMutex(ctx.snr_mutex_id);
+
+ DeleteMessageQueue(ctx.tile_queue);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 2
+
+#define CONFIGURE_MAXIMUM_PERIODS 3
+
+#define CONFIGURE_MAXIMUM_TASKS ( TASK_COUNT + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/23.9_multi_cache_repl_policy_l2_random/multi_cache_repl_policy_l2_random.c b/testsuites/isvv/23.9_multi_cache_repl_policy_l2_random/multi_cache_repl_policy_l2_random.c
new file mode 100644
index 0000000000..62a8f1e822
--- /dev/null
+++ b/testsuites/isvv/23.9_multi_cache_repl_policy_l2_random/multi_cache_repl_policy_l2_random.c
@@ -0,0 +1,725 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "../shared/utils.h"
+#include "../shared/isvv_rtems_aux.h"
+#include "../shared/low_level_utils.h"
+
+/**
+ *
+ * @brief Tests impact performing of L2 cache replacement policy
+ *
+ * Step 2: Multiprocessor with L2 cache replacement policy Pseudo-Random
+ *
+ * There are two main set of math equations used here:
+ * - one named "filter_simulation"
+ * - and other named "snr_processing"
+ *
+ * The equations for "filter_simulation" are used by TWO tasks that processes small
+ * sections of a "data array" in parallel.
+ * The equations for "snr_processing" are used by TWO tasks that processes small
+ * sections of other "data array" in sequential order, but in parallel with the other
+ * tasks.
+ *
+ * The locations in memory for both "data arrays" do overlap in terms of cache memory
+ * positions, and when acessing one "data array", or part of one, other sections of
+ * the other "data array" should be kicked out of the cache. Sometimes that may
+ * also happen within the same "data array".
+ *
+ * Expected Results:
+ * - The Tiles must be processed only once.
+ * - "Ouput Data Result Value" must match with the Multiprocessor with
+ * L2 cache replacement policy LRU version and Uniprocessor version.
+ * - SNR triggers index positions must match with the ones from the Multiprocessor with
+ * L2 cache replacement policy LRU version and with the ones from the Uniprocessor
+ * version.
+ * - L2 cache misses should be significantly higher than the Multiprocessor with L2
+ * cache replacement policy LRU version.
+ *
+ */
+
+/**
+ *
+ * For standalone tests in the actual hardware boards the following options can be used:
+ *
+ * 1) use make XFLAGS="-Dgr740 -DGR740_ESA_BOARD"
+ * 2) declare #define GR740_ESA_BOARD at the beginning of this file
+ *
+ */
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP(64, RTEMS_TASK_STORAGE_ALIGNMENT)
+
+#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
+
+#define TASK_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE, \
+ TASK_ATTRIBUTES)
+
+
+// test specific global vars
+#define TASK_COUNT_FILTER (2U ) //2 parallel tasks for "filter simulation"
+#define TASK_COUNT_SNR (2U) //2 sequential tasks for "snr processing"
+#define TASK_COUNT (TASK_COUNT_FILTER+TASK_COUNT_SNR)
+
+#define TOTAL_TILES 128
+#define PERIOD_IN_TICKS 100
+
+#define MAX_MESSAGE_QUEUES 6
+#define MAX_MESSAGE_SIZE sizeof(uint8_t)
+#define MAX_PENDING_MESSAGES 10
+
+const rtems_event_set event_send[6] = {RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4,
+ RTEMS_EVENT_5,
+ RTEMS_EVENT_6
+ };
+
+#define EVENT_DATA_READY RTEMS_EVENT_10
+#define GO_READ_SENSOR RTEMS_EVENT_11
+
+uint8_t count_process[TOTAL_TILES];
+
+typedef struct{
+ rtems_id main_task;
+ uint8_t ntiles;
+ uint8_t next_tile;
+ rtems_id task_filter_simulation_id[TASK_COUNT_FILTER];
+ rtems_id task_snr_process_data_id;
+ rtems_id task_snr_read_sensor_data_id;
+ rtems_id tile_queue;
+ rtems_id message_queue[TASK_COUNT_FILTER];
+ rtems_id filter_mutex_id;
+ float filter_sim_process_time;
+ uint64_t accxL2;
+ rtems_id snr_mutex_id;
+ float snr_process_time;
+ float scaling_fft_factor;
+} test_context;
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT)
+static char calc_task_storage[TASK_COUNT][TASK_STORAGE_SIZE];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_tile_queue_storage[MAX_PENDING_MESSAGES];
+
+RTEMS_MESSAGE_QUEUE_BUFFER(MAX_MESSAGE_SIZE)
+msg_task_queue_storage[TASK_COUNT_FILTER][MAX_PENDING_MESSAGES];
+
+#define ITOA_STR_SIZE (8*sizeof(int)+1)
+
+//-------------------------------------------------------------------------------
+#define L2_CACHE_SIZE (4U*512U*1024U) // 2M bytes
+#define L2_CACHE_WAY_SIZE (512U*1024U) // 512k bytes
+#define xL2_ELEM (4*L2_CACHE_SIZE/sizeof(uint32_t)) // 2M elements
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_SIZE)
+#endif
+static uint32_t xL2[xL2_ELEM];
+
+#define COEFS_SIZE (128U)
+const uint32_t coefs[COEFS_SIZE] =
+ { 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773};
+
+//-------------------------------------------------------------------------------
+#define SENSOR_DATA_ELEM (6*L2_CACHE_WAY_SIZE/sizeof(uint32_t))
+#define MAX_ITER (SENSOR_DATA_ELEM / FFT_SIZE)
+#define FFT_SIZE (8192U)
+#define FFT_SIZE_LOG2 (13U)
+#define TC_MAX (16U)
+#define FILTER_TAPS (64U)
+#define SNR_THRESHOLD (1000000.0f)
+const uint16_t FS = 48000U;
+const uint16_t FREQ[TC_MAX] = { 2500U, 1500U, 15000U, 500U,
+ 1000U, 800U, 440U, 8000U,
+ 100U, 3500U, 12345U, 1200U,
+ 20000U, 715U, 5000U, 4500U };
+const float NOISE_FACTOR[TC_MAX] = { 0.0001f, 0.2250f, 0.00068f, 0.30f,
+ 0.004f, 0.0123f, 0.0054f, 0.00054f,
+ 0.01f, 0.0325f, 0.012f, 0.00032f,
+ 0.075f, 0.0423f, 0.0354f, 0.00002f };
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataRe[SENSOR_DATA_ELEM];
+
+#ifdef GR740_ESA_BOARD
+RTEMS_ALIGNED(L2_CACHE_WAY_SIZE)
+#endif
+static float inSensorDataIm[SENSOR_DATA_ELEM];
+static uint8_t dsp_result[MAX_ITER];
+
+
+//=======================================================================================
+// Auxiliary Functions
+//=======================================================================================
+static void fill_main_memory_with_data(void){
+ // Store to memory
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j ++)
+ xL2[j] = j;
+}
+
+static uint64_t warmup_caches(void){
+ uint64_t acc = 0;
+ for ( uint32_t j = 0 ; j < xL2_ELEM; j++)
+ acc += xL2[j];
+ return acc;
+}
+
+
+//=======================================================================================
+// "filter_simulation" Tasks/Functions
+//=======================================================================================
+static uint64_t calc_filter_simulation_equation(uint8_t tile, uint32_t total_elems) {
+ uint64_t acc = 0;
+ const uint32_t begin_idx = tile*xL2_ELEM/total_elems;
+ const uint32_t end_idx = begin_idx + (xL2_ELEM/total_elems) - 1;
+
+ for ( uint32_t j = begin_idx ; j <= end_idx; j++ ) {
+ uint32_t i;
+
+ // Simulating filtering/convolution
+ uint32_t t1 = 0, t2 = 0, t3 = 0, t4 = 0;
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*1/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*2/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*3/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*4/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*5/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*6/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ for (i = 0 ; i < FILTER_TAPS; i++)
+ t1 += xL2[(j+i+L2_CACHE_WAY_SIZE*7/2/sizeof(uint32_t)) % xL2_ELEM]*coefs[i];
+
+ // Simulating normalization
+ t3 = ((t1*1000)/(42*137)) + 1;
+ t4 = ((t2*10)/(96*137)) + 1;
+ uint64_t t5 = (uint64_t)t3 * (uint64_t)t3;
+ uint64_t t6 = (uint64_t)t4 * (uint64_t)t4;
+ acc += (t5+t6)/((uint64_t)isqrt(t4+t3));
+ }
+ return acc;
+}
+
+
+static void calc_task_function(rtems_task_argument arg){
+ test_context *ctx;
+ uint64_t acc;
+ rtems_id calc_task_period;
+ struct timespec begin_time;
+ struct timespec end_time;
+ uint8_t tile = 0;
+ uint8_t task_idx = 255;
+
+ ctx = (test_context *)arg;
+ rtems_id local_id = TaskSelfId();
+
+ for (uint32_t i = 0; i < TASK_COUNT; i++){
+ if (ctx->task_filter_simulation_id[i] == local_id){
+ task_idx = i;
+ break;
+ }
+ }
+
+ char ch = '0' + task_idx;
+
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', ch),
+ .maximum_pending_messages = MAX_PENDING_MESSAGES,
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_task_queue_storage[task_idx]),
+ .storage_area = &msg_task_queue_storage[task_idx],
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx->message_queue[task_idx] = CreateMessageQueue(msg_config);
+ calc_task_period = CreateRateMonotonic();
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+
+ while (tile <= ctx->ntiles) {
+
+#ifdef GR740_ESA_BOARD
+ WaitPeriod(calc_task_period, 8*PERIOD_IN_TICKS);
+#endif
+
+ count_process[tile - 1]++;
+ rtems_clock_get_uptime(&begin_time);
+ acc = calc_filter_simulation_equation(tile-1, ctx->ntiles);
+ rtems_clock_get_uptime(&end_time);
+
+ ObtainMutex(ctx->filter_mutex_id);
+ ctx->filter_sim_process_time += (float)(end_time.tv_sec - begin_time.tv_sec)
+ + ( (float)(end_time.tv_nsec/1000 - begin_time.tv_nsec/1000)/1000000.0);
+ ctx->accxL2 += acc;
+ ReleaseMutex(ctx->filter_mutex_id);
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ ReceiveMessage(ctx->message_queue[task_idx], &tile);
+ }
+
+ SendMessage(ctx->tile_queue, &task_idx, sizeof(task_idx));
+ SendEvents(ctx->main_task, event_send[task_idx]);
+ DeleteRateMonotonic(calc_task_period);
+ SuspendSelf();
+}
+
+//=======================================================================================
+// "snr_processing" Tasks/Functions
+//=======================================================================================
+static void task_snr_read_sensor_data(rtems_task_argument arg){
+ test_context *ctx;
+ rtems_id read_sensor_data_period;
+ uint32_t start_idx = 0;
+ uint32_t iter = 0;
+
+ ctx = (test_context *)arg;
+
+ ReceiveAllEvents(GO_READ_SENSOR);
+ read_sensor_data_period = CreateRateMonotonic();
+
+ while ( start_idx < SENSOR_DATA_ELEM) {
+
+#ifdef GR740_ESA_BOARD
+ WaitPeriod(read_sensor_data_period, 5*PERIOD_IN_TICKS);
+#endif
+
+ ObtainMutex(ctx->snr_mutex_id);
+
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[start_idx + i] = 0.4995f * cos_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter%TC_MAX]);
+ inSensorDataIm[start_idx + i] = 0.4995f * sin_aprox(i*2.0f*PI*FREQ[iter%TC_MAX]/FS)
+ + (noise_generator(0) * NOISE_FACTOR[iter % TC_MAX]);
+ }
+
+ ReleaseMutex(ctx->snr_mutex_id);
+ SendEvents(ctx->task_snr_process_data_id, EVENT_DATA_READY);
+
+ start_idx += FFT_SIZE;
+ iter++;
+
+ }
+
+ rtems_event_send(ctx->main_task, event_send[(TASK_COUNT-2)]);
+ DeleteRateMonotonic(read_sensor_data_period);
+ SuspendSelf();
+}
+
+static void task_snr_process_data(rtems_task_argument arg) {
+ test_context *ctx;
+ ctx = (test_context *)arg;
+ uint32_t start_idx = 0;
+ uint32_t iter = 0;
+ struct timespec begin_time;
+ struct timespec end_time;
+
+ while ( start_idx < SENSOR_DATA_ELEM ) {
+ ReceiveAllEvents(EVENT_DATA_READY);
+ ObtainMutex(ctx->snr_mutex_id);
+ rtems_clock_get_uptime(&begin_time);
+
+ //Apply Blackman-Harris Window
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = inSensorDataRe[start_idx+i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ inSensorDataIm[i] = inSensorDataIm[start_idx+i]*blackman_harris(i, FFT_SIZE)/ctx->scaling_fft_factor;
+ }
+
+ //Calculates FFT
+ fft(&inSensorDataRe[0], &inSensorDataIm[0], FFT_SIZE_LOG2);
+
+ //Calculates the magnitude values
+ for (uint32_t i = 0; i < FFT_SIZE; i++) {
+ inSensorDataRe[i] = (inSensorDataRe[i] * inSensorDataRe[i]
+ + inSensorDataIm[i] * inSensorDataIm[i]) / ((float)FFT_SIZE);
+ }
+
+ //Look for the peak Value and its index (no DC)
+ float maxValue = 0.0;
+ float maxValueIndex = -1;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if (inSensorDataRe[i] > maxValue) {
+ maxValue = inSensorDataRe[i];
+ maxValueIndex = i;
+ }
+ }
+
+ //Calculates the signal and noise power (no DC)
+ float sig = 0.0f;
+ float noise = 0.0f;
+ for (uint32_t i = 3; i < (FFT_SIZE / 2); i++) {
+ if ((i > maxValueIndex - 4) && (i < maxValueIndex + 4)) {
+ sig += (2 * inSensorDataRe[i]);
+ }
+ else {
+ noise += (2 * inSensorDataRe[i]);
+ }
+ }
+
+ if (!(sig > 0.0f)) { sig = 0.0000000001f; }
+ if (!(noise > 0.0f)) { noise = 0.0000000001f; }
+
+ //Calculates SNR
+ float snr_float = sig/noise;
+
+ if (snr_float > SNR_THRESHOLD) {
+ dsp_result[iter] = 1;
+ }
+ else {
+ dsp_result[iter] = 0;
+ }
+ rtems_clock_get_uptime(&end_time);
+
+ ctx->snr_process_time +=
+ (float)(end_time.tv_sec - begin_time.tv_sec) +
+ ( (float)((end_time.tv_nsec/1000) - (begin_time.tv_nsec/1000))/1000000.0);
+
+ ReleaseMutex(ctx->snr_mutex_id);
+ start_idx += FFT_SIZE;
+ iter++;
+ }
+
+ rtems_event_send(ctx->main_task, event_send[(TASK_COUNT-1)]);
+ SuspendSelf();
+}
+
+
+//=======================================================================================
+// INIT/MAIN Task
+//=======================================================================================
+static void Init(rtems_task_argument arg){
+ (void)arg;
+ test_context ctx;
+ uint32_t start_time, end_time, elapsed_time;
+ char ch, str[ITOA_STR_SIZE];
+ uint32_t total_events = 0;
+ uint8_t task = 255;
+ bool correctly_processed = true;
+ (void) memset(&ctx, 0, sizeof(test_context));
+ (void) memset(&count_process[0], 0, TOTAL_TILES);
+ (void) memset(&xL2[0], 0, xL2_ELEM);
+ (void) memset(&inSensorDataRe[0], 0, SENSOR_DATA_ELEM);
+ (void) memset(&inSensorDataIm[0], 0, SENSOR_DATA_ELEM);
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_regs soc_stats;
+#endif
+
+//-----------------------------------------------------------------------------
+// Create/Initialize Objects
+//-----------------------------------------------------------------------------
+ rtems_message_queue_config msg_config = {
+ .name = rtems_build_name('M', 'S', 'G', 'T'),
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE(msg_tile_queue_storage),
+ .maximum_message_size = MAX_MESSAGE_SIZE,
+ .storage_size = sizeof(msg_tile_queue_storage),
+ .storage_area = &msg_tile_queue_storage,
+ .attributes = RTEMS_FIFO | RTEMS_GLOBAL};
+
+ ctx.main_task = rtems_task_self();
+ ctx.tile_queue = CreateMessageQueue(msg_config);
+ ctx.ntiles = TOTAL_TILES;
+ ctx.next_tile = 1;
+
+ rtems_task_config calc_task_config = {
+ .initial_priority = PRIO_NORMAL,
+ .storage_size = TASK_STORAGE_SIZE,
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES};
+
+ ctx.filter_mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', '0'));
+ ctx.snr_mutex_id = CreateMutex(rtems_build_name('M', 'U', 'T', '1'));
+ SetSelfPriority( PRIO_NORMAL );
+
+ for (uint32_t i = 0; i < TASK_COUNT-2; i++){
+ ch = '0' + i;
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[i][0];
+
+ ctx.task_filter_simulation_id[i] = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_filter_simulation_id[i], calc_task_function, &ctx);
+ total_events += event_send[i];
+ }
+
+ ch = '0' + (TASK_COUNT-2);
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[(TASK_COUNT-2)][0];
+ ctx.task_snr_read_sensor_data_id = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_snr_read_sensor_data_id, task_snr_read_sensor_data, &ctx);
+
+ ch = '0' + (TASK_COUNT-1);
+ calc_task_config.name = rtems_build_name('R', 'U', 'N', ch);
+ calc_task_config.storage_area = &calc_task_storage[(TASK_COUNT-1)][0];
+ ctx.task_snr_process_data_id = DoCreateTask(calc_task_config);
+ StartTask(ctx.task_snr_process_data_id, task_snr_process_data, &ctx);
+
+//-----------------------------------------------------------------------------
+// Setup the testcase
+//-----------------------------------------------------------------------------
+ fill_main_memory_with_data();
+ l1_dcache_flush();
+ l1_dcache_disable();
+
+#ifdef GR740_ESA_BOARD
+ l2_cache_disable();
+ l2_cache_flush();
+ l2_cache_set_replacement_policy(L2_CACHE_REPL_PSEUDORANDOM, 0);
+ l2_cache_enable();
+#endif
+
+ l1_dcache_enable();
+ uint32_t control_data_word = warmup_caches();
+
+#ifdef GR740_ESA_BOARD
+ clockgating_enable_l4stat();
+ soc_stats_configure_regs();
+ soc_stats_init(&soc_stats);
+#endif
+
+ //Calculates mean of Blackman-Harris terms
+ ctx.scaling_fft_factor = 0.0;
+ for (uint32_t i = 0; i<FFT_SIZE; i++){
+ ctx.scaling_fft_factor += blackman_harris( i, FFT_SIZE);
+ }
+ ctx.scaling_fft_factor = ctx.scaling_fft_factor/ ((float) FFT_SIZE);
+
+//-----------------------------------------------------------------------------
+// Do the work: distribute the work through the tasks
+//-----------------------------------------------------------------------------
+ SendEvents(ctx.task_snr_read_sensor_data_id, GO_READ_SENSOR);
+ start_time = rtems_clock_get_ticks_since_boot();
+
+ rtems_event_set revents = ReceiveAvailableEvents();
+ while ( (revents & total_events) != total_events ) {
+ ReceiveMessage(ctx.tile_queue, &task);
+ SendMessage(ctx.message_queue[task], &ctx.next_tile, sizeof(ctx.next_tile));
+ ctx.next_tile++;
+ revents = ReceiveAvailableEvents();
+
+ }
+ // Wait for the SNR processing tasks to finish
+ ReceiveAllEvents(event_send[(TASK_COUNT-2)]);
+ ReceiveAllEvents(event_send[(TASK_COUNT-1)]);
+
+ end_time = rtems_clock_get_ticks_since_boot();
+ elapsed_time = end_time - start_time;
+
+#ifdef GR740_ESA_BOARD
+ soc_stats_update(&soc_stats);
+#endif
+
+//-----------------------------------------------------------------------------
+// Show Results
+//-----------------------------------------------------------------------------
+ print_string("\n");
+ print_string("Multicore Elapsed Time -");
+ print_string(itoa(elapsed_time, &str[0], 10));
+ print_string("\n");
+
+ for (uint8_t i = 0; i < ctx.ntiles; i++){
+ if (count_process[i] != 1){
+ correctly_processed = false;
+ break;
+ }
+ }
+
+ if (correctly_processed){
+ print_string("Each tile only processed once : true\n");
+ }
+ else{
+ print_string("Each tile only processed once : false\n");
+ }
+
+ print_string("Input Data Result Value : 0x");
+ print_string(itoa(control_data_word , &str[0], 16));
+ print_string("\n");
+
+ print_string("Ouput Data Result Value : 0x");
+ if (ctx.accxL2>=UINT32_MAX) {
+ print_string(itoa( (int32_t) ((ctx.accxL2 >> 32U) & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ print_string(itoa( (int32_t) (ctx.accxL2 & ((uint64_t)UINT32_MAX)) , &str[0], 16));
+ }
+ else {
+ print_string(itoa((int32_t)ctx.accxL2 , &str[0], 16));
+ }
+ print_string("\n");
+ print_string("Time used in filter sim processing : ");
+ print_string(itoa( (int32_t) (ctx.filter_sim_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("Time used in SNR processing : ");
+ print_string(itoa( (int32_t) (ctx.snr_process_time *1000) , &str[0], 10));
+ print_string(" ms\n");
+
+ print_string("SNR triggers found at : ");
+ for (uint32_t j = 0; j < MAX_ITER; j++)
+ if (dsp_result[j] > 0.0){
+ print_string(itoa(j, &str[0], 10));
+ print_string(" ");
+ }
+ print_string("\n");
+
+
+#ifdef GR740_ESA_BOARD
+ print_string("L1 Instr Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instr Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_inst_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_0 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[0], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_1 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[1], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_2 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[2], &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses (read) CPU_3 : ");
+ print_string(itoa(soc_stats.l1_data_cache_miss[3], &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_hits, &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses (read + writes) : ");
+ print_string(itoa(soc_stats.l2_cache_miss, &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(soc_stats.ahb_split_delay, &str[0], 10));
+ print_string("\n");
+ print_string("\n");
+#endif
+
+
+// --------------------------------------------------------------------------
+// Delete Objects and Finalize testcase
+// --------------------------------------------------------------------------
+ for (uint32_t i = 0; i < (TASK_COUNT-2); i++){
+ DeleteTask(ctx.task_filter_simulation_id[i]);
+ DeleteMessageQueue(ctx.message_queue[i]);
+ }
+
+ DeleteTask(ctx.task_snr_process_data_id);
+ DeleteTask(ctx.task_snr_read_sensor_data_id);
+
+ DeleteMutex(ctx.filter_mutex_id);
+ DeleteMutex(ctx.snr_mutex_id);
+
+ DeleteMessageQueue(ctx.tile_queue);
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, 0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS TEST_PROCESSORS
+
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES MAX_MESSAGE_QUEUES
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES 2
+
+#define CONFIGURE_MAXIMUM_PERIODS 3
+
+#define CONFIGURE_MAXIMUM_TASKS ( TASK_COUNT + 1 )
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE \
+ RTEMS_MINIMUM_STACK_SIZE + CPU_STACK_ALIGNMENT
+
+#define CONFIGURE_EXTRA_TASK_STACKS RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE 2 * TASK_STORAGE_SIZE
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
+ CONFIGURE_MAXIMUM_TASKS
+
+#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE MAX_TLS_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_ATTRIBUTES (RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES)
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/isvv/shared/isvv_rtems_aux.c b/testsuites/isvv/shared/isvv_rtems_aux.c
new file mode 100644
index 0000000000..b67bcc982e
--- /dev/null
+++ b/testsuites/isvv/shared/isvv_rtems_aux.c
@@ -0,0 +1,622 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include "isvv_rtems_aux.h"
+
+# define ITOA_STR_SIZE (8 * sizeof(int) + 1)
+
+/* ############################################### */
+/* Scheduler */
+/* ############################################### */
+rtems_id IdentifyScheduler( rtems_name name )
+{
+ rtems_id id;
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_ident( name, &id );
+ ASSERT_SUCCESS(sc);
+ return id;
+}
+
+void SetScheduler(rtems_id task_id, rtems_id scheduler_id, rtems_task_priority priority) {
+ rtems_status_code sc;
+
+ sc = rtems_task_set_scheduler( task_id, scheduler_id, priority );
+ ASSERT_SUCCESS( sc );
+}
+
+/* ############################################### */
+/* Tasks */
+/* ############################################### */
+rtems_id DoCreateTask( rtems_task_config task_config )
+{
+ rtems_id id;
+ rtems_status_code sc;
+
+ sc = rtems_task_construct(&task_config, &id);
+ ASSERT_SUCCESS(sc);
+ return id;
+}
+
+void StartTask( rtems_id id, rtems_task_entry entry, void *arg )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_start( id, entry, (rtems_task_argument) arg);
+ ASSERT_SUCCESS( sc );
+}
+
+void DeleteTask( rtems_id id )
+{
+ if ( id != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_task_delete( id );
+ ASSERT_SUCCESS( sc );
+ }
+}
+
+void SuspendTask( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_suspend( id );
+ ASSERT_SUCCESS( sc );
+}
+
+void SuspendSelf( void )
+{
+ SuspendTask( RTEMS_SELF );
+}
+
+void ResumeTask( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_resume( id );
+ ASSERT_SUCCESS( sc );
+}
+
+bool IsTaskSuspended( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_is_suspended( id );
+ return sc == RTEMS_ALREADY_SUSPENDED;
+}
+
+rtems_id TaskSelfId(void)
+{
+ rtems_id id;
+ rtems_status_code sc;
+
+ sc = rtems_task_ident(RTEMS_WHO_AM_I, RTEMS_SEARCH_ALL_NODES, &id);
+ ASSERT_SUCCESS( sc );
+ return id;
+}
+
+rtems_task_priority SetTaskPriority(rtems_id id, rtems_task_priority prio) {
+ rtems_status_code sc;
+ rtems_task_priority old_prio;
+
+ sc = rtems_task_set_priority(id, prio, &old_prio);
+ ASSERT_SUCCESS(sc);
+ return old_prio;
+}
+
+rtems_task_priority SetSelfPriority( rtems_task_priority priority )
+{
+ return SetTaskPriority( RTEMS_SELF, priority );
+}
+
+rtems_task_priority GetTaskPriority(rtems_id id) {
+ return SetTaskPriority(id, RTEMS_CURRENT_PRIORITY);
+}
+
+void SetTaskMode(rtems_mode mode_set, rtems_mode mask, rtems_mode previous_mode_set) {
+ rtems_status_code sc;
+
+ sc = rtems_task_mode(mode_set, mask, &previous_mode_set);
+ ASSERT_SUCCESS(sc);
+}
+
+rtems_mode GetTaskMode( void ) {
+ rtems_status_code sc;
+ rtems_mode mode_set;
+
+ // First parameter is ignored when second parameter is set to RTEMS_CURRENT_MODE
+ sc = rtems_task_mode(RTEMS_CURRENT_MODE, RTEMS_CURRENT_MODE, &mode_set);
+ ASSERT_SUCCESS(sc);
+
+ return mode_set;
+}
+
+// If task modes aren't equal to what we expect, print them out in hex
+bool ASSERT_TASK_MODES_EQ(rtems_mode RESULT_MODE, rtems_mode EXPECTED_MODE)
+{
+ char str[ITOA_STR_SIZE];
+ if (EXPECTED_MODE != RESULT_MODE)
+ {
+ print_string("TASK MODES NOT EXPECTED.\nRECEIVED-");
+ print_string(itoa(RESULT_MODE, &str[0], 16));
+ print_string(" EXPECTED-");
+ print_string(itoa(EXPECTED_MODE, &str[0], 16));
+ print_string("\n");
+ }
+
+ return (EXPECTED_MODE == RESULT_MODE);
+}
+
+/* ############################################### */
+/* Semaphores */
+/* ############################################### */
+rtems_id CreateMutex( rtems_name name )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(name, 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_INHERIT_PRIORITY,
+ 0, &id);
+ ASSERT_SUCCESS( sc );
+
+ return id;
+}
+
+rtems_id CreateMutexNoProtocol( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(rtems_build_name('M', 'U', 'T', 'X'), 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY, 0, &id);
+ ASSERT_SUCCESS( sc );
+
+ return id;
+}
+
+rtems_id CreateMutexNoLocking( rtems_name name )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(name, 3, RTEMS_NO_INHERIT_PRIORITY, 0, &id);
+ ASSERT_SUCCESS( sc );
+
+ return id;
+}
+
+rtems_id CreateMutexFIFO( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(rtems_build_name('M', 'U', 'T', 'X'), 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_FIFO, 0, &id);
+ ASSERT_SUCCESS(sc);
+
+ return id;
+}
+
+rtems_id CreateMutexMrsP( rtems_name name )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(name, 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_ULTRA_HIGH, &id);
+ ASSERT_SUCCESS(sc);
+
+ return id;
+}
+
+void ObtainMutex( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
+ ASSERT_SUCCESS(sc);
+}
+
+void ReleaseMutex( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_release( id );
+ ASSERT_SUCCESS( sc );
+}
+
+void DeleteMutex( rtems_id id )
+{
+ if ( id != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_delete( id );
+ ASSERT_SUCCESS(sc);
+ }
+}
+
+rtems_id CreateCounterSemaphore( rtems_name name, uint32_t count )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(name, count, RTEMS_DEFAULT_ATTRIBUTES, 0, &id);
+ ASSERT_SUCCESS( sc );
+
+ return id;
+}
+
+void ObtainCounterSemaphore( rtems_id id )
+{
+ ObtainMutex(id);
+}
+
+void ReleaseCounterSemaphore( rtems_id id)
+{
+ ReleaseMutex(id);
+}
+
+
+/* ############################################### */
+/* Messages */
+/* ############################################### */
+rtems_id CreateMessageQueue(rtems_message_queue_config config) {
+ rtems_id id;
+ rtems_status_code sc;
+
+ sc = rtems_message_queue_construct(&config, &id);
+ ASSERT_SUCCESS(sc);
+ return id;
+}
+
+void SendMessage(rtems_id id, void *buffer, size_t size) {
+ rtems_status_code sc;
+
+ sc = rtems_message_queue_send(id, buffer, size);
+ ASSERT_SUCCESS(sc);
+}
+
+void ReceiveMessage(rtems_id id, void *buffer) {
+ rtems_status_code sc;
+ size_t size;
+
+ sc = rtems_message_queue_receive(id, buffer, &size, RTEMS_DEFAULT_OPTIONS,
+ RTEMS_NO_TIMEOUT);
+ ASSERT_SUCCESS(sc);
+}
+
+void DeleteMessageQueue( rtems_id id )
+{
+ if ( id != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_message_queue_delete( id );
+ ASSERT_SUCCESS(sc);
+ }
+}
+
+
+/* ############################################### */
+/* Events */
+/* ############################################### */
+rtems_event_set ReceiveAllEvents( rtems_event_set events )
+{
+ rtems_status_code sc;
+ rtems_event_set received;
+
+ received = 0;
+ sc = rtems_event_receive(events, RTEMS_EVENT_ALL | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT, &received);
+ ASSERT_SUCCESS(sc);
+ return received;
+}
+
+rtems_event_set ReceiveAvailableEvents( void )
+{
+ rtems_status_code sc;
+ rtems_event_set events;
+
+ events = 0;
+ sc = rtems_event_receive(RTEMS_PENDING_EVENTS,
+ RTEMS_EVENT_ALL | RTEMS_WAIT, 0, &events);
+ if (sc != RTEMS_TIMEOUT) ASSERT_SUCCESS(sc);
+
+ return events;
+}
+
+rtems_event_set QueryPendingEvents( void )
+{
+ rtems_status_code sc;
+ rtems_event_set events;
+
+ events = 0;
+ sc = rtems_event_receive(RTEMS_PENDING_EVENTS,
+ RTEMS_EVENT_ALL | RTEMS_NO_WAIT, 0, &events);
+ ASSERT_SUCCESS(sc);
+
+ return events;
+}
+
+rtems_event_set ReceiveAnyEvents( void )
+{
+ return ReceiveAnyEventsTimed( RTEMS_NO_TIMEOUT );
+}
+
+rtems_event_set ReceiveAnyEventsTimed(rtems_interval ticks)
+{
+ rtems_status_code sc;
+ rtems_event_set events;
+
+ events = 0;
+ sc = rtems_event_receive(RTEMS_ALL_EVENTS, RTEMS_EVENT_ANY | RTEMS_WAIT,
+ ticks, &events);
+ ASSERT_SUCCESS(sc);
+
+ return events;
+}
+
+void SendEvents( rtems_id id, rtems_event_set events )
+{
+ rtems_status_code sc;
+
+ sc = rtems_event_send( id, events );
+ ASSERT_SUCCESS(sc);
+}
+
+/* ############################################### */
+/* Rate Monotonic */
+/* ############################################### */
+rtems_id CreateRateMonotonic( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_rate_monotonic_create(rtems_build_name( 'R', 'M', 'O', 'N' ), &id);
+ ASSERT_SUCCESS( sc );
+
+ return id;
+}
+
+bool DoesPeriodTimeOut( rtems_id id, rtems_interval period )
+{
+ rtems_status_code sc;
+ bool timeout = false;
+
+ sc = rtems_rate_monotonic_period(id, period);
+ if (sc == RTEMS_TIMEOUT) {
+ timeout = true;
+ } else {
+ ASSERT_SUCCESS(sc);
+ }
+
+ return timeout;
+}
+
+void WaitPeriod( rtems_id id, rtems_interval period )
+{
+ rtems_status_code sc;
+
+ sc = rtems_rate_monotonic_period(id, period);
+ ASSERT_SUCCESS(sc);
+}
+
+void DeleteRateMonotonic( rtems_id id )
+{
+ if ( id != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_rate_monotonic_delete( id );
+ ASSERT_SUCCESS(sc);
+ }
+}
+
+
+/* ############################################### */
+/* Timer */
+/* ############################################### */
+rtems_id CreateTimer( rtems_name name )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_timer_create(name, &id);
+ ASSERT_SUCCESS( sc );
+
+ return id;
+}
+
+void LaunchFunctionAfter(rtems_id id, rtems_interval ticks,
+ rtems_timer_service_routine_entry routine,
+ void *user_data) {
+ rtems_status_code sc;
+ sc = rtems_timer_fire_after(id, ticks, routine, user_data);
+ ASSERT_SUCCESS(sc);
+}
+
+void ResetTimer( rtems_id id ) {
+ rtems_status_code sc;
+ sc = rtems_timer_reset( id );
+ ASSERT_SUCCESS(sc);
+}
+
+void DeleteTimer( rtems_id id )
+{
+ if ( id != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_timer_delete( id );
+ ASSERT_SUCCESS(sc);
+ }
+}
+
+/* ############################################### */
+/* Barrier */
+/* ############################################### */
+rtems_id CreateAutomaticBarrier( uint8_t nbarriers )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_barrier_create(rtems_build_name('B', 'A', 'R', 'A'),
+ RTEMS_BARRIER_AUTOMATIC_RELEASE, nbarriers, &id);
+ ASSERT_SUCCESS( sc );
+
+ return id;
+}
+
+rtems_id CreateManualBarrier(void)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_barrier_create(rtems_build_name('B', 'A', 'R', 'M'),
+ RTEMS_BARRIER_MANUAL_RELEASE, 0, &id);
+ ASSERT_SUCCESS( sc );
+
+ return id;
+}
+
+void WaitAtBarrier( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_barrier_wait(id, BARRIER_TIMEOUT);
+ ASSERT_SUCCESS( sc );
+}
+
+void ReleaseManualBarrier( rtems_id id, uint32_t n_barriers_to_release )
+{
+ rtems_status_code sc;
+ uint32_t released;
+ uint32_t total_released = 0;
+
+ while (total_released < n_barriers_to_release) {
+ sc = rtems_barrier_release(id, &released);
+ ASSERT_SUCCESS(sc);
+ total_released += released;
+ }
+}
+
+void DeleteBarrier( rtems_id id )
+{
+ if ( id != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_barrier_delete( id );
+ ASSERT_SUCCESS(sc);
+ }
+}
+
+/* ############################################### */
+/* Other */
+/* ############################################### */
+/* char GetRandomChar(void) { */
+/* return "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" */
+/* [rand() % 62]; */
+/* } */
+
+/* rtems_name BuildRandomName( void ) { */
+/* return rtems_build_name(GetRandomChar(),GetRandomChar(),GetRandomChar(),GetRandomChar()); */
+/* } */
+
+Thread_Control *GetThread( rtems_id id )
+{
+ Thread_Control *the_thread;
+ ISR_lock_Context lock_context;
+
+ the_thread = _Thread_Get( id, &lock_context );
+
+ if ( the_thread == NULL ) {
+ return NULL;
+ }
+
+ _ISR_lock_ISR_enable( &lock_context);
+ return the_thread;
+}
+
+void WaitForExecutionStop( rtems_id task_id )
+{
+#if defined( RTEMS_SMP )
+ Thread_Control *the_thread;
+
+ the_thread = GetThread( task_id );
+
+ while ( _Thread_Is_executing_on_a_processor( the_thread ) ) {
+ /* Wait */
+ }
+#else
+ (void) task_id;
+#endif
+}
+
+void WaitForIntendToBlock( rtems_id task_id )
+{
+#if defined( RTEMS_SMP )
+ Thread_Control *the_thread;
+ Thread_Wait_flags intend_to_block;
+
+ the_thread = GetThread( task_id );
+
+ intend_to_block = THREAD_WAIT_CLASS_OBJECT |
+ THREAD_WAIT_STATE_INTEND_TO_BLOCK;
+
+ while ( _Thread_Wait_flags_get_acquire( the_thread ) != intend_to_block ) {
+ /* Wait */
+ }
+#else
+ (void) task_id;
+#endif
+}
+
+rtems_task_priority GetPriorityByScheduler(rtems_id task_id,
+ rtems_id scheduler_id) {
+ rtems_status_code sc;
+ rtems_task_priority priority;
+
+ priority = PRIO_INVALID;
+ sc = rtems_task_get_priority( task_id, scheduler_id, &priority );
+
+ if ( sc != RTEMS_SUCCESSFUL ) {
+ return PRIO_INVALID;
+ }
+
+ return priority;
+}
diff --git a/testsuites/isvv/shared/isvv_rtems_aux.h b/testsuites/isvv/shared/isvv_rtems_aux.h
new file mode 100644
index 0000000000..8b4988756f
--- /dev/null
+++ b/testsuites/isvv/shared/isvv_rtems_aux.h
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <rtems.h>
+#include <rtems/score/percpu.h>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#include <rtems/score/threadimpl.h>
+#pragma GCC diagnostic pop
+#include "utils.h"
+
+typedef enum {
+ PRIO_PSEUDO_ISR,
+ PRIO_VERY_ULTRA_HIGH,
+ PRIO_ULTRA_HIGH,
+ PRIO_VERY_HIGH,
+ PRIO_HIGH,
+ PRIO_NORMAL,
+ PRIO_LOW,
+ PRIO_VERY_LOW,
+ PRIO_ULTRA_LOW
+} Priority;
+
+#define INVALID_ID 0xfffffffd
+#define PRIO_INVALID 0xfffffffe
+
+#define BARRIER_TIMEOUT 10000
+
+#define SCHEDULER_A_NAME rtems_build_name( 'A', ' ', ' ', ' ' )
+#define SCHEDULER_B_NAME rtems_build_name( 'B', ' ', ' ', ' ' )
+#define SCHEDULER_C_NAME rtems_build_name( 'C', ' ', ' ', ' ' )
+#define SCHEDULER_D_NAME rtems_build_name( 'D', ' ', ' ', ' ' )
+
+typedef struct {
+ rtems_name name;
+ uint32_t count;
+ size_t max_message_size;
+} message_config;
+
+rtems_id IdentifyScheduler(rtems_name name);
+
+void SetScheduler(rtems_id task_id, rtems_id scheduler_id, rtems_task_priority priority);
+
+rtems_id DoCreateTask( rtems_task_config task_config );
+
+void StartTask( rtems_id id, rtems_task_entry entry, void *arg );
+
+void DeleteTask(rtems_id id);
+
+void SuspendTask( rtems_id id );
+
+void SuspendSelf( void );
+
+void ResumeTask( rtems_id id );
+
+bool IsTaskSuspended(rtems_id id);
+
+rtems_id TaskSelfId(void);
+
+rtems_task_priority SetTaskPriority( rtems_id id, rtems_task_priority prio );
+
+rtems_task_priority SetSelfPriority( rtems_task_priority priority );
+
+rtems_task_priority GetTaskPriority(rtems_id id);
+
+void SetTaskMode(rtems_mode mode_set, rtems_mode mask, rtems_mode previous_mode_set);
+
+rtems_mode GetTaskMode( void );
+
+bool ASSERT_TASK_MODES_EQ(rtems_mode RESULT_MODE, rtems_mode EXPECTED_MODE);
+
+rtems_id CreateMutex( rtems_name name );
+
+rtems_id CreateMutexNoProtocol( void );
+
+rtems_id CreateMutexNoLocking( rtems_name name );
+
+rtems_id CreateMutexFIFO( void );
+
+rtems_id CreateMutexMrsP( rtems_name name );
+
+void ObtainMutex( rtems_id id );
+
+void ReleaseMutex( rtems_id id );
+
+void DeleteMutex( rtems_id id );
+
+rtems_id CreateCounterSemaphore( rtems_name name, uint32_t count );
+
+void ObtainCounterSemaphore( rtems_id id );
+
+void ReleaseCounterSemaphore( rtems_id id);
+
+rtems_id CreateMessageQueue(rtems_message_queue_config config);
+
+void SendMessage(rtems_id id, void *buffer, size_t size);
+
+void ReceiveMessage(rtems_id id, void *buffer);
+
+void DeleteMessageQueue(rtems_id id);
+
+rtems_event_set ReceiveAllEvents( rtems_event_set events );
+
+rtems_event_set ReceiveAnyEvents(void);
+
+rtems_event_set ReceiveAnyEventsTimed(rtems_interval ticks);
+
+rtems_event_set ReceiveAvailableEvents( void );
+
+rtems_event_set QueryPendingEvents( void );
+
+void SendEvents( rtems_id id, rtems_event_set events );
+
+rtems_id CreateRateMonotonic( void );
+
+bool DoesPeriodTimeOut( rtems_id id, rtems_interval period );
+
+void WaitPeriod( rtems_id id, rtems_interval period );
+
+void DeleteRateMonotonic( rtems_id id );
+
+rtems_id CreateTimer( rtems_name name );
+
+void LaunchFunctionAfter(rtems_id id, rtems_interval ticks,
+ rtems_timer_service_routine_entry routine,
+ void *user_data);
+
+void ResetTimer( rtems_id id );
+
+void DeleteTimer( rtems_id id );
+
+rtems_id CreateAutomaticBarrier( uint8_t nbarriers );
+
+rtems_id CreateManualBarrier(void);
+
+void WaitAtBarrier( rtems_id id );
+
+void ReleaseManualBarrier( rtems_id id, uint32_t n_barriers_to_release);
+
+void DeleteBarrier( rtems_id id );
+
+char GetRandomChar( void );
+
+rtems_name BuildRandomName( void );
+
+Thread_Control *GetThread( rtems_id id );
+
+void WaitForExecutionStop( rtems_id task_id );
+
+void WaitForIntendToBlock( rtems_id task_id );
+
+rtems_task_priority GetPriorityByScheduler( rtems_id task_id, rtems_id scheduler_id );
diff --git a/testsuites/isvv/shared/low_level_utils.c b/testsuites/isvv/shared/low_level_utils.c
new file mode 100644
index 0000000000..5c46f239bb
--- /dev/null
+++ b/testsuites/isvv/shared/low_level_utils.c
@@ -0,0 +1,464 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <string.h>
+#include "low_level_utils.h"
+#include "utils.h"
+
+// ------------------------------------------------------------------------------------------------
+// Pricate Declarations
+// ------------------------------------------------------------------------------------------------
+
+// Processor numeration
+#define CPU_0 (0U)
+#define CPU_1 (1U)
+#define CPU_2 (2U)
+#define CPU_3 (3U)
+
+// L1 Cache Bit registers bit definitions
+#define L1_CACHE_CTRL_FD (0x00400000U)
+#define L1_CACHE_CTRL_DP (0x00004000U)
+#define L1_CACHE_CTRL_DCS (0x0000000CU)
+
+// L1 Cache Replacement policies
+#define L1_CACHE_REPL_MAX (3U)
+#define L1_CACHE_REPL_MASK (0xCFFFFFFF)
+#define L1_CACHE_REPL_SHIFT (28U)
+
+// L2 Cache Bit registers bit definitions
+#define L2_CACHE_L2CC_EN (0x80000000U)
+#define L2_CACHE_L2CFMA_FMODE_FLUSH_ALL (0x00000007U)
+
+// L2 Cache Replacement policies
+#define L2_CACHE_REPL_MAX (3U)
+#define L2_CACHE_ENABLE_SPLIT_RESPONSES (0x00000002U)
+
+#define L2_CACHE_REPL_MASK (0xCFFFFFFF)
+#define L2_CACHE_REPL_SHIFT (28U)
+#define L2_CACHE_WAYS_MAX (4U)
+#define L2_CACHE_WAYS_MASK (0xFFFFF0FF)
+#define L2_CACHE_WAYS_LOCK_SHIFT (8U)
+#define L2_CACHE_INDEX_WAYS_MASK (0xFFFF0FFF)
+#define L2_CACHE_INDEX_WAYS_SHIFT (12U)
+
+// L4 Stats definitions
+#define L4_STAT_CLEAR_COUNTER_ON_READ (0x00002000U)
+#define L4_STAT_ENABLE_COUNTER (0x00001000U)
+#define L4_STAT_L1_INST_CACHE_MISS_EVENT (0x00000000U)
+#define L4_STAT_L1_DATA_CACHE_MISS_EVENT (0x00000008U)
+#define L4_STAT_L2_CACHE_HIT_EVENT (0x00000060U)
+#define L4_STAT_L2_CACHE_MISS_EVENT (0x00000061U)
+#define L4_STAT_AHB_SPLIT_DELAY_EVENT (0x0000004EU)
+#define L4_STAT_EVENT_ID_SHIFT (0x00000004U)
+#define L4_STAT_EVENT_ID_MASK (0x00000FF0U)
+#define L4_STAT_CPU_SHIFT (0x00000000U)
+#define L4_STAT_CPU_MASK (0x0000000FU)
+
+
+typedef struct l4stat_regs {
+ uint32_t cval[32]; /* 0x000 */
+ uint32_t cctrl[32]; /* 0x080 */
+ uint32_t cmax[32]; /* 0x100 */
+ uint32_t timestamp; /* 0x180 */
+} l4stat_regs;
+
+
+// ------------------------------------------------------------------------------------------------
+// Leon3/4 internal registers access - Public functions implementation
+// ------------------------------------------------------------------------------------------------
+
+uint32_t leon3_get_configuration_register(void) {
+ uint32_t asr17;
+ __asm__ volatile ("mov %%asr17, %0" : "=&r" (asr17) );
+ return asr17;
+}
+
+uint32_t leon3_get_psr_register(void) {
+ uint32_t psr;
+ __asm__ volatile ("mov %%psr, %0" : "=&r" (psr) );
+ return psr;
+}
+
+uint32_t leon3_get_wim_register(void) {
+ uint32_t wim;
+ __asm__ volatile ("mov %%wim, %0" : "=&r" (wim) );
+ return wim;
+}
+
+uint32_t leon3_get_tbr_register(void) {
+ uint32_t tbr;
+ __asm__ volatile ("mov %%tbr, %0" : "=&r" (tbr) );
+ return tbr;
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// L1 Cache peripheral/module - Public functions implementation
+// ------------------------------------------------------------------------------------------------
+
+void l1_dcache_disable(void) {
+ // Set the Data Cache state bits (DCS bits 3:2) to '00' in the Cache control register
+ uint32_t cache_reg = leon3_get_cache_control_register();
+ cache_reg &= ~L1_CACHE_CTRL_DCS;
+ leon3_set_cache_control_register(cache_reg);
+}
+
+void l1_dcache_enable(void) {
+ // Set the Data Cache state bits (DCS bits 3:2) to '11' in the Cache control register
+ uint32_t cache_reg = leon3_get_cache_control_register();
+ cache_reg |= L1_CACHE_CTRL_DCS;
+ leon3_set_cache_control_register(cache_reg);
+}
+
+void l1_dcache_flush(void) {
+ // Set the Flush data cache bit (FD - bit 22) to '1' in the Cache control register
+ uint32_t cache_reg = leon3_get_cache_control_register();
+ cache_reg |= L1_CACHE_CTRL_FD;
+ leon3_set_cache_control_register(cache_reg);
+
+ // Loop while the Data cache flush pending bit (DP - 14) in the Cache control register is set to '1'
+ do {
+ cache_reg = leon3_get_cache_control_register();
+ }
+ while ( (cache_reg & L1_CACHE_CTRL_DP) == L1_CACHE_CTRL_DP);
+}
+
+void l1_dcache_set_replacement_policy(uint32_t policy) {
+ if (policy <= L1_CACHE_REPL_MAX){
+ uint32_t cache_reg = leon3_get_data_cache_config_register();
+ cache_reg = (cache_reg & L1_CACHE_REPL_MASK) | (policy << L1_CACHE_REPL_SHIFT);
+ // There is no leon3_set_data_cache_config_register() in leon3.h, so a lower level function is used
+ leon3_set_system_register( 0xC, cache_reg );
+ }
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// L2 Cache peripheral/module - Public functions implementation
+// ------------------------------------------------------------------------------------------------
+
+void l2_cache_disable(void) {
+ // Set the L2 Controller Cache enable bit register (EN bit 31) to '0' in the L2C Control register (L2CS)
+ volatile l2cache *regs;
+ regs = (l2cache *) LEON3_L2CACHE_BASE;
+ uint32_t status = regs->l2cc;
+ status &= ~L2_CACHE_L2CC_EN;
+ regs->l2cc = status;
+}
+
+void l2_cache_enable(void) {
+ // Set the L2 Controller Cache enable bit register (EN bit 31) to '1' in the L2C Control register (L2CS)
+ volatile l2cache *regs;
+ regs = (l2cache *) LEON3_L2CACHE_BASE;
+ uint32_t status = regs->l2cc;
+ status |= L2_CACHE_L2CC_EN;
+ regs->l2cc = status;
+}
+
+void l2_cache_flush(void) {
+ // Set the L2 Flush mode bit registers ( FMODE bits 2:0) to '111' in the "L2C Flush
+ // (Memory address) register" (L2CFMA)
+ volatile l2cache *regs;
+ regs = (l2cache *) LEON3_L2CACHE_BASE;
+ uint32_t status = L2_CACHE_L2CFMA_FMODE_FLUSH_ALL;
+ regs->l2cfma = status;
+
+ // There is no active way to wait for the L2 flush to finish, so a loop is added
+ Loop(1000);
+}
+
+void l2_cache_set_replacement_policy(uint32_t policy, uint32_t index_way) {
+ // The index_way is only used if the Policy is L2_CACHE_REPL_MASTERINDEX_REPLACE
+ // (10: Master-index using index-replace field)
+ if ((policy <= L2_CACHE_REPL_MAX) && (index_way <= L2_CACHE_REPL_MAX)) {
+ volatile l2cache *regs;
+ regs = (l2cache *) LEON3_L2CACHE_BASE;
+ uint32_t status = regs->l2cc;
+ status = (status & L2_CACHE_REPL_MASK) | (policy << L2_CACHE_REPL_SHIFT) ;
+ if ( policy == L2_CACHE_REPL_MASTERINDEX_REPLACE)
+ status = (status & L2_CACHE_INDEX_WAYS_MASK)| (index_way << L2_CACHE_INDEX_WAYS_SHIFT);
+ regs->l2cc = status;
+ }
+}
+
+void l2_cache_set_way_lock(uint32_t ways) {
+ // We can only control the number of cache ways to be locked:
+ // if 1 way is to be locked then way#4 is locked,
+ // if 2 ways are to be locked then way#3 and way#4 are locked,
+ // if 3 ways are to be locked then way#2, way#3 and way#4 are locked,
+ // otherwise all cache ways are locked.
+
+ if (ways <= L2_CACHE_WAYS_MAX) {
+ volatile l2cache *regs;
+ regs = (l2cache *) LEON3_L2CACHE_BASE;
+ uint32_t status = regs->l2cc;
+ status = (status & L2_CACHE_WAYS_MASK) | (ways << L2_CACHE_WAYS_LOCK_SHIFT);
+ regs->l2cc = status;
+ }
+}
+
+void l2_cache_enable_split_responses(void) {
+ volatile l2cache *regs;
+ regs = (l2cache *) LEON3_L2CACHE_BASE;
+ uint32_t status = regs->l2caccc;
+ status |= L2_CACHE_ENABLE_SPLIT_RESPONSES;
+ regs->l2caccc = status;
+}
+
+void l2_cache_disable_split_responses(void) {
+ volatile l2cache *regs;
+ regs = (l2cache *) LEON3_L2CACHE_BASE;
+ uint32_t status = regs->l2caccc;
+ status &= ~L2_CACHE_ENABLE_SPLIT_RESPONSES;
+ regs->l2caccc = status;
+}
+
+size_t l2_cache_get_size(void) {
+ volatile l2cache *regs;
+ unsigned status;
+ unsigned ways;
+ unsigned set_size;
+
+ regs = (l2cache *) LEON3_L2CACHE_BASE;
+ status = regs->l2cs;
+ ways = L2CACHE_L2CS_WAY_GET(status) + 1;
+ set_size = L2CACHE_L2CS_WAY_SIZE_GET(status) * 1024;
+
+ return ways * set_size;
+}
+
+
+void l2_cache_print_tags(uint32_t n) {
+ const uint32_t LEON3_L2CACHE_TAGS_OFFSET_ADDR = 0x80000U;
+ char str[8*sizeof(int)+1];
+
+ for ( uint32_t i=0; i<32*n; i+=4) {
+ volatile uint32_t addr = LEON3_L2CACHE_BASE + LEON3_L2CACHE_TAGS_OFFSET_ADDR + i;
+ if (addr%32 < 16) {
+ print_string("L2 cache Tag @addr[0x");
+ print_string(itoa( addr, &str[0], 16));
+ print_string("] : 0x");
+ print_string(itoa(grlib_load_32((void*)(addr)), &str[0], 16));
+ print_string("\n");
+ }
+ }
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// Leon4 Statistics peripheral/module - Public functions implementation
+// ------------------------------------------------------------------------------------------------
+
+void soc_stats_configure_regs(void) {
+ volatile l4stat_regs *regs;
+ uint32_t status;
+
+ regs = (l4stat_regs *) L4_STAT_BASE;
+
+ // "Counter 0 value register": Event "0x00 Instruction Data cache (read) miss" on processor #0
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L1_INST_CACHE_MISS_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ status |= CPU_0 << L4_STAT_CPU_SHIFT;
+ regs->cctrl[0] = status;
+
+ // "Counter 1 value register": Event "0x00 Instruction cache (read) miss" on processor #1
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L1_INST_CACHE_MISS_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ status |= CPU_1 << L4_STAT_CPU_SHIFT;
+ regs->cctrl[1] = status;
+
+ // "Counter 2 value register": Event "0x00 Instruction cache (read) miss" on processor #2
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L1_INST_CACHE_MISS_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ status |= CPU_2 << L4_STAT_CPU_SHIFT;
+ regs->cctrl[2] = status;
+
+ // "Counter 3 value register": Event 0x00 Instruction cache (read) miss" on processor #3
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L1_INST_CACHE_MISS_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ status |= CPU_3 << L4_STAT_CPU_SHIFT;
+ regs->cctrl[3] = status;
+
+ // "Counter 4 value register": Event "0x08 Data cache (read) miss" on processor #0
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L1_DATA_CACHE_MISS_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ status |= CPU_0 << L4_STAT_CPU_SHIFT;
+ regs->cctrl[4] = status;
+
+ // "Counter 5 value register": Event "0x08 Data cache (read) miss" on processor #1
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L1_DATA_CACHE_MISS_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ status |= CPU_1 << L4_STAT_CPU_SHIFT;
+ regs->cctrl[5] = status;
+
+ // "Counter 6 value register": Event "0x08 Data cache (read) miss" on processor #2
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L1_DATA_CACHE_MISS_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ status |= CPU_2 << L4_STAT_CPU_SHIFT;
+ regs->cctrl[6] = status;
+
+ // "Counter 7 value register": Event "0x08 Data cache (read) miss" on processor #3
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L1_DATA_CACHE_MISS_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ status |= CPU_3 << L4_STAT_CPU_SHIFT;
+ regs->cctrl[7] = status;
+
+ // "Counter 8 value register": Event "0x60 L2 cache hits (external event 0, CPU/AHBM
+ // field can select AHB master)"
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L2_CACHE_HIT_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ regs->cctrl[8] = status;
+
+ // "Counter 9 value register": Event "0x61 L2 cache miss (external event 1, CPU/AHBM
+ // field can select AHB master)"
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_L2_CACHE_MISS_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ regs->cctrl[9] = status;
+
+ // "Counter 10 value register": Event "0x4E AHB SPLIT delay. Filtered on CPU/AHBM
+ // if SU(1) = ‘1‘"
+ status = L4_STAT_CLEAR_COUNTER_ON_READ | L4_STAT_ENABLE_COUNTER;
+ status |= L4_STAT_AHB_SPLIT_DELAY_EVENT << L4_STAT_EVENT_ID_SHIFT;
+ status |= CPU_1 << L4_STAT_CPU_SHIFT;
+ regs->cctrl[10] = status;
+}
+
+void soc_stats_init(soc_stats_regs *stats) {
+ volatile l4stat_regs *regs;
+ regs = (l4stat_regs *) L4_STAT_BASE;
+
+ memset(stats, 0, sizeof(soc_stats_regs));
+
+ // The following dummy read operations purpose is to clean the statistcs counters
+ (void) regs->cval[0];
+ (void) regs->cval[1];
+ (void) regs->cval[2];
+ (void) regs->cval[3];
+ (void) regs->cval[4];
+ (void) regs->cval[5];
+ (void) regs->cval[6];
+ (void) regs->cval[7];
+ (void) regs->cval[8];
+ (void) regs->cval[9];
+ (void) regs->cval[10];
+}
+
+void soc_stats_update(soc_stats_regs *stats){
+ volatile l4stat_regs *regs;
+
+ regs = (l4stat_regs *) L4_STAT_BASE;
+ stats->l1_inst_cache_miss[0] += regs->cval[0];
+ stats->l1_inst_cache_miss[1] += regs->cval[1];
+ stats->l1_inst_cache_miss[2] += regs->cval[2];
+ stats->l1_inst_cache_miss[3] += regs->cval[3];
+ stats->l1_data_cache_miss[0] += regs->cval[4];
+ stats->l1_data_cache_miss[1] += regs->cval[5];
+ stats->l1_data_cache_miss[2] += regs->cval[6];
+ stats->l1_data_cache_miss[3] += regs->cval[7];
+ stats->l2_cache_hits += regs->cval[8];
+ stats->l2_cache_miss += regs->cval[9];
+ stats->ahb_split_delay += regs->cval[10];
+}
+
+void l4_stats_print(void) {
+ char str[8*sizeof(int)+1];
+ print_string("------------------------------------------------------------\n");
+ print_string("Printing L4 STAT REGS current value\n");
+ print_string("L1 Instructions Cache misses CPU_0 : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x00U)), &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instructions Cache misses CPU_1 : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x04U)), &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instructions Cache misses CPU_2 : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x08U)), &str[0], 10));
+ print_string("\n");
+ print_string("L1 Instructions Cache misses CPU_3 : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x0CU)), &str[0], 10));
+ print_string("L1 Data Cache misses CPU_0 : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x10U)), &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses CPU_1 : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x14U)), &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses CPU_2 : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x18U)), &str[0], 10));
+ print_string("\n");
+ print_string("L1 Data Cache misses CPU_3 : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x1CU)), &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache hits : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x20U)), &str[0], 10));
+ print_string("\n");
+ print_string("L2 Cache misses : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x24U)), &str[0], 10));
+ print_string("\n");
+ print_string("AHB Splits : ");
+ print_string(itoa(grlib_load_32((uint32_t*)( L4_STAT_BASE +0x30U)), &str[0], 10));
+ print_string("\n");
+}
+
+// ------------------------------------------------------------------------------------------------
+// Clock Gating peripheral/module - Public functions implementation
+// ------------------------------------------------------------------------------------------------
+
+void clockgating_enable_l4stat(void) {
+ // 1. Write a 1 to the corresponding bit in the unlock register
+ volatile uint32_t reg = grlib_load_32((uint32_t*)(GRCLKGATE_BASE + 0x00U));
+ reg |= 0x40LU;
+ grlib_store_32((uint32_t*)(GRCLKGATE_BASE + 0x00U), reg);
+
+ // 2. Write a 1 to the corresponding bit in the core reset register
+ reg = grlib_load_32((uint32_t*)(GRCLKGATE_BASE + 0x08U));
+ reg |= 0x40LU;
+ grlib_store_32((uint32_t*)(GRCLKGATE_BASE + 0x08U), reg);
+
+ // 3. Write a 1 to the corresponding bit in the clock enable register
+ reg = grlib_load_32((uint32_t*)(GRCLKGATE_BASE + 0x04U));
+ reg |= 0x40LU;
+ grlib_store_32((uint32_t*)(GRCLKGATE_BASE + 0x04U), reg);
+
+ // 4. Write a 0 to the corresponding bit in the clock enable register
+ reg = grlib_load_32((uint32_t*)(GRCLKGATE_BASE + 0x04U));
+ reg &= ~0x40LU;
+ grlib_store_32((uint32_t*)(GRCLKGATE_BASE + 0x04U), reg);
+
+ // 5. Write a 0 to the corresponding bit in the core reset register
+ reg = grlib_load_32((uint32_t*)(GRCLKGATE_BASE + 0x08U));
+ reg &= ~0x40LU;
+ grlib_store_32((uint32_t*)(GRCLKGATE_BASE + 0x08U), reg);
+
+ // 6. Write a 1 to the corresponding bit in the clock enable register
+ reg = grlib_load_32((uint32_t*)(GRCLKGATE_BASE + 0x04U));
+ reg |= 0x40LU;
+ grlib_store_32((uint32_t*)(GRCLKGATE_BASE + 0x04U), reg);
+
+ // 7. Write a 0 to the corresponding bit in the unlock register
+ reg = grlib_load_32((uint32_t*)(GRCLKGATE_BASE + 0x00U));
+ reg &= ~0x40LU;
+ grlib_store_32((uint32_t*)(GRCLKGATE_BASE + 0x00U), reg);
+}
diff --git a/testsuites/isvv/shared/low_level_utils.h b/testsuites/isvv/shared/low_level_utils.h
new file mode 100644
index 0000000000..22f0de4369
--- /dev/null
+++ b/testsuites/isvv/shared/low_level_utils.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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 _LOW_LEVEL_UTILS_H
+#define _LOW_LEVEL_UTILS_H
+
+#include <bsp/leon3.h>
+#include <grlib/l2cache-regs.h>
+#include <grlib/io.h>
+
+
+// ------------------------------------------------------------------------------------------------
+// Leon3/4 Configuration Registers
+// ------------------------------------------------------------------------------------------------
+
+uint32_t leon3_get_configuration_register( void );
+
+uint32_t leon3_get_psr_register( void );
+
+uint32_t leon3_get_wim_register( void );
+
+uint32_t leon3_get_tbr_register( void );
+
+
+// ------------------------------------------------------------------------------------------------
+// L1 Cache definitions
+// ------------------------------------------------------------------------------------------------
+// L1 Cache Replacement policies
+#define L1_CACHE_REPL_DIRECT_MAPPED (0x00000000U) // 00: no replacement policy (direct-mapped cache)
+#define L1_CACHE_REPL_LRU (0x00000001U) // 01: least recently used (LRU)
+#define L1_CACHE_REPL_LRR (0x00000002U) // 10: least recently replaced (LRR)
+#define L1_CACHE_REPL_RANDOM (0x00000003U) // 11: random
+
+void l1_dcache_flush(void);
+
+void l1_dcache_disable(void);
+
+void l1_dcache_enable(void);
+
+void l1_dcache_set_replacement_policy(uint32_t policy);
+
+
+// ------------------------------------------------------------------------------------------------
+// L2 Cache definitions
+// ------------------------------------------------------------------------------------------------
+// L2 Cache Replacement policies
+#define L2_CACHE_REPL_LRU (0x00000000U) // 00: LRU
+#define L2_CACHE_REPL_PSEUDORANDOM (0x00000001U) // 01: (pseudo-) random
+#define L2_CACHE_REPL_MASTERINDEX_REPLACE (0x00000002U) // 10: Master-index using index-replace field
+#define L2_CACHE_REPL_MASTERINDEX_MODULUS (0x00000003U) // 11: Master-index using the modulus function
+
+void l2_cache_disable(void);
+
+void l2_cache_enable(void);
+
+void l2_cache_flush(void);
+
+void l2_cache_set_replacement_policy(uint32_t policy, uint32_t index_way);
+
+void l2_cache_set_way_lock(uint32_t ways);
+
+void l2_cache_enable_split_responses(void);
+
+void l2_cache_disable_split_responses(void);
+
+size_t l2_cache_get_size(void);
+
+void l2_cache_print_tags(uint32_t n);
+
+
+// ------------------------------------------------------------------------------------------------
+// SOC Statistics definitions
+// ------------------------------------------------------------------------------------------------
+#define L4_STAT_BASE (0xFFA0D000U)
+
+typedef struct soc_stats_regs {
+ uint32_t l1_inst_cache_miss[4];
+ uint32_t l1_data_cache_miss[4];
+ uint32_t l2_cache_hits;
+ uint32_t l2_cache_miss;
+ uint32_t ahb_split_delay;
+
+} soc_stats_regs;
+
+void soc_stats_init(soc_stats_regs *stats);
+
+void soc_stats_configure_regs(void);
+
+void soc_stats_update(soc_stats_regs *stats);
+
+void l4_stats_print(void);
+
+
+// ------------------------------------------------------------------------------------------------
+// Clock Gating Definitions
+// ------------------------------------------------------------------------------------------------
+#define GRCLKGATE_BASE (0xFFA04000U)
+
+void clockgating_enable_l4stat(void);
+
+#endif /* !_LOW_LEVEL_UTILS_H */
+/* end of include file */
diff --git a/testsuites/isvv/shared/trig_tables.h b/testsuites/isvv/shared/trig_tables.h
new file mode 100644
index 0000000000..0a9dfe609c
--- /dev/null
+++ b/testsuites/isvv/shared/trig_tables.h
@@ -0,0 +1,2091 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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 _TRIG_TABLES_H
+#define _TRIG_TABLES_H
+
+#ifndef PI
+#define PI (3.14159265358979323846f)
+#endif
+
+#define FFT_TABLE_SIZE (8192U)
+
+static const float cosTable[FFT_TABLE_SIZE]={
+ 1.00000000, 0.99999970, 0.99999881, 0.99999738, 0.99999529, 0.99999267, 0.99998939, 0.99998558,
+ 0.99998116, 0.99997616, 0.99997061, 0.99996442, 0.99995762, 0.99995029, 0.99994236, 0.99993384,
+ 0.99992472, 0.99991500, 0.99990469, 0.99989384, 0.99988234, 0.99987030, 0.99985766, 0.99984443,
+ 0.99983060, 0.99981618, 0.99980116, 0.99978560, 0.99976939, 0.99975264, 0.99973530, 0.99971735,
+ 0.99969882, 0.99967968, 0.99966002, 0.99963969, 0.99961883, 0.99959737, 0.99957532, 0.99955267,
+ 0.99952942, 0.99950558, 0.99948120, 0.99945617, 0.99943060, 0.99940443, 0.99937767, 0.99935031,
+ 0.99932235, 0.99929386, 0.99926478, 0.99923503, 0.99920475, 0.99917388, 0.99914241, 0.99911034,
+ 0.99907774, 0.99904448, 0.99901068, 0.99897629, 0.99894130, 0.99890572, 0.99886954, 0.99883282,
+ 0.99879545, 0.99875754, 0.99871904, 0.99867994, 0.99864024, 0.99859995, 0.99855906, 0.99851763,
+ 0.99847555, 0.99843293, 0.99838972, 0.99834591, 0.99830157, 0.99825656, 0.99821103, 0.99816483,
+ 0.99811810, 0.99807078, 0.99802285, 0.99797440, 0.99792528, 0.99787563, 0.99782532, 0.99777448,
+ 0.99772304, 0.99767107, 0.99761844, 0.99756521, 0.99751145, 0.99745709, 0.99740213, 0.99734658,
+ 0.99729043, 0.99723375, 0.99717641, 0.99711853, 0.99706006, 0.99700099, 0.99694133, 0.99688113,
+ 0.99682027, 0.99675888, 0.99669689, 0.99663430, 0.99657112, 0.99650741, 0.99644303, 0.99637812,
+ 0.99631262, 0.99624652, 0.99617982, 0.99611259, 0.99604470, 0.99597627, 0.99590725, 0.99583763,
+ 0.99576741, 0.99569660, 0.99562526, 0.99555331, 0.99548078, 0.99540764, 0.99533391, 0.99525958,
+ 0.99518472, 0.99510926, 0.99503320, 0.99495655, 0.99487931, 0.99480152, 0.99472314, 0.99464417,
+ 0.99456459, 0.99448442, 0.99440366, 0.99432236, 0.99424046, 0.99415797, 0.99407488, 0.99399120,
+ 0.99390697, 0.99382216, 0.99373674, 0.99365073, 0.99356413, 0.99347699, 0.99338919, 0.99330086,
+ 0.99321193, 0.99312246, 0.99303234, 0.99294168, 0.99285042, 0.99275857, 0.99266613, 0.99257314,
+ 0.99247956, 0.99238533, 0.99229062, 0.99219525, 0.99209929, 0.99200279, 0.99190569, 0.99180800,
+ 0.99170977, 0.99161088, 0.99151146, 0.99141145, 0.99131083, 0.99120969, 0.99110794, 0.99100554,
+ 0.99090266, 0.99079913, 0.99069500, 0.99059033, 0.99048507, 0.99037921, 0.99027282, 0.99016583,
+ 0.99005818, 0.98995006, 0.98984128, 0.98973197, 0.98962200, 0.98951149, 0.98940045, 0.98928875,
+ 0.98917651, 0.98906368, 0.98895025, 0.98883629, 0.98872167, 0.98860651, 0.98849082, 0.98837447,
+ 0.98825759, 0.98814011, 0.98802203, 0.98790336, 0.98778415, 0.98766434, 0.98754394, 0.98742294,
+ 0.98730141, 0.98717928, 0.98705655, 0.98693329, 0.98680937, 0.98668492, 0.98655993, 0.98643428,
+ 0.98630810, 0.98618132, 0.98605394, 0.98592603, 0.98579752, 0.98566842, 0.98553872, 0.98540848,
+ 0.98527765, 0.98514622, 0.98501426, 0.98488164, 0.98474848, 0.98461479, 0.98448044, 0.98434556,
+ 0.98421007, 0.98407406, 0.98393744, 0.98380023, 0.98366243, 0.98352402, 0.98338509, 0.98324561,
+ 0.98310548, 0.98296481, 0.98282355, 0.98268169, 0.98253930, 0.98239630, 0.98225272, 0.98210859,
+ 0.98196387, 0.98181856, 0.98167270, 0.98152626, 0.98137921, 0.98123157, 0.98108339, 0.98093462,
+ 0.98078525, 0.98063534, 0.98048484, 0.98033381, 0.98018211, 0.98002988, 0.97987711, 0.97972375,
+ 0.97956979, 0.97941524, 0.97926015, 0.97910446, 0.97894818, 0.97879136, 0.97863394, 0.97847593,
+ 0.97831738, 0.97815824, 0.97799850, 0.97783822, 0.97767735, 0.97751594, 0.97735387, 0.97719133,
+ 0.97702813, 0.97686440, 0.97670007, 0.97653520, 0.97636974, 0.97620368, 0.97603709, 0.97586989,
+ 0.97570211, 0.97553378, 0.97536486, 0.97519541, 0.97502536, 0.97485471, 0.97468352, 0.97451174,
+ 0.97433937, 0.97416645, 0.97399294, 0.97381890, 0.97364426, 0.97346902, 0.97329324, 0.97311687,
+ 0.97293997, 0.97276247, 0.97258437, 0.97240573, 0.97222650, 0.97204673, 0.97186631, 0.97168541,
+ 0.97150391, 0.97132182, 0.97113913, 0.97095591, 0.97077215, 0.97058779, 0.97040284, 0.97021735,
+ 0.97003126, 0.96984458, 0.96965736, 0.96946961, 0.96928126, 0.96909231, 0.96890283, 0.96871275,
+ 0.96852207, 0.96833086, 0.96813911, 0.96794677, 0.96775383, 0.96756035, 0.96736628, 0.96717167,
+ 0.96697646, 0.96678072, 0.96658438, 0.96638745, 0.96618998, 0.96599197, 0.96579337, 0.96559417,
+ 0.96539444, 0.96519411, 0.96499324, 0.96479183, 0.96458977, 0.96438724, 0.96418405, 0.96398038,
+ 0.96377605, 0.96357119, 0.96336579, 0.96315980, 0.96295327, 0.96274614, 0.96253848, 0.96233022,
+ 0.96212143, 0.96191204, 0.96170205, 0.96149158, 0.96128047, 0.96106887, 0.96085662, 0.96064389,
+ 0.96043050, 0.96021664, 0.96000212, 0.95978713, 0.95957154, 0.95935535, 0.95913863, 0.95892131,
+ 0.95870346, 0.95848507, 0.95826608, 0.95804650, 0.95782644, 0.95760572, 0.95738453, 0.95716268,
+ 0.95694035, 0.95671743, 0.95649391, 0.95626986, 0.95604527, 0.95582008, 0.95559436, 0.95536804,
+ 0.95514119, 0.95491374, 0.95468575, 0.95445722, 0.95422810, 0.95399845, 0.95376819, 0.95353740,
+ 0.95330602, 0.95307410, 0.95284164, 0.95260859, 0.95237499, 0.95214087, 0.95190614, 0.95167089,
+ 0.95143503, 0.95119864, 0.95096165, 0.95072412, 0.95048606, 0.95024747, 0.95000827, 0.94976848,
+ 0.94952816, 0.94928730, 0.94904590, 0.94880390, 0.94856137, 0.94831824, 0.94807458, 0.94783038,
+ 0.94758558, 0.94734025, 0.94709438, 0.94684792, 0.94660091, 0.94635338, 0.94610524, 0.94585657,
+ 0.94560730, 0.94535756, 0.94510722, 0.94485629, 0.94460481, 0.94435281, 0.94410026, 0.94384712,
+ 0.94359344, 0.94333923, 0.94308442, 0.94282907, 0.94257319, 0.94231677, 0.94205976, 0.94180220,
+ 0.94154406, 0.94128537, 0.94102615, 0.94076639, 0.94050604, 0.94024521, 0.93998373, 0.93972176,
+ 0.93945920, 0.93919611, 0.93893248, 0.93866831, 0.93840355, 0.93813825, 0.93787235, 0.93760598,
+ 0.93733901, 0.93707150, 0.93680346, 0.93653482, 0.93626565, 0.93599594, 0.93572569, 0.93545485,
+ 0.93518353, 0.93491161, 0.93463916, 0.93436611, 0.93409252, 0.93381846, 0.93354380, 0.93326855,
+ 0.93299282, 0.93271649, 0.93243963, 0.93216223, 0.93188429, 0.93160576, 0.93132669, 0.93104708,
+ 0.93076694, 0.93048626, 0.93020505, 0.92992324, 0.92964089, 0.92935801, 0.92907459, 0.92879063,
+ 0.92850608, 0.92822099, 0.92793542, 0.92764926, 0.92736250, 0.92707527, 0.92678750, 0.92649913,
+ 0.92621022, 0.92592078, 0.92563081, 0.92534029, 0.92504925, 0.92475760, 0.92446548, 0.92417276,
+ 0.92387950, 0.92358577, 0.92329144, 0.92299652, 0.92270112, 0.92240518, 0.92210865, 0.92181164,
+ 0.92151403, 0.92121589, 0.92091721, 0.92061806, 0.92031831, 0.92001796, 0.91971713, 0.91941577,
+ 0.91911387, 0.91881138, 0.91850841, 0.91820484, 0.91790080, 0.91759616, 0.91729099, 0.91698527,
+ 0.91667908, 0.91637230, 0.91606498, 0.91575712, 0.91544873, 0.91513979, 0.91483033, 0.91452032,
+ 0.91420978, 0.91389865, 0.91358703, 0.91327488, 0.91296220, 0.91264898, 0.91233516, 0.91202086,
+ 0.91170603, 0.91139066, 0.91107476, 0.91075826, 0.91044128, 0.91012377, 0.90980572, 0.90948713,
+ 0.90916800, 0.90884835, 0.90852809, 0.90820736, 0.90788609, 0.90756434, 0.90724200, 0.90691912,
+ 0.90659571, 0.90627176, 0.90594727, 0.90562230, 0.90529674, 0.90497071, 0.90464407, 0.90431696,
+ 0.90398932, 0.90366107, 0.90333235, 0.90300310, 0.90267330, 0.90234298, 0.90201217, 0.90168077,
+ 0.90134883, 0.90101641, 0.90068340, 0.90034992, 0.90001589, 0.89968133, 0.89934623, 0.89901060,
+ 0.89867449, 0.89833778, 0.89800060, 0.89766282, 0.89732456, 0.89698577, 0.89664650, 0.89630663,
+ 0.89596623, 0.89562535, 0.89528394, 0.89494199, 0.89459950, 0.89425647, 0.89391297, 0.89356887,
+ 0.89322430, 0.89287919, 0.89253354, 0.89218742, 0.89184070, 0.89149350, 0.89114577, 0.89079750,
+ 0.89044875, 0.89009941, 0.88974959, 0.88939923, 0.88904834, 0.88869697, 0.88834506, 0.88799256,
+ 0.88763964, 0.88728613, 0.88693213, 0.88657761, 0.88622254, 0.88586694, 0.88551086, 0.88515425,
+ 0.88479710, 0.88443947, 0.88408124, 0.88372254, 0.88336337, 0.88300359, 0.88264334, 0.88228256,
+ 0.88192129, 0.88155943, 0.88119709, 0.88083428, 0.88047087, 0.88010699, 0.87974262, 0.87937766,
+ 0.87901223, 0.87864625, 0.87827981, 0.87791282, 0.87754530, 0.87717724, 0.87680870, 0.87643969,
+ 0.87607008, 0.87570000, 0.87532938, 0.87495828, 0.87458664, 0.87421453, 0.87384182, 0.87346870,
+ 0.87309498, 0.87272078, 0.87234604, 0.87197083, 0.87159508, 0.87121886, 0.87084204, 0.87046480,
+ 0.87008697, 0.86970866, 0.86932987, 0.86895055, 0.86857069, 0.86819035, 0.86780947, 0.86742812,
+ 0.86704624, 0.86666387, 0.86628097, 0.86589754, 0.86551362, 0.86512917, 0.86474425, 0.86435878,
+ 0.86397284, 0.86358637, 0.86319941, 0.86281192, 0.86242396, 0.86203545, 0.86164647, 0.86125696,
+ 0.86086696, 0.86047643, 0.86008537, 0.85969388, 0.85930181, 0.85890925, 0.85851622, 0.85812265,
+ 0.85772860, 0.85733402, 0.85693896, 0.85654342, 0.85614735, 0.85575074, 0.85535365, 0.85495609,
+ 0.85455799, 0.85415941, 0.85376030, 0.85336071, 0.85296059, 0.85255998, 0.85215890, 0.85175729,
+ 0.85135520, 0.85095257, 0.85054946, 0.85014588, 0.84974176, 0.84933716, 0.84893203, 0.84852648,
+ 0.84812033, 0.84771377, 0.84730661, 0.84689903, 0.84649092, 0.84608233, 0.84567326, 0.84526366,
+ 0.84485358, 0.84444296, 0.84403187, 0.84362030, 0.84320825, 0.84279567, 0.84238261, 0.84196901,
+ 0.84155500, 0.84114045, 0.84072536, 0.84030986, 0.83989382, 0.83947724, 0.83906025, 0.83864272,
+ 0.83822471, 0.83780622, 0.83738720, 0.83696771, 0.83654773, 0.83612728, 0.83570629, 0.83528483,
+ 0.83486289, 0.83444041, 0.83401752, 0.83359408, 0.83317018, 0.83274579, 0.83232087, 0.83189547,
+ 0.83146960, 0.83104324, 0.83061641, 0.83018905, 0.82976121, 0.82933295, 0.82890409, 0.82847482,
+ 0.82804507, 0.82761478, 0.82718402, 0.82675278, 0.82632107, 0.82588887, 0.82545614, 0.82502300,
+ 0.82458931, 0.82415515, 0.82372051, 0.82328540, 0.82284981, 0.82241368, 0.82197714, 0.82154006,
+ 0.82110250, 0.82066447, 0.82022595, 0.81978697, 0.81934750, 0.81890756, 0.81846714, 0.81802619,
+ 0.81758481, 0.81714290, 0.81670058, 0.81625772, 0.81581444, 0.81537062, 0.81492633, 0.81448156,
+ 0.81403631, 0.81359059, 0.81314439, 0.81269777, 0.81225061, 0.81180298, 0.81135488, 0.81090623,
+ 0.81045717, 0.81000763, 0.80955762, 0.80910712, 0.80865616, 0.80820471, 0.80775285, 0.80730045,
+ 0.80684757, 0.80639422, 0.80594039, 0.80548608, 0.80503136, 0.80457610, 0.80412036, 0.80366421,
+ 0.80320752, 0.80275041, 0.80229282, 0.80183470, 0.80137616, 0.80091715, 0.80045766, 0.79999769,
+ 0.79953724, 0.79907638, 0.79861498, 0.79815316, 0.79769087, 0.79722804, 0.79676479, 0.79630107,
+ 0.79583693, 0.79537225, 0.79490715, 0.79444152, 0.79397547, 0.79350895, 0.79304194, 0.79257452,
+ 0.79210657, 0.79163820, 0.79116935, 0.79070002, 0.79023021, 0.78975999, 0.78928924, 0.78881806,
+ 0.78834641, 0.78787434, 0.78740174, 0.78692871, 0.78645521, 0.78598124, 0.78550684, 0.78503191,
+ 0.78455657, 0.78408080, 0.78360450, 0.78312778, 0.78265059, 0.78217292, 0.78169483, 0.78121626,
+ 0.78073722, 0.78025776, 0.77977777, 0.77929735, 0.77881652, 0.77833521, 0.77785343, 0.77737117,
+ 0.77688849, 0.77640533, 0.77592170, 0.77543765, 0.77495313, 0.77446812, 0.77398270, 0.77349681,
+ 0.77301043, 0.77252364, 0.77203637, 0.77154869, 0.77106053, 0.77057189, 0.77008283, 0.76959330,
+ 0.76910335, 0.76861292, 0.76812202, 0.76763070, 0.76713890, 0.76664668, 0.76615399, 0.76566088,
+ 0.76516724, 0.76467323, 0.76417875, 0.76368380, 0.76318842, 0.76269257, 0.76219630, 0.76169956,
+ 0.76120239, 0.76070476, 0.76020670, 0.75970817, 0.75920922, 0.75870979, 0.75820988, 0.75770962,
+ 0.75720882, 0.75670767, 0.75620598, 0.75570393, 0.75520140, 0.75469840, 0.75419497, 0.75369114,
+ 0.75318682, 0.75268203, 0.75217682, 0.75167120, 0.75116515, 0.75065863, 0.75015163, 0.74964422,
+ 0.74913639, 0.74862808, 0.74811935, 0.74761021, 0.74710059, 0.74659055, 0.74608010, 0.74556917,
+ 0.74505776, 0.74454600, 0.74403375, 0.74352109, 0.74300796, 0.74249440, 0.74198043, 0.74146599,
+ 0.74095112, 0.74043584, 0.73992008, 0.73940390, 0.73888731, 0.73837030, 0.73785281, 0.73733491,
+ 0.73681659, 0.73629779, 0.73577857, 0.73525894, 0.73473889, 0.73421836, 0.73369741, 0.73317605,
+ 0.73265427, 0.73213202, 0.73160940, 0.73108631, 0.73056275, 0.73003882, 0.72951442, 0.72898960,
+ 0.72846437, 0.72793871, 0.72741264, 0.72688609, 0.72635913, 0.72583181, 0.72530395, 0.72477573,
+ 0.72424710, 0.72371799, 0.72318846, 0.72265857, 0.72212821, 0.72159743, 0.72106618, 0.72053456,
+ 0.72000253, 0.71947002, 0.71893710, 0.71840382, 0.71787006, 0.71733588, 0.71680129, 0.71626627,
+ 0.71573085, 0.71519494, 0.71465868, 0.71412200, 0.71358484, 0.71304733, 0.71250939, 0.71197098,
+ 0.71143222, 0.71089298, 0.71035337, 0.70981330, 0.70927280, 0.70873195, 0.70819062, 0.70764893,
+ 0.70710677, 0.70656425, 0.70602125, 0.70547789, 0.70493406, 0.70438987, 0.70384526, 0.70330018,
+ 0.70275474, 0.70220888, 0.70166260, 0.70111591, 0.70056880, 0.70002127, 0.69947332, 0.69892502,
+ 0.69837624, 0.69782710, 0.69727749, 0.69672751, 0.69617712, 0.69562632, 0.69507509, 0.69452351,
+ 0.69397146, 0.69341904, 0.69286615, 0.69231290, 0.69175923, 0.69120520, 0.69065070, 0.69009584,
+ 0.68954057, 0.68898487, 0.68842876, 0.68787223, 0.68731534, 0.68675804, 0.68620032, 0.68564218,
+ 0.68508369, 0.68452471, 0.68396538, 0.68340570, 0.68284553, 0.68228501, 0.68172407, 0.68116271,
+ 0.68060100, 0.68003887, 0.67947632, 0.67891335, 0.67835003, 0.67778629, 0.67722219, 0.67665762,
+ 0.67609268, 0.67552739, 0.67496163, 0.67439550, 0.67382902, 0.67326206, 0.67269474, 0.67212707,
+ 0.67155898, 0.67099047, 0.67042154, 0.66985226, 0.66928262, 0.66871250, 0.66814202, 0.66757119,
+ 0.66699994, 0.66642827, 0.66585624, 0.66528380, 0.66471100, 0.66413778, 0.66356415, 0.66299015,
+ 0.66241580, 0.66184098, 0.66126585, 0.66069031, 0.66011435, 0.65953803, 0.65896130, 0.65838420,
+ 0.65780669, 0.65722883, 0.65665054, 0.65607190, 0.65549284, 0.65491343, 0.65433359, 0.65375340,
+ 0.65317285, 0.65259188, 0.65201056, 0.65142882, 0.65084666, 0.65026420, 0.64968133, 0.64909804,
+ 0.64851439, 0.64793038, 0.64734596, 0.64676118, 0.64617604, 0.64559048, 0.64500451, 0.64441824,
+ 0.64383155, 0.64324450, 0.64265704, 0.64206922, 0.64148104, 0.64089245, 0.64030349, 0.63971418,
+ 0.63912445, 0.63853437, 0.63794392, 0.63735306, 0.63676184, 0.63617027, 0.63557833, 0.63498598,
+ 0.63439327, 0.63380021, 0.63320678, 0.63261294, 0.63201874, 0.63142419, 0.63082922, 0.63023394,
+ 0.62963825, 0.62904221, 0.62844574, 0.62784898, 0.62725180, 0.62665427, 0.62605637, 0.62545812,
+ 0.62485951, 0.62426049, 0.62366110, 0.62306136, 0.62246126, 0.62186080, 0.62125999, 0.62065876,
+ 0.62005723, 0.61945528, 0.61885297, 0.61825031, 0.61764729, 0.61704391, 0.61644018, 0.61583608,
+ 0.61523157, 0.61462677, 0.61402154, 0.61341602, 0.61281008, 0.61220378, 0.61159718, 0.61099017,
+ 0.61038280, 0.60977507, 0.60916704, 0.60855860, 0.60794979, 0.60734063, 0.60673112, 0.60612124,
+ 0.60551107, 0.60490048, 0.60428953, 0.60367823, 0.60306662, 0.60245460, 0.60184222, 0.60122955,
+ 0.60061646, 0.60000306, 0.59938931, 0.59877521, 0.59816068, 0.59754586, 0.59693068, 0.59631521,
+ 0.59569931, 0.59508306, 0.59446651, 0.59384960, 0.59323227, 0.59261465, 0.59199667, 0.59137839,
+ 0.59075969, 0.59014070, 0.58952129, 0.58890158, 0.58828157, 0.58766115, 0.58704036, 0.58641928,
+ 0.58579785, 0.58517605, 0.58455396, 0.58393145, 0.58330864, 0.58268547, 0.58206201, 0.58143812,
+ 0.58081394, 0.58018941, 0.57956457, 0.57893932, 0.57831377, 0.57768792, 0.57706165, 0.57643509,
+ 0.57580817, 0.57518095, 0.57455337, 0.57392544, 0.57329714, 0.57266855, 0.57203960, 0.57141036,
+ 0.57078075, 0.57015079, 0.56952053, 0.56888992, 0.56825894, 0.56762767, 0.56699604, 0.56636411,
+ 0.56573182, 0.56509918, 0.56446624, 0.56383294, 0.56319934, 0.56256539, 0.56193113, 0.56129652,
+ 0.56066155, 0.56002629, 0.55939072, 0.55875480, 0.55811852, 0.55748194, 0.55684501, 0.55620778,
+ 0.55557024, 0.55493236, 0.55429411, 0.55365556, 0.55301672, 0.55237752, 0.55173796, 0.55109817,
+ 0.55045795, 0.54981750, 0.54917663, 0.54853553, 0.54789406, 0.54725230, 0.54661018, 0.54596776,
+ 0.54532498, 0.54468191, 0.54403853, 0.54339480, 0.54275078, 0.54210645, 0.54146177, 0.54081678,
+ 0.54017144, 0.53952587, 0.53887993, 0.53823364, 0.53758705, 0.53694016, 0.53629297, 0.53564548,
+ 0.53499764, 0.53434944, 0.53370100, 0.53305221, 0.53240311, 0.53175372, 0.53110403, 0.53045398,
+ 0.52980363, 0.52915299, 0.52850199, 0.52785075, 0.52719915, 0.52654725, 0.52589500, 0.52524251,
+ 0.52458966, 0.52393657, 0.52328312, 0.52262938, 0.52197528, 0.52132094, 0.52066624, 0.52001125,
+ 0.51935601, 0.51870042, 0.51804453, 0.51738828, 0.51673180, 0.51607502, 0.51541787, 0.51476043,
+ 0.51410276, 0.51344472, 0.51278639, 0.51212776, 0.51146883, 0.51080960, 0.51015007, 0.50949025,
+ 0.50883013, 0.50816971, 0.50750899, 0.50684798, 0.50618666, 0.50552505, 0.50486308, 0.50420088,
+ 0.50353837, 0.50287557, 0.50221246, 0.50154907, 0.50088537, 0.50022137, 0.49955711, 0.49889255,
+ 0.49822766, 0.49756250, 0.49689704, 0.49623129, 0.49556527, 0.49489895, 0.49423230, 0.49356541,
+ 0.49289820, 0.49223071, 0.49156290, 0.49089485, 0.49022648, 0.48955783, 0.48888889, 0.48821968,
+ 0.48755017, 0.48688036, 0.48621029, 0.48553991, 0.48486924, 0.48419830, 0.48352706, 0.48285556,
+ 0.48218378, 0.48151168, 0.48083934, 0.48016667, 0.47949377, 0.47882056, 0.47814706, 0.47747329,
+ 0.47679922, 0.47612488, 0.47545028, 0.47477537, 0.47410020, 0.47342476, 0.47274902, 0.47207302,
+ 0.47139674, 0.47072017, 0.47004333, 0.46936622, 0.46868882, 0.46801114, 0.46733320, 0.46665499,
+ 0.46597651, 0.46529773, 0.46461868, 0.46393937, 0.46325979, 0.46257994, 0.46189979, 0.46121940,
+ 0.46053872, 0.45985776, 0.45917654, 0.45849505, 0.45781329, 0.45713127, 0.45644897, 0.45576641,
+ 0.45508358, 0.45440048, 0.45371711, 0.45303348, 0.45234957, 0.45166543, 0.45098099, 0.45029628,
+ 0.44961134, 0.44892609, 0.44824061, 0.44755486, 0.44686884, 0.44618255, 0.44549602, 0.44480920,
+ 0.44412214, 0.44343480, 0.44274724, 0.44205937, 0.44137126, 0.44068289, 0.43999428, 0.43930539,
+ 0.43861625, 0.43792683, 0.43723717, 0.43654725, 0.43585709, 0.43516666, 0.43447596, 0.43378502,
+ 0.43309382, 0.43240237, 0.43171066, 0.43101871, 0.43032649, 0.42963400, 0.42894128, 0.42824832,
+ 0.42755508, 0.42686161, 0.42616788, 0.42547390, 0.42477968, 0.42408520, 0.42339048, 0.42269549,
+ 0.42200026, 0.42130479, 0.42060909, 0.41991311, 0.41921690, 0.41852042, 0.41782370, 0.41712677,
+ 0.41642955, 0.41573212, 0.41503441, 0.41433650, 0.41363832, 0.41293988, 0.41224122, 0.41154233,
+ 0.41084316, 0.41014379, 0.40944415, 0.40874428, 0.40804416, 0.40734380, 0.40664321, 0.40594238,
+ 0.40524131, 0.40454000, 0.40383846, 0.40313667, 0.40243465, 0.40173239, 0.40102988, 0.40032718,
+ 0.39962420, 0.39892101, 0.39821756, 0.39751390, 0.39681000, 0.39610586, 0.39540148, 0.39469686,
+ 0.39399204, 0.39328697, 0.39258167, 0.39187613, 0.39117038, 0.39046440, 0.38975817, 0.38905174,
+ 0.38834503, 0.38763815, 0.38693100, 0.38622364, 0.38551605, 0.38480824, 0.38410020, 0.38339192,
+ 0.38268343, 0.38197473, 0.38126576, 0.38055661, 0.37984720, 0.37913761, 0.37842774, 0.37771770,
+ 0.37700742, 0.37629691, 0.37558618, 0.37487522, 0.37416407, 0.37345266, 0.37274107, 0.37202924,
+ 0.37131721, 0.37060493, 0.36989245, 0.36917976, 0.36846682, 0.36775368, 0.36704034, 0.36632678,
+ 0.36561298, 0.36489901, 0.36418480, 0.36347038, 0.36275572, 0.36204088, 0.36132580, 0.36061051,
+ 0.35989505, 0.35917935, 0.35846341, 0.35774729, 0.35703096, 0.35631442, 0.35559767, 0.35488069,
+ 0.35416353, 0.35344616, 0.35272855, 0.35201076, 0.35129276, 0.35057455, 0.34985614, 0.34913751,
+ 0.34841868, 0.34769964, 0.34698042, 0.34626096, 0.34554133, 0.34482148, 0.34410143, 0.34338117,
+ 0.34266073, 0.34194008, 0.34121922, 0.34049815, 0.33977687, 0.33905542, 0.33833376, 0.33761191,
+ 0.33688986, 0.33616760, 0.33544514, 0.33472249, 0.33399966, 0.33327660, 0.33255336, 0.33182994,
+ 0.33110631, 0.33038250, 0.32965845, 0.32893425, 0.32820985, 0.32748523, 0.32676044, 0.32603547,
+ 0.32531029, 0.32458493, 0.32385936, 0.32313362, 0.32240769, 0.32168156, 0.32095525, 0.32022873,
+ 0.31950203, 0.31877515, 0.31804809, 0.31732082, 0.31659338, 0.31586576, 0.31513792, 0.31440994,
+ 0.31368175, 0.31295338, 0.31222481, 0.31149608, 0.31076714, 0.31003806, 0.30930877, 0.30857930,
+ 0.30784965, 0.30711982, 0.30638981, 0.30565959, 0.30492923, 0.30419868, 0.30346796, 0.30273703,
+ 0.30200595, 0.30127469, 0.30054325, 0.29981163, 0.29907984, 0.29834786, 0.29761571, 0.29688337,
+ 0.29615089, 0.29541820, 0.29468536, 0.29395235, 0.29321915, 0.29248580, 0.29175225, 0.29101855,
+ 0.29028466, 0.28955063, 0.28881642, 0.28808203, 0.28734747, 0.28661272, 0.28587782, 0.28514278,
+ 0.28440753, 0.28367212, 0.28293657, 0.28220084, 0.28146493, 0.28072888, 0.27999264, 0.27925625,
+ 0.27851969, 0.27778298, 0.27704608, 0.27630904, 0.27557182, 0.27483445, 0.27409691, 0.27335921,
+ 0.27262136, 0.27188334, 0.27114516, 0.27040681, 0.26966831, 0.26892966, 0.26819086, 0.26745188,
+ 0.26671275, 0.26597348, 0.26523402, 0.26449442, 0.26375467, 0.26301476, 0.26227471, 0.26153448,
+ 0.26079410, 0.26005360, 0.25931293, 0.25857207, 0.25783110, 0.25708997, 0.25634867, 0.25560725,
+ 0.25486565, 0.25412393, 0.25338203, 0.25264001, 0.25189781, 0.25115550, 0.25041300, 0.24967039,
+ 0.24892761, 0.24818468, 0.24744162, 0.24669841, 0.24595505, 0.24521154, 0.24446790, 0.24372411,
+ 0.24298018, 0.24223611, 0.24149188, 0.24074753, 0.24000302, 0.23925838, 0.23851359, 0.23776866,
+ 0.23702361, 0.23627840, 0.23553306, 0.23478758, 0.23404196, 0.23329620, 0.23255031, 0.23180428,
+ 0.23105811, 0.23031181, 0.22956537, 0.22881879, 0.22807208, 0.22732525, 0.22657827, 0.22583115,
+ 0.22508392, 0.22433653, 0.22358903, 0.22284140, 0.22209363, 0.22134572, 0.22059768, 0.21984953,
+ 0.21910124, 0.21835282, 0.21760428, 0.21685560, 0.21610680, 0.21535787, 0.21460882, 0.21385963,
+ 0.21311031, 0.21236089, 0.21161133, 0.21086164, 0.21011184, 0.20936191, 0.20861185, 0.20786168,
+ 0.20711137, 0.20636095, 0.20561041, 0.20485975, 0.20410897, 0.20335807, 0.20260704, 0.20185590,
+ 0.20110464, 0.20035325, 0.19960175, 0.19885014, 0.19809841, 0.19734657, 0.19659460, 0.19584252,
+ 0.19509032, 0.19433801, 0.19358559, 0.19283305, 0.19208039, 0.19132763, 0.19057475, 0.18982176,
+ 0.18906866, 0.18831545, 0.18756212, 0.18680869, 0.18605515, 0.18530150, 0.18454774, 0.18379387,
+ 0.18303989, 0.18228580, 0.18153161, 0.18077731, 0.18002290, 0.17926839, 0.17851377, 0.17775905,
+ 0.17700422, 0.17624930, 0.17549425, 0.17473911, 0.17398387, 0.17322853, 0.17247309, 0.17171754,
+ 0.17096189, 0.17020614, 0.16945030, 0.16869435, 0.16793829, 0.16718215, 0.16642590, 0.16566956,
+ 0.16491312, 0.16415659, 0.16339995, 0.16264322, 0.16188639, 0.16112947, 0.16037245, 0.15961535,
+ 0.15885815, 0.15810084, 0.15734346, 0.15658598, 0.15582840, 0.15507074, 0.15431297, 0.15355512,
+ 0.15279719, 0.15203916, 0.15128104, 0.15052283, 0.14976454, 0.14900614, 0.14824767, 0.14748912,
+ 0.14673047, 0.14597175, 0.14521292, 0.14445402, 0.14369503, 0.14293596, 0.14217681, 0.14141756,
+ 0.14065824, 0.13989884, 0.13913934, 0.13837977, 0.13762012, 0.13686039, 0.13610058, 0.13534068,
+ 0.13458070, 0.13382065, 0.13306053, 0.13230032, 0.13154003, 0.13077967, 0.13001922, 0.12925871,
+ 0.12849811, 0.12773745, 0.12697670, 0.12621588, 0.12545498, 0.12469402, 0.12393297, 0.12317186,
+ 0.12241068, 0.12164941, 0.12088808, 0.12012669, 0.11936522, 0.11860368, 0.11784206, 0.11708038,
+ 0.11631863, 0.11555681, 0.11479492, 0.11403298, 0.11327095, 0.11250886, 0.11174671, 0.11098449,
+ 0.11022221, 0.10945985, 0.10869744, 0.10793497, 0.10717242, 0.10640982, 0.10564715, 0.10488442,
+ 0.10412163, 0.10335878, 0.10259587, 0.10183290, 0.10106986, 0.10030677, 0.09954362, 0.09878041,
+ 0.09801714, 0.09725381, 0.09649043, 0.09572699, 0.09496350, 0.09419994, 0.09343634, 0.09267268,
+ 0.09190895, 0.09114519, 0.09038136, 0.08961748, 0.08885355, 0.08808957, 0.08732554, 0.08656145,
+ 0.08579731, 0.08503313, 0.08426889, 0.08350460, 0.08274026, 0.08197588, 0.08121145, 0.08044697,
+ 0.07968244, 0.07891786, 0.07815325, 0.07738858, 0.07662386, 0.07585911, 0.07509430, 0.07432945,
+ 0.07356457, 0.07279963, 0.07203465, 0.07126963, 0.07050458, 0.06973947, 0.06897433, 0.06820914,
+ 0.06744392, 0.06667866, 0.06591335, 0.06514801, 0.06438263, 0.06361721, 0.06285176, 0.06208627,
+ 0.06132074, 0.06055517, 0.05978957, 0.05902394, 0.05825827, 0.05749256, 0.05672682, 0.05596105,
+ 0.05519525, 0.05442941, 0.05366354, 0.05289764, 0.05213170, 0.05136574, 0.05059975, 0.04983373,
+ 0.04906768, 0.04830159, 0.04753548, 0.04676935, 0.04600318, 0.04523699, 0.04447077, 0.04370453,
+ 0.04293826, 0.04217196, 0.04140564, 0.04063930, 0.03987293, 0.03910654, 0.03834012, 0.03757368,
+ 0.03680722, 0.03604074, 0.03527424, 0.03450771, 0.03374117, 0.03297461, 0.03220803, 0.03144142,
+ 0.03067480, 0.02990817, 0.02914151, 0.02837484, 0.02760815, 0.02684144, 0.02607472, 0.02530798,
+ 0.02454123, 0.02377446, 0.02300768, 0.02224089, 0.02147408, 0.02070726, 0.01994043, 0.01917358,
+ 0.01840673, 0.01763986, 0.01687299, 0.01610610, 0.01533921, 0.01457230, 0.01380539, 0.01303847,
+ 0.01227154, 0.01150460, 0.01073766, 0.00997071, 0.00920375, 0.00843679, 0.00766983, 0.00690286,
+ 0.00613588, 0.00536891, 0.00460193, 0.00383494, 0.00306796, 0.00230097, 0.00153398, 0.00076699,
+ 0.00000000, -0.00076699, -0.00153398, -0.00230097, -0.00306796, -0.00383494, -0.00460193, -0.00536891,
+ -0.00613588, -0.00690286, -0.00766983, -0.00843679, -0.00920375, -0.00997071, -0.01073766, -0.01150460,
+ -0.01227154, -0.01303847, -0.01380539, -0.01457230, -0.01533921, -0.01610610, -0.01687299, -0.01763986,
+ -0.01840673, -0.01917358, -0.01994043, -0.02070726, -0.02147408, -0.02224089, -0.02300768, -0.02377446,
+ -0.02454123, -0.02530798, -0.02607472, -0.02684144, -0.02760815, -0.02837484, -0.02914151, -0.02990817,
+ -0.03067480, -0.03144142, -0.03220803, -0.03297461, -0.03374117, -0.03450771, -0.03527424, -0.03604074,
+ -0.03680722, -0.03757368, -0.03834012, -0.03910654, -0.03987293, -0.04063930, -0.04140564, -0.04217196,
+ -0.04293826, -0.04370453, -0.04447077, -0.04523699, -0.04600318, -0.04676935, -0.04753548, -0.04830159,
+ -0.04906768, -0.04983373, -0.05059975, -0.05136574, -0.05213170, -0.05289764, -0.05366354, -0.05442941,
+ -0.05519525, -0.05596105, -0.05672682, -0.05749256, -0.05825827, -0.05902394, -0.05978957, -0.06055517,
+ -0.06132074, -0.06208627, -0.06285176, -0.06361721, -0.06438263, -0.06514801, -0.06591335, -0.06667866,
+ -0.06744392, -0.06820914, -0.06897433, -0.06973947, -0.07050458, -0.07126963, -0.07203465, -0.07279963,
+ -0.07356457, -0.07432945, -0.07509430, -0.07585911, -0.07662386, -0.07738858, -0.07815325, -0.07891786,
+ -0.07968244, -0.08044697, -0.08121145, -0.08197588, -0.08274026, -0.08350460, -0.08426889, -0.08503313,
+ -0.08579731, -0.08656145, -0.08732554, -0.08808957, -0.08885355, -0.08961748, -0.09038136, -0.09114519,
+ -0.09190895, -0.09267268, -0.09343634, -0.09419994, -0.09496350, -0.09572699, -0.09649043, -0.09725381,
+ -0.09801714, -0.09878041, -0.09954362, -0.10030677, -0.10106986, -0.10183290, -0.10259587, -0.10335878,
+ -0.10412163, -0.10488442, -0.10564715, -0.10640982, -0.10717242, -0.10793497, -0.10869744, -0.10945985,
+ -0.11022221, -0.11098449, -0.11174671, -0.11250886, -0.11327095, -0.11403298, -0.11479492, -0.11555681,
+ -0.11631863, -0.11708038, -0.11784206, -0.11860368, -0.11936522, -0.12012669, -0.12088808, -0.12164941,
+ -0.12241068, -0.12317186, -0.12393297, -0.12469402, -0.12545498, -0.12621588, -0.12697670, -0.12773745,
+ -0.12849811, -0.12925871, -0.13001922, -0.13077967, -0.13154003, -0.13230032, -0.13306053, -0.13382065,
+ -0.13458070, -0.13534068, -0.13610058, -0.13686039, -0.13762012, -0.13837977, -0.13913934, -0.13989884,
+ -0.14065824, -0.14141756, -0.14217681, -0.14293596, -0.14369503, -0.14445402, -0.14521292, -0.14597175,
+ -0.14673047, -0.14748912, -0.14824767, -0.14900614, -0.14976454, -0.15052283, -0.15128104, -0.15203916,
+ -0.15279719, -0.15355512, -0.15431297, -0.15507074, -0.15582840, -0.15658598, -0.15734346, -0.15810084,
+ -0.15885815, -0.15961535, -0.16037245, -0.16112947, -0.16188639, -0.16264322, -0.16339995, -0.16415659,
+ -0.16491312, -0.16566956, -0.16642590, -0.16718215, -0.16793829, -0.16869435, -0.16945030, -0.17020614,
+ -0.17096189, -0.17171754, -0.17247309, -0.17322853, -0.17398387, -0.17473911, -0.17549425, -0.17624930,
+ -0.17700422, -0.17775905, -0.17851377, -0.17926839, -0.18002290, -0.18077731, -0.18153161, -0.18228580,
+ -0.18303989, -0.18379387, -0.18454774, -0.18530150, -0.18605515, -0.18680869, -0.18756212, -0.18831545,
+ -0.18906866, -0.18982176, -0.19057475, -0.19132763, -0.19208039, -0.19283305, -0.19358559, -0.19433801,
+ -0.19509032, -0.19584252, -0.19659460, -0.19734657, -0.19809841, -0.19885014, -0.19960175, -0.20035325,
+ -0.20110464, -0.20185590, -0.20260704, -0.20335807, -0.20410897, -0.20485975, -0.20561041, -0.20636095,
+ -0.20711137, -0.20786168, -0.20861185, -0.20936191, -0.21011184, -0.21086164, -0.21161133, -0.21236089,
+ -0.21311031, -0.21385963, -0.21460882, -0.21535787, -0.21610680, -0.21685560, -0.21760428, -0.21835282,
+ -0.21910124, -0.21984953, -0.22059768, -0.22134572, -0.22209363, -0.22284140, -0.22358903, -0.22433653,
+ -0.22508392, -0.22583115, -0.22657827, -0.22732525, -0.22807208, -0.22881879, -0.22956537, -0.23031181,
+ -0.23105811, -0.23180428, -0.23255031, -0.23329620, -0.23404196, -0.23478758, -0.23553306, -0.23627840,
+ -0.23702361, -0.23776866, -0.23851359, -0.23925838, -0.24000302, -0.24074753, -0.24149188, -0.24223611,
+ -0.24298018, -0.24372411, -0.24446790, -0.24521154, -0.24595505, -0.24669841, -0.24744162, -0.24818468,
+ -0.24892761, -0.24967039, -0.25041300, -0.25115550, -0.25189781, -0.25264001, -0.25338203, -0.25412393,
+ -0.25486565, -0.25560725, -0.25634867, -0.25708997, -0.25783110, -0.25857207, -0.25931293, -0.26005360,
+ -0.26079410, -0.26153448, -0.26227471, -0.26301476, -0.26375467, -0.26449442, -0.26523402, -0.26597348,
+ -0.26671275, -0.26745188, -0.26819086, -0.26892966, -0.26966831, -0.27040681, -0.27114516, -0.27188334,
+ -0.27262136, -0.27335921, -0.27409691, -0.27483445, -0.27557182, -0.27630904, -0.27704608, -0.27778298,
+ -0.27851969, -0.27925625, -0.27999264, -0.28072888, -0.28146493, -0.28220084, -0.28293657, -0.28367212,
+ -0.28440753, -0.28514278, -0.28587782, -0.28661272, -0.28734747, -0.28808203, -0.28881642, -0.28955063,
+ -0.29028466, -0.29101855, -0.29175225, -0.29248580, -0.29321915, -0.29395235, -0.29468536, -0.29541820,
+ -0.29615089, -0.29688337, -0.29761571, -0.29834786, -0.29907984, -0.29981163, -0.30054325, -0.30127469,
+ -0.30200595, -0.30273703, -0.30346796, -0.30419868, -0.30492923, -0.30565959, -0.30638981, -0.30711982,
+ -0.30784965, -0.30857930, -0.30930877, -0.31003806, -0.31076714, -0.31149608, -0.31222481, -0.31295338,
+ -0.31368175, -0.31440994, -0.31513792, -0.31586576, -0.31659338, -0.31732082, -0.31804809, -0.31877515,
+ -0.31950203, -0.32022873, -0.32095525, -0.32168156, -0.32240769, -0.32313362, -0.32385936, -0.32458493,
+ -0.32531029, -0.32603547, -0.32676044, -0.32748523, -0.32820985, -0.32893425, -0.32965845, -0.33038250,
+ -0.33110631, -0.33182994, -0.33255336, -0.33327660, -0.33399966, -0.33472249, -0.33544514, -0.33616760,
+ -0.33688986, -0.33761191, -0.33833376, -0.33905542, -0.33977687, -0.34049815, -0.34121922, -0.34194008,
+ -0.34266073, -0.34338117, -0.34410143, -0.34482148, -0.34554133, -0.34626096, -0.34698042, -0.34769964,
+ -0.34841868, -0.34913751, -0.34985614, -0.35057455, -0.35129276, -0.35201076, -0.35272855, -0.35344616,
+ -0.35416353, -0.35488069, -0.35559767, -0.35631442, -0.35703096, -0.35774729, -0.35846341, -0.35917935,
+ -0.35989505, -0.36061051, -0.36132580, -0.36204088, -0.36275572, -0.36347038, -0.36418480, -0.36489901,
+ -0.36561298, -0.36632678, -0.36704034, -0.36775368, -0.36846682, -0.36917976, -0.36989245, -0.37060493,
+ -0.37131721, -0.37202924, -0.37274107, -0.37345266, -0.37416407, -0.37487522, -0.37558618, -0.37629691,
+ -0.37700742, -0.37771770, -0.37842774, -0.37913761, -0.37984720, -0.38055661, -0.38126576, -0.38197473,
+ -0.38268343, -0.38339192, -0.38410020, -0.38480824, -0.38551605, -0.38622364, -0.38693100, -0.38763815,
+ -0.38834503, -0.38905174, -0.38975817, -0.39046440, -0.39117038, -0.39187613, -0.39258167, -0.39328697,
+ -0.39399204, -0.39469686, -0.39540148, -0.39610586, -0.39681000, -0.39751390, -0.39821756, -0.39892101,
+ -0.39962420, -0.40032718, -0.40102988, -0.40173239, -0.40243465, -0.40313667, -0.40383846, -0.40454000,
+ -0.40524131, -0.40594238, -0.40664321, -0.40734380, -0.40804416, -0.40874428, -0.40944415, -0.41014379,
+ -0.41084316, -0.41154233, -0.41224122, -0.41293988, -0.41363832, -0.41433650, -0.41503441, -0.41573212,
+ -0.41642955, -0.41712677, -0.41782370, -0.41852042, -0.41921690, -0.41991311, -0.42060909, -0.42130479,
+ -0.42200026, -0.42269549, -0.42339048, -0.42408520, -0.42477968, -0.42547390, -0.42616788, -0.42686161,
+ -0.42755508, -0.42824832, -0.42894128, -0.42963400, -0.43032649, -0.43101871, -0.43171066, -0.43240237,
+ -0.43309382, -0.43378502, -0.43447596, -0.43516666, -0.43585709, -0.43654725, -0.43723717, -0.43792683,
+ -0.43861625, -0.43930539, -0.43999428, -0.44068289, -0.44137126, -0.44205937, -0.44274724, -0.44343480,
+ -0.44412214, -0.44480920, -0.44549602, -0.44618255, -0.44686884, -0.44755486, -0.44824061, -0.44892609,
+ -0.44961134, -0.45029628, -0.45098099, -0.45166543, -0.45234957, -0.45303348, -0.45371711, -0.45440048,
+ -0.45508358, -0.45576641, -0.45644897, -0.45713127, -0.45781329, -0.45849505, -0.45917654, -0.45985776,
+ -0.46053872, -0.46121940, -0.46189979, -0.46257994, -0.46325979, -0.46393937, -0.46461868, -0.46529773,
+ -0.46597651, -0.46665499, -0.46733320, -0.46801114, -0.46868882, -0.46936622, -0.47004333, -0.47072017,
+ -0.47139674, -0.47207302, -0.47274902, -0.47342476, -0.47410020, -0.47477537, -0.47545028, -0.47612488,
+ -0.47679922, -0.47747329, -0.47814706, -0.47882056, -0.47949377, -0.48016667, -0.48083934, -0.48151168,
+ -0.48218378, -0.48285556, -0.48352706, -0.48419830, -0.48486924, -0.48553991, -0.48621029, -0.48688036,
+ -0.48755017, -0.48821968, -0.48888889, -0.48955783, -0.49022648, -0.49089485, -0.49156290, -0.49223071,
+ -0.49289820, -0.49356541, -0.49423230, -0.49489895, -0.49556527, -0.49623129, -0.49689704, -0.49756250,
+ -0.49822766, -0.49889255, -0.49955711, -0.50022137, -0.50088537, -0.50154907, -0.50221246, -0.50287557,
+ -0.50353837, -0.50420088, -0.50486308, -0.50552505, -0.50618666, -0.50684798, -0.50750899, -0.50816971,
+ -0.50883013, -0.50949025, -0.51015007, -0.51080960, -0.51146883, -0.51212776, -0.51278639, -0.51344472,
+ -0.51410276, -0.51476043, -0.51541787, -0.51607502, -0.51673180, -0.51738828, -0.51804453, -0.51870042,
+ -0.51935601, -0.52001125, -0.52066624, -0.52132094, -0.52197528, -0.52262938, -0.52328312, -0.52393657,
+ -0.52458966, -0.52524251, -0.52589500, -0.52654725, -0.52719915, -0.52785075, -0.52850199, -0.52915299,
+ -0.52980363, -0.53045398, -0.53110403, -0.53175372, -0.53240311, -0.53305221, -0.53370100, -0.53434944,
+ -0.53499764, -0.53564548, -0.53629297, -0.53694016, -0.53758705, -0.53823364, -0.53887993, -0.53952587,
+ -0.54017144, -0.54081678, -0.54146177, -0.54210645, -0.54275078, -0.54339480, -0.54403853, -0.54468191,
+ -0.54532498, -0.54596776, -0.54661018, -0.54725230, -0.54789406, -0.54853553, -0.54917663, -0.54981750,
+ -0.55045795, -0.55109817, -0.55173796, -0.55237752, -0.55301672, -0.55365556, -0.55429411, -0.55493236,
+ -0.55557024, -0.55620778, -0.55684501, -0.55748194, -0.55811852, -0.55875480, -0.55939072, -0.56002629,
+ -0.56066155, -0.56129652, -0.56193113, -0.56256539, -0.56319934, -0.56383294, -0.56446624, -0.56509918,
+ -0.56573182, -0.56636411, -0.56699604, -0.56762767, -0.56825894, -0.56888992, -0.56952053, -0.57015079,
+ -0.57078075, -0.57141036, -0.57203960, -0.57266855, -0.57329714, -0.57392544, -0.57455337, -0.57518095,
+ -0.57580817, -0.57643509, -0.57706165, -0.57768792, -0.57831377, -0.57893932, -0.57956457, -0.58018941,
+ -0.58081394, -0.58143812, -0.58206201, -0.58268547, -0.58330864, -0.58393145, -0.58455396, -0.58517605,
+ -0.58579785, -0.58641928, -0.58704036, -0.58766115, -0.58828157, -0.58890158, -0.58952129, -0.59014070,
+ -0.59075969, -0.59137839, -0.59199667, -0.59261465, -0.59323227, -0.59384960, -0.59446651, -0.59508306,
+ -0.59569931, -0.59631521, -0.59693068, -0.59754586, -0.59816068, -0.59877521, -0.59938931, -0.60000306,
+ -0.60061646, -0.60122955, -0.60184222, -0.60245460, -0.60306662, -0.60367823, -0.60428953, -0.60490048,
+ -0.60551107, -0.60612124, -0.60673112, -0.60734063, -0.60794979, -0.60855860, -0.60916704, -0.60977507,
+ -0.61038280, -0.61099017, -0.61159718, -0.61220378, -0.61281008, -0.61341602, -0.61402154, -0.61462677,
+ -0.61523157, -0.61583608, -0.61644018, -0.61704391, -0.61764729, -0.61825031, -0.61885297, -0.61945528,
+ -0.62005723, -0.62065876, -0.62125999, -0.62186080, -0.62246126, -0.62306136, -0.62366110, -0.62426049,
+ -0.62485951, -0.62545812, -0.62605637, -0.62665427, -0.62725180, -0.62784898, -0.62844574, -0.62904221,
+ -0.62963825, -0.63023394, -0.63082922, -0.63142419, -0.63201874, -0.63261294, -0.63320678, -0.63380021,
+ -0.63439327, -0.63498598, -0.63557833, -0.63617027, -0.63676184, -0.63735306, -0.63794392, -0.63853437,
+ -0.63912445, -0.63971418, -0.64030349, -0.64089245, -0.64148104, -0.64206922, -0.64265704, -0.64324450,
+ -0.64383155, -0.64441824, -0.64500451, -0.64559048, -0.64617604, -0.64676118, -0.64734596, -0.64793038,
+ -0.64851439, -0.64909804, -0.64968133, -0.65026420, -0.65084666, -0.65142882, -0.65201056, -0.65259188,
+ -0.65317285, -0.65375340, -0.65433359, -0.65491343, -0.65549284, -0.65607190, -0.65665054, -0.65722883,
+ -0.65780669, -0.65838420, -0.65896130, -0.65953803, -0.66011435, -0.66069031, -0.66126585, -0.66184098,
+ -0.66241580, -0.66299015, -0.66356415, -0.66413778, -0.66471100, -0.66528380, -0.66585624, -0.66642827,
+ -0.66699994, -0.66757119, -0.66814202, -0.66871250, -0.66928262, -0.66985226, -0.67042154, -0.67099047,
+ -0.67155898, -0.67212707, -0.67269474, -0.67326206, -0.67382902, -0.67439550, -0.67496163, -0.67552739,
+ -0.67609268, -0.67665762, -0.67722219, -0.67778629, -0.67835003, -0.67891335, -0.67947632, -0.68003887,
+ -0.68060100, -0.68116271, -0.68172407, -0.68228501, -0.68284553, -0.68340570, -0.68396538, -0.68452471,
+ -0.68508369, -0.68564218, -0.68620032, -0.68675804, -0.68731534, -0.68787223, -0.68842876, -0.68898487,
+ -0.68954057, -0.69009584, -0.69065070, -0.69120520, -0.69175923, -0.69231290, -0.69286615, -0.69341904,
+ -0.69397146, -0.69452351, -0.69507509, -0.69562632, -0.69617712, -0.69672751, -0.69727749, -0.69782710,
+ -0.69837624, -0.69892502, -0.69947332, -0.70002127, -0.70056880, -0.70111591, -0.70166260, -0.70220888,
+ -0.70275474, -0.70330018, -0.70384526, -0.70438987, -0.70493406, -0.70547789, -0.70602125, -0.70656425,
+ -0.70710677, -0.70764893, -0.70819062, -0.70873195, -0.70927280, -0.70981330, -0.71035337, -0.71089298,
+ -0.71143222, -0.71197098, -0.71250939, -0.71304733, -0.71358484, -0.71412200, -0.71465868, -0.71519494,
+ -0.71573085, -0.71626627, -0.71680129, -0.71733588, -0.71787006, -0.71840382, -0.71893710, -0.71947002,
+ -0.72000253, -0.72053456, -0.72106618, -0.72159743, -0.72212821, -0.72265857, -0.72318846, -0.72371799,
+ -0.72424710, -0.72477573, -0.72530395, -0.72583181, -0.72635913, -0.72688609, -0.72741264, -0.72793871,
+ -0.72846437, -0.72898960, -0.72951442, -0.73003882, -0.73056275, -0.73108631, -0.73160940, -0.73213202,
+ -0.73265427, -0.73317605, -0.73369741, -0.73421836, -0.73473889, -0.73525894, -0.73577857, -0.73629779,
+ -0.73681659, -0.73733491, -0.73785281, -0.73837030, -0.73888731, -0.73940390, -0.73992008, -0.74043584,
+ -0.74095112, -0.74146599, -0.74198043, -0.74249440, -0.74300796, -0.74352109, -0.74403375, -0.74454600,
+ -0.74505776, -0.74556917, -0.74608010, -0.74659055, -0.74710059, -0.74761021, -0.74811935, -0.74862808,
+ -0.74913639, -0.74964422, -0.75015163, -0.75065863, -0.75116515, -0.75167120, -0.75217682, -0.75268203,
+ -0.75318682, -0.75369114, -0.75419497, -0.75469840, -0.75520140, -0.75570393, -0.75620598, -0.75670767,
+ -0.75720882, -0.75770962, -0.75820988, -0.75870979, -0.75920922, -0.75970817, -0.76020670, -0.76070476,
+ -0.76120239, -0.76169956, -0.76219630, -0.76269257, -0.76318842, -0.76368380, -0.76417875, -0.76467323,
+ -0.76516724, -0.76566088, -0.76615399, -0.76664668, -0.76713890, -0.76763070, -0.76812202, -0.76861292,
+ -0.76910335, -0.76959330, -0.77008283, -0.77057189, -0.77106053, -0.77154869, -0.77203637, -0.77252364,
+ -0.77301043, -0.77349681, -0.77398270, -0.77446812, -0.77495313, -0.77543765, -0.77592170, -0.77640533,
+ -0.77688849, -0.77737117, -0.77785343, -0.77833521, -0.77881652, -0.77929735, -0.77977777, -0.78025776,
+ -0.78073722, -0.78121626, -0.78169483, -0.78217292, -0.78265059, -0.78312778, -0.78360450, -0.78408080,
+ -0.78455657, -0.78503191, -0.78550684, -0.78598124, -0.78645521, -0.78692871, -0.78740174, -0.78787434,
+ -0.78834641, -0.78881806, -0.78928924, -0.78975999, -0.79023021, -0.79070002, -0.79116935, -0.79163820,
+ -0.79210657, -0.79257452, -0.79304194, -0.79350895, -0.79397547, -0.79444152, -0.79490715, -0.79537225,
+ -0.79583693, -0.79630107, -0.79676479, -0.79722804, -0.79769087, -0.79815316, -0.79861498, -0.79907638,
+ -0.79953724, -0.79999769, -0.80045766, -0.80091715, -0.80137616, -0.80183470, -0.80229282, -0.80275041,
+ -0.80320752, -0.80366421, -0.80412036, -0.80457610, -0.80503136, -0.80548608, -0.80594039, -0.80639422,
+ -0.80684757, -0.80730045, -0.80775285, -0.80820471, -0.80865616, -0.80910712, -0.80955762, -0.81000763,
+ -0.81045717, -0.81090623, -0.81135488, -0.81180298, -0.81225061, -0.81269777, -0.81314439, -0.81359059,
+ -0.81403631, -0.81448156, -0.81492633, -0.81537062, -0.81581444, -0.81625772, -0.81670058, -0.81714290,
+ -0.81758481, -0.81802619, -0.81846714, -0.81890756, -0.81934750, -0.81978697, -0.82022595, -0.82066447,
+ -0.82110250, -0.82154006, -0.82197714, -0.82241368, -0.82284981, -0.82328540, -0.82372051, -0.82415515,
+ -0.82458931, -0.82502300, -0.82545614, -0.82588887, -0.82632107, -0.82675278, -0.82718402, -0.82761478,
+ -0.82804507, -0.82847482, -0.82890409, -0.82933295, -0.82976121, -0.83018905, -0.83061641, -0.83104324,
+ -0.83146960, -0.83189547, -0.83232087, -0.83274579, -0.83317018, -0.83359408, -0.83401752, -0.83444041,
+ -0.83486289, -0.83528483, -0.83570629, -0.83612728, -0.83654773, -0.83696771, -0.83738720, -0.83780622,
+ -0.83822471, -0.83864272, -0.83906025, -0.83947724, -0.83989382, -0.84030986, -0.84072536, -0.84114045,
+ -0.84155500, -0.84196901, -0.84238261, -0.84279567, -0.84320825, -0.84362030, -0.84403187, -0.84444296,
+ -0.84485358, -0.84526366, -0.84567326, -0.84608233, -0.84649092, -0.84689903, -0.84730661, -0.84771377,
+ -0.84812033, -0.84852648, -0.84893203, -0.84933716, -0.84974176, -0.85014588, -0.85054946, -0.85095257,
+ -0.85135520, -0.85175729, -0.85215890, -0.85255998, -0.85296059, -0.85336071, -0.85376030, -0.85415941,
+ -0.85455799, -0.85495609, -0.85535365, -0.85575074, -0.85614735, -0.85654342, -0.85693896, -0.85733402,
+ -0.85772860, -0.85812265, -0.85851622, -0.85890925, -0.85930181, -0.85969388, -0.86008537, -0.86047643,
+ -0.86086696, -0.86125696, -0.86164647, -0.86203545, -0.86242396, -0.86281192, -0.86319941, -0.86358637,
+ -0.86397284, -0.86435878, -0.86474425, -0.86512917, -0.86551362, -0.86589754, -0.86628097, -0.86666387,
+ -0.86704624, -0.86742812, -0.86780947, -0.86819035, -0.86857069, -0.86895055, -0.86932987, -0.86970866,
+ -0.87008697, -0.87046480, -0.87084204, -0.87121886, -0.87159508, -0.87197083, -0.87234604, -0.87272078,
+ -0.87309498, -0.87346870, -0.87384182, -0.87421453, -0.87458664, -0.87495828, -0.87532938, -0.87570000,
+ -0.87607008, -0.87643969, -0.87680870, -0.87717724, -0.87754530, -0.87791282, -0.87827981, -0.87864625,
+ -0.87901223, -0.87937766, -0.87974262, -0.88010699, -0.88047087, -0.88083428, -0.88119709, -0.88155943,
+ -0.88192129, -0.88228256, -0.88264334, -0.88300359, -0.88336337, -0.88372254, -0.88408124, -0.88443947,
+ -0.88479710, -0.88515425, -0.88551086, -0.88586694, -0.88622254, -0.88657761, -0.88693213, -0.88728613,
+ -0.88763964, -0.88799256, -0.88834506, -0.88869697, -0.88904834, -0.88939923, -0.88974959, -0.89009941,
+ -0.89044875, -0.89079750, -0.89114577, -0.89149350, -0.89184070, -0.89218742, -0.89253354, -0.89287919,
+ -0.89322430, -0.89356887, -0.89391297, -0.89425647, -0.89459950, -0.89494199, -0.89528394, -0.89562535,
+ -0.89596623, -0.89630663, -0.89664650, -0.89698577, -0.89732456, -0.89766282, -0.89800060, -0.89833778,
+ -0.89867449, -0.89901060, -0.89934623, -0.89968133, -0.90001589, -0.90034992, -0.90068340, -0.90101641,
+ -0.90134883, -0.90168077, -0.90201217, -0.90234298, -0.90267330, -0.90300310, -0.90333235, -0.90366107,
+ -0.90398932, -0.90431696, -0.90464407, -0.90497071, -0.90529674, -0.90562230, -0.90594727, -0.90627176,
+ -0.90659571, -0.90691912, -0.90724200, -0.90756434, -0.90788609, -0.90820736, -0.90852809, -0.90884835,
+ -0.90916800, -0.90948713, -0.90980572, -0.91012377, -0.91044128, -0.91075826, -0.91107476, -0.91139066,
+ -0.91170603, -0.91202086, -0.91233516, -0.91264898, -0.91296220, -0.91327488, -0.91358703, -0.91389865,
+ -0.91420978, -0.91452032, -0.91483033, -0.91513979, -0.91544873, -0.91575712, -0.91606498, -0.91637230,
+ -0.91667908, -0.91698527, -0.91729099, -0.91759616, -0.91790080, -0.91820484, -0.91850841, -0.91881138,
+ -0.91911387, -0.91941577, -0.91971713, -0.92001796, -0.92031831, -0.92061806, -0.92091721, -0.92121589,
+ -0.92151403, -0.92181164, -0.92210865, -0.92240518, -0.92270112, -0.92299652, -0.92329144, -0.92358577,
+ -0.92387950, -0.92417276, -0.92446548, -0.92475760, -0.92504925, -0.92534029, -0.92563081, -0.92592078,
+ -0.92621022, -0.92649913, -0.92678750, -0.92707527, -0.92736250, -0.92764926, -0.92793542, -0.92822099,
+ -0.92850608, -0.92879063, -0.92907459, -0.92935801, -0.92964089, -0.92992324, -0.93020505, -0.93048626,
+ -0.93076694, -0.93104708, -0.93132669, -0.93160576, -0.93188429, -0.93216223, -0.93243963, -0.93271649,
+ -0.93299282, -0.93326855, -0.93354380, -0.93381846, -0.93409252, -0.93436611, -0.93463916, -0.93491161,
+ -0.93518353, -0.93545485, -0.93572569, -0.93599594, -0.93626565, -0.93653482, -0.93680346, -0.93707150,
+ -0.93733901, -0.93760598, -0.93787235, -0.93813825, -0.93840355, -0.93866831, -0.93893248, -0.93919611,
+ -0.93945920, -0.93972176, -0.93998373, -0.94024521, -0.94050604, -0.94076639, -0.94102615, -0.94128537,
+ -0.94154406, -0.94180220, -0.94205976, -0.94231677, -0.94257319, -0.94282907, -0.94308442, -0.94333923,
+ -0.94359344, -0.94384712, -0.94410026, -0.94435281, -0.94460481, -0.94485629, -0.94510722, -0.94535756,
+ -0.94560730, -0.94585657, -0.94610524, -0.94635338, -0.94660091, -0.94684792, -0.94709438, -0.94734025,
+ -0.94758558, -0.94783038, -0.94807458, -0.94831824, -0.94856137, -0.94880390, -0.94904590, -0.94928730,
+ -0.94952816, -0.94976848, -0.95000827, -0.95024747, -0.95048606, -0.95072412, -0.95096165, -0.95119864,
+ -0.95143503, -0.95167089, -0.95190614, -0.95214087, -0.95237499, -0.95260859, -0.95284164, -0.95307410,
+ -0.95330602, -0.95353740, -0.95376819, -0.95399845, -0.95422810, -0.95445722, -0.95468575, -0.95491374,
+ -0.95514119, -0.95536804, -0.95559436, -0.95582008, -0.95604527, -0.95626986, -0.95649391, -0.95671743,
+ -0.95694035, -0.95716268, -0.95738453, -0.95760572, -0.95782644, -0.95804650, -0.95826608, -0.95848507,
+ -0.95870346, -0.95892131, -0.95913863, -0.95935535, -0.95957154, -0.95978713, -0.96000212, -0.96021664,
+ -0.96043050, -0.96064389, -0.96085662, -0.96106887, -0.96128047, -0.96149158, -0.96170205, -0.96191204,
+ -0.96212143, -0.96233022, -0.96253848, -0.96274614, -0.96295327, -0.96315980, -0.96336579, -0.96357119,
+ -0.96377605, -0.96398038, -0.96418405, -0.96438724, -0.96458977, -0.96479183, -0.96499324, -0.96519411,
+ -0.96539444, -0.96559417, -0.96579337, -0.96599197, -0.96618998, -0.96638745, -0.96658438, -0.96678072,
+ -0.96697646, -0.96717167, -0.96736628, -0.96756035, -0.96775383, -0.96794677, -0.96813911, -0.96833086,
+ -0.96852207, -0.96871275, -0.96890283, -0.96909231, -0.96928126, -0.96946961, -0.96965736, -0.96984458,
+ -0.97003126, -0.97021735, -0.97040284, -0.97058779, -0.97077215, -0.97095591, -0.97113913, -0.97132182,
+ -0.97150391, -0.97168541, -0.97186631, -0.97204673, -0.97222650, -0.97240573, -0.97258437, -0.97276247,
+ -0.97293997, -0.97311687, -0.97329324, -0.97346902, -0.97364426, -0.97381890, -0.97399294, -0.97416645,
+ -0.97433937, -0.97451174, -0.97468352, -0.97485471, -0.97502536, -0.97519541, -0.97536486, -0.97553378,
+ -0.97570211, -0.97586989, -0.97603709, -0.97620368, -0.97636974, -0.97653520, -0.97670007, -0.97686440,
+ -0.97702813, -0.97719133, -0.97735387, -0.97751594, -0.97767735, -0.97783822, -0.97799850, -0.97815824,
+ -0.97831738, -0.97847593, -0.97863394, -0.97879136, -0.97894818, -0.97910446, -0.97926015, -0.97941524,
+ -0.97956979, -0.97972375, -0.97987711, -0.98002988, -0.98018211, -0.98033381, -0.98048484, -0.98063534,
+ -0.98078525, -0.98093462, -0.98108339, -0.98123157, -0.98137921, -0.98152626, -0.98167270, -0.98181856,
+ -0.98196387, -0.98210859, -0.98225272, -0.98239630, -0.98253930, -0.98268169, -0.98282355, -0.98296481,
+ -0.98310548, -0.98324561, -0.98338509, -0.98352402, -0.98366243, -0.98380023, -0.98393744, -0.98407406,
+ -0.98421007, -0.98434556, -0.98448044, -0.98461479, -0.98474848, -0.98488164, -0.98501426, -0.98514622,
+ -0.98527765, -0.98540848, -0.98553872, -0.98566842, -0.98579752, -0.98592603, -0.98605394, -0.98618132,
+ -0.98630810, -0.98643428, -0.98655993, -0.98668492, -0.98680937, -0.98693329, -0.98705655, -0.98717928,
+ -0.98730141, -0.98742294, -0.98754394, -0.98766434, -0.98778415, -0.98790336, -0.98802203, -0.98814011,
+ -0.98825759, -0.98837447, -0.98849082, -0.98860651, -0.98872167, -0.98883629, -0.98895025, -0.98906368,
+ -0.98917651, -0.98928875, -0.98940045, -0.98951149, -0.98962200, -0.98973197, -0.98984128, -0.98995006,
+ -0.99005818, -0.99016583, -0.99027282, -0.99037921, -0.99048507, -0.99059033, -0.99069500, -0.99079913,
+ -0.99090266, -0.99100554, -0.99110794, -0.99120969, -0.99131083, -0.99141145, -0.99151146, -0.99161088,
+ -0.99170977, -0.99180800, -0.99190569, -0.99200279, -0.99209929, -0.99219525, -0.99229062, -0.99238533,
+ -0.99247956, -0.99257314, -0.99266613, -0.99275857, -0.99285042, -0.99294168, -0.99303234, -0.99312246,
+ -0.99321193, -0.99330086, -0.99338919, -0.99347699, -0.99356413, -0.99365073, -0.99373674, -0.99382216,
+ -0.99390697, -0.99399120, -0.99407488, -0.99415797, -0.99424046, -0.99432236, -0.99440366, -0.99448442,
+ -0.99456459, -0.99464417, -0.99472314, -0.99480152, -0.99487931, -0.99495655, -0.99503320, -0.99510926,
+ -0.99518472, -0.99525958, -0.99533391, -0.99540764, -0.99548078, -0.99555331, -0.99562526, -0.99569660,
+ -0.99576741, -0.99583763, -0.99590725, -0.99597627, -0.99604470, -0.99611259, -0.99617982, -0.99624652,
+ -0.99631262, -0.99637812, -0.99644303, -0.99650741, -0.99657112, -0.99663430, -0.99669689, -0.99675888,
+ -0.99682027, -0.99688113, -0.99694133, -0.99700099, -0.99706006, -0.99711853, -0.99717641, -0.99723375,
+ -0.99729043, -0.99734658, -0.99740213, -0.99745709, -0.99751145, -0.99756521, -0.99761844, -0.99767107,
+ -0.99772304, -0.99777448, -0.99782532, -0.99787563, -0.99792528, -0.99797440, -0.99802285, -0.99807078,
+ -0.99811810, -0.99816483, -0.99821103, -0.99825656, -0.99830157, -0.99834591, -0.99838972, -0.99843293,
+ -0.99847555, -0.99851763, -0.99855906, -0.99859995, -0.99864024, -0.99867994, -0.99871904, -0.99875754,
+ -0.99879545, -0.99883282, -0.99886954, -0.99890572, -0.99894130, -0.99897629, -0.99901068, -0.99904448,
+ -0.99907774, -0.99911034, -0.99914241, -0.99917388, -0.99920475, -0.99923503, -0.99926478, -0.99929386,
+ -0.99932235, -0.99935031, -0.99937767, -0.99940443, -0.99943060, -0.99945617, -0.99948120, -0.99950558,
+ -0.99952942, -0.99955267, -0.99957532, -0.99959737, -0.99961883, -0.99963969, -0.99966002, -0.99967968,
+ -0.99969882, -0.99971735, -0.99973530, -0.99975264, -0.99976939, -0.99978560, -0.99980116, -0.99981618,
+ -0.99983060, -0.99984443, -0.99985766, -0.99987030, -0.99988234, -0.99989384, -0.99990469, -0.99991500,
+ -0.99992472, -0.99993384, -0.99994236, -0.99995029, -0.99995762, -0.99996442, -0.99997061, -0.99997616,
+ -0.99998116, -0.99998558, -0.99998939, -0.99999267, -0.99999529, -0.99999738, -0.99999881, -0.99999970,
+ -1.00000000, -0.99999970, -0.99999881, -0.99999738, -0.99999529, -0.99999267, -0.99998939, -0.99998558,
+ -0.99998116, -0.99997616, -0.99997061, -0.99996442, -0.99995762, -0.99995029, -0.99994236, -0.99993384,
+ -0.99992472, -0.99991500, -0.99990469, -0.99989384, -0.99988234, -0.99987030, -0.99985766, -0.99984443,
+ -0.99983060, -0.99981618, -0.99980116, -0.99978560, -0.99976939, -0.99975264, -0.99973530, -0.99971735,
+ -0.99969882, -0.99967968, -0.99966002, -0.99963969, -0.99961883, -0.99959737, -0.99957532, -0.99955267,
+ -0.99952942, -0.99950558, -0.99948120, -0.99945617, -0.99943060, -0.99940443, -0.99937767, -0.99935031,
+ -0.99932235, -0.99929386, -0.99926478, -0.99923503, -0.99920475, -0.99917388, -0.99914241, -0.99911034,
+ -0.99907774, -0.99904448, -0.99901068, -0.99897629, -0.99894130, -0.99890572, -0.99886954, -0.99883282,
+ -0.99879545, -0.99875754, -0.99871904, -0.99867994, -0.99864024, -0.99859995, -0.99855906, -0.99851763,
+ -0.99847555, -0.99843293, -0.99838972, -0.99834591, -0.99830157, -0.99825656, -0.99821103, -0.99816483,
+ -0.99811810, -0.99807078, -0.99802285, -0.99797440, -0.99792528, -0.99787563, -0.99782532, -0.99777448,
+ -0.99772304, -0.99767107, -0.99761844, -0.99756521, -0.99751145, -0.99745709, -0.99740213, -0.99734658,
+ -0.99729043, -0.99723375, -0.99717641, -0.99711853, -0.99706006, -0.99700099, -0.99694133, -0.99688113,
+ -0.99682027, -0.99675888, -0.99669689, -0.99663430, -0.99657112, -0.99650741, -0.99644303, -0.99637812,
+ -0.99631262, -0.99624652, -0.99617982, -0.99611259, -0.99604470, -0.99597627, -0.99590725, -0.99583763,
+ -0.99576741, -0.99569660, -0.99562526, -0.99555331, -0.99548078, -0.99540764, -0.99533391, -0.99525958,
+ -0.99518472, -0.99510926, -0.99503320, -0.99495655, -0.99487931, -0.99480152, -0.99472314, -0.99464417,
+ -0.99456459, -0.99448442, -0.99440366, -0.99432236, -0.99424046, -0.99415797, -0.99407488, -0.99399120,
+ -0.99390697, -0.99382216, -0.99373674, -0.99365073, -0.99356413, -0.99347699, -0.99338919, -0.99330086,
+ -0.99321193, -0.99312246, -0.99303234, -0.99294168, -0.99285042, -0.99275857, -0.99266613, -0.99257314,
+ -0.99247956, -0.99238533, -0.99229062, -0.99219525, -0.99209929, -0.99200279, -0.99190569, -0.99180800,
+ -0.99170977, -0.99161088, -0.99151146, -0.99141145, -0.99131083, -0.99120969, -0.99110794, -0.99100554,
+ -0.99090266, -0.99079913, -0.99069500, -0.99059033, -0.99048507, -0.99037921, -0.99027282, -0.99016583,
+ -0.99005818, -0.98995006, -0.98984128, -0.98973197, -0.98962200, -0.98951149, -0.98940045, -0.98928875,
+ -0.98917651, -0.98906368, -0.98895025, -0.98883629, -0.98872167, -0.98860651, -0.98849082, -0.98837447,
+ -0.98825759, -0.98814011, -0.98802203, -0.98790336, -0.98778415, -0.98766434, -0.98754394, -0.98742294,
+ -0.98730141, -0.98717928, -0.98705655, -0.98693329, -0.98680937, -0.98668492, -0.98655993, -0.98643428,
+ -0.98630810, -0.98618132, -0.98605394, -0.98592603, -0.98579752, -0.98566842, -0.98553872, -0.98540848,
+ -0.98527765, -0.98514622, -0.98501426, -0.98488164, -0.98474848, -0.98461479, -0.98448044, -0.98434556,
+ -0.98421007, -0.98407406, -0.98393744, -0.98380023, -0.98366243, -0.98352402, -0.98338509, -0.98324561,
+ -0.98310548, -0.98296481, -0.98282355, -0.98268169, -0.98253930, -0.98239630, -0.98225272, -0.98210859,
+ -0.98196387, -0.98181856, -0.98167270, -0.98152626, -0.98137921, -0.98123157, -0.98108339, -0.98093462,
+ -0.98078525, -0.98063534, -0.98048484, -0.98033381, -0.98018211, -0.98002988, -0.97987711, -0.97972375,
+ -0.97956979, -0.97941524, -0.97926015, -0.97910446, -0.97894818, -0.97879136, -0.97863394, -0.97847593,
+ -0.97831738, -0.97815824, -0.97799850, -0.97783822, -0.97767735, -0.97751594, -0.97735387, -0.97719133,
+ -0.97702813, -0.97686440, -0.97670007, -0.97653520, -0.97636974, -0.97620368, -0.97603709, -0.97586989,
+ -0.97570211, -0.97553378, -0.97536486, -0.97519541, -0.97502536, -0.97485471, -0.97468352, -0.97451174,
+ -0.97433937, -0.97416645, -0.97399294, -0.97381890, -0.97364426, -0.97346902, -0.97329324, -0.97311687,
+ -0.97293997, -0.97276247, -0.97258437, -0.97240573, -0.97222650, -0.97204673, -0.97186631, -0.97168541,
+ -0.97150391, -0.97132182, -0.97113913, -0.97095591, -0.97077215, -0.97058779, -0.97040284, -0.97021735,
+ -0.97003126, -0.96984458, -0.96965736, -0.96946961, -0.96928126, -0.96909231, -0.96890283, -0.96871275,
+ -0.96852207, -0.96833086, -0.96813911, -0.96794677, -0.96775383, -0.96756035, -0.96736628, -0.96717167,
+ -0.96697646, -0.96678072, -0.96658438, -0.96638745, -0.96618998, -0.96599197, -0.96579337, -0.96559417,
+ -0.96539444, -0.96519411, -0.96499324, -0.96479183, -0.96458977, -0.96438724, -0.96418405, -0.96398038,
+ -0.96377605, -0.96357119, -0.96336579, -0.96315980, -0.96295327, -0.96274614, -0.96253848, -0.96233022,
+ -0.96212143, -0.96191204, -0.96170205, -0.96149158, -0.96128047, -0.96106887, -0.96085662, -0.96064389,
+ -0.96043050, -0.96021664, -0.96000212, -0.95978713, -0.95957154, -0.95935535, -0.95913863, -0.95892131,
+ -0.95870346, -0.95848507, -0.95826608, -0.95804650, -0.95782644, -0.95760572, -0.95738453, -0.95716268,
+ -0.95694035, -0.95671743, -0.95649391, -0.95626986, -0.95604527, -0.95582008, -0.95559436, -0.95536804,
+ -0.95514119, -0.95491374, -0.95468575, -0.95445722, -0.95422810, -0.95399845, -0.95376819, -0.95353740,
+ -0.95330602, -0.95307410, -0.95284164, -0.95260859, -0.95237499, -0.95214087, -0.95190614, -0.95167089,
+ -0.95143503, -0.95119864, -0.95096165, -0.95072412, -0.95048606, -0.95024747, -0.95000827, -0.94976848,
+ -0.94952816, -0.94928730, -0.94904590, -0.94880390, -0.94856137, -0.94831824, -0.94807458, -0.94783038,
+ -0.94758558, -0.94734025, -0.94709438, -0.94684792, -0.94660091, -0.94635338, -0.94610524, -0.94585657,
+ -0.94560730, -0.94535756, -0.94510722, -0.94485629, -0.94460481, -0.94435281, -0.94410026, -0.94384712,
+ -0.94359344, -0.94333923, -0.94308442, -0.94282907, -0.94257319, -0.94231677, -0.94205976, -0.94180220,
+ -0.94154406, -0.94128537, -0.94102615, -0.94076639, -0.94050604, -0.94024521, -0.93998373, -0.93972176,
+ -0.93945920, -0.93919611, -0.93893248, -0.93866831, -0.93840355, -0.93813825, -0.93787235, -0.93760598,
+ -0.93733901, -0.93707150, -0.93680346, -0.93653482, -0.93626565, -0.93599594, -0.93572569, -0.93545485,
+ -0.93518353, -0.93491161, -0.93463916, -0.93436611, -0.93409252, -0.93381846, -0.93354380, -0.93326855,
+ -0.93299282, -0.93271649, -0.93243963, -0.93216223, -0.93188429, -0.93160576, -0.93132669, -0.93104708,
+ -0.93076694, -0.93048626, -0.93020505, -0.92992324, -0.92964089, -0.92935801, -0.92907459, -0.92879063,
+ -0.92850608, -0.92822099, -0.92793542, -0.92764926, -0.92736250, -0.92707527, -0.92678750, -0.92649913,
+ -0.92621022, -0.92592078, -0.92563081, -0.92534029, -0.92504925, -0.92475760, -0.92446548, -0.92417276,
+ -0.92387950, -0.92358577, -0.92329144, -0.92299652, -0.92270112, -0.92240518, -0.92210865, -0.92181164,
+ -0.92151403, -0.92121589, -0.92091721, -0.92061806, -0.92031831, -0.92001796, -0.91971713, -0.91941577,
+ -0.91911387, -0.91881138, -0.91850841, -0.91820484, -0.91790080, -0.91759616, -0.91729099, -0.91698527,
+ -0.91667908, -0.91637230, -0.91606498, -0.91575712, -0.91544873, -0.91513979, -0.91483033, -0.91452032,
+ -0.91420978, -0.91389865, -0.91358703, -0.91327488, -0.91296220, -0.91264898, -0.91233516, -0.91202086,
+ -0.91170603, -0.91139066, -0.91107476, -0.91075826, -0.91044128, -0.91012377, -0.90980572, -0.90948713,
+ -0.90916800, -0.90884835, -0.90852809, -0.90820736, -0.90788609, -0.90756434, -0.90724200, -0.90691912,
+ -0.90659571, -0.90627176, -0.90594727, -0.90562230, -0.90529674, -0.90497071, -0.90464407, -0.90431696,
+ -0.90398932, -0.90366107, -0.90333235, -0.90300310, -0.90267330, -0.90234298, -0.90201217, -0.90168077,
+ -0.90134883, -0.90101641, -0.90068340, -0.90034992, -0.90001589, -0.89968133, -0.89934623, -0.89901060,
+ -0.89867449, -0.89833778, -0.89800060, -0.89766282, -0.89732456, -0.89698577, -0.89664650, -0.89630663,
+ -0.89596623, -0.89562535, -0.89528394, -0.89494199, -0.89459950, -0.89425647, -0.89391297, -0.89356887,
+ -0.89322430, -0.89287919, -0.89253354, -0.89218742, -0.89184070, -0.89149350, -0.89114577, -0.89079750,
+ -0.89044875, -0.89009941, -0.88974959, -0.88939923, -0.88904834, -0.88869697, -0.88834506, -0.88799256,
+ -0.88763964, -0.88728613, -0.88693213, -0.88657761, -0.88622254, -0.88586694, -0.88551086, -0.88515425,
+ -0.88479710, -0.88443947, -0.88408124, -0.88372254, -0.88336337, -0.88300359, -0.88264334, -0.88228256,
+ -0.88192129, -0.88155943, -0.88119709, -0.88083428, -0.88047087, -0.88010699, -0.87974262, -0.87937766,
+ -0.87901223, -0.87864625, -0.87827981, -0.87791282, -0.87754530, -0.87717724, -0.87680870, -0.87643969,
+ -0.87607008, -0.87570000, -0.87532938, -0.87495828, -0.87458664, -0.87421453, -0.87384182, -0.87346870,
+ -0.87309498, -0.87272078, -0.87234604, -0.87197083, -0.87159508, -0.87121886, -0.87084204, -0.87046480,
+ -0.87008697, -0.86970866, -0.86932987, -0.86895055, -0.86857069, -0.86819035, -0.86780947, -0.86742812,
+ -0.86704624, -0.86666387, -0.86628097, -0.86589754, -0.86551362, -0.86512917, -0.86474425, -0.86435878,
+ -0.86397284, -0.86358637, -0.86319941, -0.86281192, -0.86242396, -0.86203545, -0.86164647, -0.86125696,
+ -0.86086696, -0.86047643, -0.86008537, -0.85969388, -0.85930181, -0.85890925, -0.85851622, -0.85812265,
+ -0.85772860, -0.85733402, -0.85693896, -0.85654342, -0.85614735, -0.85575074, -0.85535365, -0.85495609,
+ -0.85455799, -0.85415941, -0.85376030, -0.85336071, -0.85296059, -0.85255998, -0.85215890, -0.85175729,
+ -0.85135520, -0.85095257, -0.85054946, -0.85014588, -0.84974176, -0.84933716, -0.84893203, -0.84852648,
+ -0.84812033, -0.84771377, -0.84730661, -0.84689903, -0.84649092, -0.84608233, -0.84567326, -0.84526366,
+ -0.84485358, -0.84444296, -0.84403187, -0.84362030, -0.84320825, -0.84279567, -0.84238261, -0.84196901,
+ -0.84155500, -0.84114045, -0.84072536, -0.84030986, -0.83989382, -0.83947724, -0.83906025, -0.83864272,
+ -0.83822471, -0.83780622, -0.83738720, -0.83696771, -0.83654773, -0.83612728, -0.83570629, -0.83528483,
+ -0.83486289, -0.83444041, -0.83401752, -0.83359408, -0.83317018, -0.83274579, -0.83232087, -0.83189547,
+ -0.83146960, -0.83104324, -0.83061641, -0.83018905, -0.82976121, -0.82933295, -0.82890409, -0.82847482,
+ -0.82804507, -0.82761478, -0.82718402, -0.82675278, -0.82632107, -0.82588887, -0.82545614, -0.82502300,
+ -0.82458931, -0.82415515, -0.82372051, -0.82328540, -0.82284981, -0.82241368, -0.82197714, -0.82154006,
+ -0.82110250, -0.82066447, -0.82022595, -0.81978697, -0.81934750, -0.81890756, -0.81846714, -0.81802619,
+ -0.81758481, -0.81714290, -0.81670058, -0.81625772, -0.81581444, -0.81537062, -0.81492633, -0.81448156,
+ -0.81403631, -0.81359059, -0.81314439, -0.81269777, -0.81225061, -0.81180298, -0.81135488, -0.81090623,
+ -0.81045717, -0.81000763, -0.80955762, -0.80910712, -0.80865616, -0.80820471, -0.80775285, -0.80730045,
+ -0.80684757, -0.80639422, -0.80594039, -0.80548608, -0.80503136, -0.80457610, -0.80412036, -0.80366421,
+ -0.80320752, -0.80275041, -0.80229282, -0.80183470, -0.80137616, -0.80091715, -0.80045766, -0.79999769,
+ -0.79953724, -0.79907638, -0.79861498, -0.79815316, -0.79769087, -0.79722804, -0.79676479, -0.79630107,
+ -0.79583693, -0.79537225, -0.79490715, -0.79444152, -0.79397547, -0.79350895, -0.79304194, -0.79257452,
+ -0.79210657, -0.79163820, -0.79116935, -0.79070002, -0.79023021, -0.78975999, -0.78928924, -0.78881806,
+ -0.78834641, -0.78787434, -0.78740174, -0.78692871, -0.78645521, -0.78598124, -0.78550684, -0.78503191,
+ -0.78455657, -0.78408080, -0.78360450, -0.78312778, -0.78265059, -0.78217292, -0.78169483, -0.78121626,
+ -0.78073722, -0.78025776, -0.77977777, -0.77929735, -0.77881652, -0.77833521, -0.77785343, -0.77737117,
+ -0.77688849, -0.77640533, -0.77592170, -0.77543765, -0.77495313, -0.77446812, -0.77398270, -0.77349681,
+ -0.77301043, -0.77252364, -0.77203637, -0.77154869, -0.77106053, -0.77057189, -0.77008283, -0.76959330,
+ -0.76910335, -0.76861292, -0.76812202, -0.76763070, -0.76713890, -0.76664668, -0.76615399, -0.76566088,
+ -0.76516724, -0.76467323, -0.76417875, -0.76368380, -0.76318842, -0.76269257, -0.76219630, -0.76169956,
+ -0.76120239, -0.76070476, -0.76020670, -0.75970817, -0.75920922, -0.75870979, -0.75820988, -0.75770962,
+ -0.75720882, -0.75670767, -0.75620598, -0.75570393, -0.75520140, -0.75469840, -0.75419497, -0.75369114,
+ -0.75318682, -0.75268203, -0.75217682, -0.75167120, -0.75116515, -0.75065863, -0.75015163, -0.74964422,
+ -0.74913639, -0.74862808, -0.74811935, -0.74761021, -0.74710059, -0.74659055, -0.74608010, -0.74556917,
+ -0.74505776, -0.74454600, -0.74403375, -0.74352109, -0.74300796, -0.74249440, -0.74198043, -0.74146599,
+ -0.74095112, -0.74043584, -0.73992008, -0.73940390, -0.73888731, -0.73837030, -0.73785281, -0.73733491,
+ -0.73681659, -0.73629779, -0.73577857, -0.73525894, -0.73473889, -0.73421836, -0.73369741, -0.73317605,
+ -0.73265427, -0.73213202, -0.73160940, -0.73108631, -0.73056275, -0.73003882, -0.72951442, -0.72898960,
+ -0.72846437, -0.72793871, -0.72741264, -0.72688609, -0.72635913, -0.72583181, -0.72530395, -0.72477573,
+ -0.72424710, -0.72371799, -0.72318846, -0.72265857, -0.72212821, -0.72159743, -0.72106618, -0.72053456,
+ -0.72000253, -0.71947002, -0.71893710, -0.71840382, -0.71787006, -0.71733588, -0.71680129, -0.71626627,
+ -0.71573085, -0.71519494, -0.71465868, -0.71412200, -0.71358484, -0.71304733, -0.71250939, -0.71197098,
+ -0.71143222, -0.71089298, -0.71035337, -0.70981330, -0.70927280, -0.70873195, -0.70819062, -0.70764893,
+ -0.70710677, -0.70656425, -0.70602125, -0.70547789, -0.70493406, -0.70438987, -0.70384526, -0.70330018,
+ -0.70275474, -0.70220888, -0.70166260, -0.70111591, -0.70056880, -0.70002127, -0.69947332, -0.69892502,
+ -0.69837624, -0.69782710, -0.69727749, -0.69672751, -0.69617712, -0.69562632, -0.69507509, -0.69452351,
+ -0.69397146, -0.69341904, -0.69286615, -0.69231290, -0.69175923, -0.69120520, -0.69065070, -0.69009584,
+ -0.68954057, -0.68898487, -0.68842876, -0.68787223, -0.68731534, -0.68675804, -0.68620032, -0.68564218,
+ -0.68508369, -0.68452471, -0.68396538, -0.68340570, -0.68284553, -0.68228501, -0.68172407, -0.68116271,
+ -0.68060100, -0.68003887, -0.67947632, -0.67891335, -0.67835003, -0.67778629, -0.67722219, -0.67665762,
+ -0.67609268, -0.67552739, -0.67496163, -0.67439550, -0.67382902, -0.67326206, -0.67269474, -0.67212707,
+ -0.67155898, -0.67099047, -0.67042154, -0.66985226, -0.66928262, -0.66871250, -0.66814202, -0.66757119,
+ -0.66699994, -0.66642827, -0.66585624, -0.66528380, -0.66471100, -0.66413778, -0.66356415, -0.66299015,
+ -0.66241580, -0.66184098, -0.66126585, -0.66069031, -0.66011435, -0.65953803, -0.65896130, -0.65838420,
+ -0.65780669, -0.65722883, -0.65665054, -0.65607190, -0.65549284, -0.65491343, -0.65433359, -0.65375340,
+ -0.65317285, -0.65259188, -0.65201056, -0.65142882, -0.65084666, -0.65026420, -0.64968133, -0.64909804,
+ -0.64851439, -0.64793038, -0.64734596, -0.64676118, -0.64617604, -0.64559048, -0.64500451, -0.64441824,
+ -0.64383155, -0.64324450, -0.64265704, -0.64206922, -0.64148104, -0.64089245, -0.64030349, -0.63971418,
+ -0.63912445, -0.63853437, -0.63794392, -0.63735306, -0.63676184, -0.63617027, -0.63557833, -0.63498598,
+ -0.63439327, -0.63380021, -0.63320678, -0.63261294, -0.63201874, -0.63142419, -0.63082922, -0.63023394,
+ -0.62963825, -0.62904221, -0.62844574, -0.62784898, -0.62725180, -0.62665427, -0.62605637, -0.62545812,
+ -0.62485951, -0.62426049, -0.62366110, -0.62306136, -0.62246126, -0.62186080, -0.62125999, -0.62065876,
+ -0.62005723, -0.61945528, -0.61885297, -0.61825031, -0.61764729, -0.61704391, -0.61644018, -0.61583608,
+ -0.61523157, -0.61462677, -0.61402154, -0.61341602, -0.61281008, -0.61220378, -0.61159718, -0.61099017,
+ -0.61038280, -0.60977507, -0.60916704, -0.60855860, -0.60794979, -0.60734063, -0.60673112, -0.60612124,
+ -0.60551107, -0.60490048, -0.60428953, -0.60367823, -0.60306662, -0.60245460, -0.60184222, -0.60122955,
+ -0.60061646, -0.60000306, -0.59938931, -0.59877521, -0.59816068, -0.59754586, -0.59693068, -0.59631521,
+ -0.59569931, -0.59508306, -0.59446651, -0.59384960, -0.59323227, -0.59261465, -0.59199667, -0.59137839,
+ -0.59075969, -0.59014070, -0.58952129, -0.58890158, -0.58828157, -0.58766115, -0.58704036, -0.58641928,
+ -0.58579785, -0.58517605, -0.58455396, -0.58393145, -0.58330864, -0.58268547, -0.58206201, -0.58143812,
+ -0.58081394, -0.58018941, -0.57956457, -0.57893932, -0.57831377, -0.57768792, -0.57706165, -0.57643509,
+ -0.57580817, -0.57518095, -0.57455337, -0.57392544, -0.57329714, -0.57266855, -0.57203960, -0.57141036,
+ -0.57078075, -0.57015079, -0.56952053, -0.56888992, -0.56825894, -0.56762767, -0.56699604, -0.56636411,
+ -0.56573182, -0.56509918, -0.56446624, -0.56383294, -0.56319934, -0.56256539, -0.56193113, -0.56129652,
+ -0.56066155, -0.56002629, -0.55939072, -0.55875480, -0.55811852, -0.55748194, -0.55684501, -0.55620778,
+ -0.55557024, -0.55493236, -0.55429411, -0.55365556, -0.55301672, -0.55237752, -0.55173796, -0.55109817,
+ -0.55045795, -0.54981750, -0.54917663, -0.54853553, -0.54789406, -0.54725230, -0.54661018, -0.54596776,
+ -0.54532498, -0.54468191, -0.54403853, -0.54339480, -0.54275078, -0.54210645, -0.54146177, -0.54081678,
+ -0.54017144, -0.53952587, -0.53887993, -0.53823364, -0.53758705, -0.53694016, -0.53629297, -0.53564548,
+ -0.53499764, -0.53434944, -0.53370100, -0.53305221, -0.53240311, -0.53175372, -0.53110403, -0.53045398,
+ -0.52980363, -0.52915299, -0.52850199, -0.52785075, -0.52719915, -0.52654725, -0.52589500, -0.52524251,
+ -0.52458966, -0.52393657, -0.52328312, -0.52262938, -0.52197528, -0.52132094, -0.52066624, -0.52001125,
+ -0.51935601, -0.51870042, -0.51804453, -0.51738828, -0.51673180, -0.51607502, -0.51541787, -0.51476043,
+ -0.51410276, -0.51344472, -0.51278639, -0.51212776, -0.51146883, -0.51080960, -0.51015007, -0.50949025,
+ -0.50883013, -0.50816971, -0.50750899, -0.50684798, -0.50618666, -0.50552505, -0.50486308, -0.50420088,
+ -0.50353837, -0.50287557, -0.50221246, -0.50154907, -0.50088537, -0.50022137, -0.49955711, -0.49889255,
+ -0.49822766, -0.49756250, -0.49689704, -0.49623129, -0.49556527, -0.49489895, -0.49423230, -0.49356541,
+ -0.49289820, -0.49223071, -0.49156290, -0.49089485, -0.49022648, -0.48955783, -0.48888889, -0.48821968,
+ -0.48755017, -0.48688036, -0.48621029, -0.48553991, -0.48486924, -0.48419830, -0.48352706, -0.48285556,
+ -0.48218378, -0.48151168, -0.48083934, -0.48016667, -0.47949377, -0.47882056, -0.47814706, -0.47747329,
+ -0.47679922, -0.47612488, -0.47545028, -0.47477537, -0.47410020, -0.47342476, -0.47274902, -0.47207302,
+ -0.47139674, -0.47072017, -0.47004333, -0.46936622, -0.46868882, -0.46801114, -0.46733320, -0.46665499,
+ -0.46597651, -0.46529773, -0.46461868, -0.46393937, -0.46325979, -0.46257994, -0.46189979, -0.46121940,
+ -0.46053872, -0.45985776, -0.45917654, -0.45849505, -0.45781329, -0.45713127, -0.45644897, -0.45576641,
+ -0.45508358, -0.45440048, -0.45371711, -0.45303348, -0.45234957, -0.45166543, -0.45098099, -0.45029628,
+ -0.44961134, -0.44892609, -0.44824061, -0.44755486, -0.44686884, -0.44618255, -0.44549602, -0.44480920,
+ -0.44412214, -0.44343480, -0.44274724, -0.44205937, -0.44137126, -0.44068289, -0.43999428, -0.43930539,
+ -0.43861625, -0.43792683, -0.43723717, -0.43654725, -0.43585709, -0.43516666, -0.43447596, -0.43378502,
+ -0.43309382, -0.43240237, -0.43171066, -0.43101871, -0.43032649, -0.42963400, -0.42894128, -0.42824832,
+ -0.42755508, -0.42686161, -0.42616788, -0.42547390, -0.42477968, -0.42408520, -0.42339048, -0.42269549,
+ -0.42200026, -0.42130479, -0.42060909, -0.41991311, -0.41921690, -0.41852042, -0.41782370, -0.41712677,
+ -0.41642955, -0.41573212, -0.41503441, -0.41433650, -0.41363832, -0.41293988, -0.41224122, -0.41154233,
+ -0.41084316, -0.41014379, -0.40944415, -0.40874428, -0.40804416, -0.40734380, -0.40664321, -0.40594238,
+ -0.40524131, -0.40454000, -0.40383846, -0.40313667, -0.40243465, -0.40173239, -0.40102988, -0.40032718,
+ -0.39962420, -0.39892101, -0.39821756, -0.39751390, -0.39681000, -0.39610586, -0.39540148, -0.39469686,
+ -0.39399204, -0.39328697, -0.39258167, -0.39187613, -0.39117038, -0.39046440, -0.38975817, -0.38905174,
+ -0.38834503, -0.38763815, -0.38693100, -0.38622364, -0.38551605, -0.38480824, -0.38410020, -0.38339192,
+ -0.38268343, -0.38197473, -0.38126576, -0.38055661, -0.37984720, -0.37913761, -0.37842774, -0.37771770,
+ -0.37700742, -0.37629691, -0.37558618, -0.37487522, -0.37416407, -0.37345266, -0.37274107, -0.37202924,
+ -0.37131721, -0.37060493, -0.36989245, -0.36917976, -0.36846682, -0.36775368, -0.36704034, -0.36632678,
+ -0.36561298, -0.36489901, -0.36418480, -0.36347038, -0.36275572, -0.36204088, -0.36132580, -0.36061051,
+ -0.35989505, -0.35917935, -0.35846341, -0.35774729, -0.35703096, -0.35631442, -0.35559767, -0.35488069,
+ -0.35416353, -0.35344616, -0.35272855, -0.35201076, -0.35129276, -0.35057455, -0.34985614, -0.34913751,
+ -0.34841868, -0.34769964, -0.34698042, -0.34626096, -0.34554133, -0.34482148, -0.34410143, -0.34338117,
+ -0.34266073, -0.34194008, -0.34121922, -0.34049815, -0.33977687, -0.33905542, -0.33833376, -0.33761191,
+ -0.33688986, -0.33616760, -0.33544514, -0.33472249, -0.33399966, -0.33327660, -0.33255336, -0.33182994,
+ -0.33110631, -0.33038250, -0.32965845, -0.32893425, -0.32820985, -0.32748523, -0.32676044, -0.32603547,
+ -0.32531029, -0.32458493, -0.32385936, -0.32313362, -0.32240769, -0.32168156, -0.32095525, -0.32022873,
+ -0.31950203, -0.31877515, -0.31804809, -0.31732082, -0.31659338, -0.31586576, -0.31513792, -0.31440994,
+ -0.31368175, -0.31295338, -0.31222481, -0.31149608, -0.31076714, -0.31003806, -0.30930877, -0.30857930,
+ -0.30784965, -0.30711982, -0.30638981, -0.30565959, -0.30492923, -0.30419868, -0.30346796, -0.30273703,
+ -0.30200595, -0.30127469, -0.30054325, -0.29981163, -0.29907984, -0.29834786, -0.29761571, -0.29688337,
+ -0.29615089, -0.29541820, -0.29468536, -0.29395235, -0.29321915, -0.29248580, -0.29175225, -0.29101855,
+ -0.29028466, -0.28955063, -0.28881642, -0.28808203, -0.28734747, -0.28661272, -0.28587782, -0.28514278,
+ -0.28440753, -0.28367212, -0.28293657, -0.28220084, -0.28146493, -0.28072888, -0.27999264, -0.27925625,
+ -0.27851969, -0.27778298, -0.27704608, -0.27630904, -0.27557182, -0.27483445, -0.27409691, -0.27335921,
+ -0.27262136, -0.27188334, -0.27114516, -0.27040681, -0.26966831, -0.26892966, -0.26819086, -0.26745188,
+ -0.26671275, -0.26597348, -0.26523402, -0.26449442, -0.26375467, -0.26301476, -0.26227471, -0.26153448,
+ -0.26079410, -0.26005360, -0.25931293, -0.25857207, -0.25783110, -0.25708997, -0.25634867, -0.25560725,
+ -0.25486565, -0.25412393, -0.25338203, -0.25264001, -0.25189781, -0.25115550, -0.25041300, -0.24967039,
+ -0.24892761, -0.24818468, -0.24744162, -0.24669841, -0.24595505, -0.24521154, -0.24446790, -0.24372411,
+ -0.24298018, -0.24223611, -0.24149188, -0.24074753, -0.24000302, -0.23925838, -0.23851359, -0.23776866,
+ -0.23702361, -0.23627840, -0.23553306, -0.23478758, -0.23404196, -0.23329620, -0.23255031, -0.23180428,
+ -0.23105811, -0.23031181, -0.22956537, -0.22881879, -0.22807208, -0.22732525, -0.22657827, -0.22583115,
+ -0.22508392, -0.22433653, -0.22358903, -0.22284140, -0.22209363, -0.22134572, -0.22059768, -0.21984953,
+ -0.21910124, -0.21835282, -0.21760428, -0.21685560, -0.21610680, -0.21535787, -0.21460882, -0.21385963,
+ -0.21311031, -0.21236089, -0.21161133, -0.21086164, -0.21011184, -0.20936191, -0.20861185, -0.20786168,
+ -0.20711137, -0.20636095, -0.20561041, -0.20485975, -0.20410897, -0.20335807, -0.20260704, -0.20185590,
+ -0.20110464, -0.20035325, -0.19960175, -0.19885014, -0.19809841, -0.19734657, -0.19659460, -0.19584252,
+ -0.19509032, -0.19433801, -0.19358559, -0.19283305, -0.19208039, -0.19132763, -0.19057475, -0.18982176,
+ -0.18906866, -0.18831545, -0.18756212, -0.18680869, -0.18605515, -0.18530150, -0.18454774, -0.18379387,
+ -0.18303989, -0.18228580, -0.18153161, -0.18077731, -0.18002290, -0.17926839, -0.17851377, -0.17775905,
+ -0.17700422, -0.17624930, -0.17549425, -0.17473911, -0.17398387, -0.17322853, -0.17247309, -0.17171754,
+ -0.17096189, -0.17020614, -0.16945030, -0.16869435, -0.16793829, -0.16718215, -0.16642590, -0.16566956,
+ -0.16491312, -0.16415659, -0.16339995, -0.16264322, -0.16188639, -0.16112947, -0.16037245, -0.15961535,
+ -0.15885815, -0.15810084, -0.15734346, -0.15658598, -0.15582840, -0.15507074, -0.15431297, -0.15355512,
+ -0.15279719, -0.15203916, -0.15128104, -0.15052283, -0.14976454, -0.14900614, -0.14824767, -0.14748912,
+ -0.14673047, -0.14597175, -0.14521292, -0.14445402, -0.14369503, -0.14293596, -0.14217681, -0.14141756,
+ -0.14065824, -0.13989884, -0.13913934, -0.13837977, -0.13762012, -0.13686039, -0.13610058, -0.13534068,
+ -0.13458070, -0.13382065, -0.13306053, -0.13230032, -0.13154003, -0.13077967, -0.13001922, -0.12925871,
+ -0.12849811, -0.12773745, -0.12697670, -0.12621588, -0.12545498, -0.12469402, -0.12393297, -0.12317186,
+ -0.12241068, -0.12164941, -0.12088808, -0.12012669, -0.11936522, -0.11860368, -0.11784206, -0.11708038,
+ -0.11631863, -0.11555681, -0.11479492, -0.11403298, -0.11327095, -0.11250886, -0.11174671, -0.11098449,
+ -0.11022221, -0.10945985, -0.10869744, -0.10793497, -0.10717242, -0.10640982, -0.10564715, -0.10488442,
+ -0.10412163, -0.10335878, -0.10259587, -0.10183290, -0.10106986, -0.10030677, -0.09954362, -0.09878041,
+ -0.09801714, -0.09725381, -0.09649043, -0.09572699, -0.09496350, -0.09419994, -0.09343634, -0.09267268,
+ -0.09190895, -0.09114519, -0.09038136, -0.08961748, -0.08885355, -0.08808957, -0.08732554, -0.08656145,
+ -0.08579731, -0.08503313, -0.08426889, -0.08350460, -0.08274026, -0.08197588, -0.08121145, -0.08044697,
+ -0.07968244, -0.07891786, -0.07815325, -0.07738858, -0.07662386, -0.07585911, -0.07509430, -0.07432945,
+ -0.07356457, -0.07279963, -0.07203465, -0.07126963, -0.07050458, -0.06973947, -0.06897433, -0.06820914,
+ -0.06744392, -0.06667866, -0.06591335, -0.06514801, -0.06438263, -0.06361721, -0.06285176, -0.06208627,
+ -0.06132074, -0.06055517, -0.05978957, -0.05902394, -0.05825827, -0.05749256, -0.05672682, -0.05596105,
+ -0.05519525, -0.05442941, -0.05366354, -0.05289764, -0.05213170, -0.05136574, -0.05059975, -0.04983373,
+ -0.04906768, -0.04830159, -0.04753548, -0.04676935, -0.04600318, -0.04523699, -0.04447077, -0.04370453,
+ -0.04293826, -0.04217196, -0.04140564, -0.04063930, -0.03987293, -0.03910654, -0.03834012, -0.03757368,
+ -0.03680722, -0.03604074, -0.03527424, -0.03450771, -0.03374117, -0.03297461, -0.03220803, -0.03144142,
+ -0.03067480, -0.02990817, -0.02914151, -0.02837484, -0.02760815, -0.02684144, -0.02607472, -0.02530798,
+ -0.02454123, -0.02377446, -0.02300768, -0.02224089, -0.02147408, -0.02070726, -0.01994043, -0.01917358,
+ -0.01840673, -0.01763986, -0.01687299, -0.01610610, -0.01533921, -0.01457230, -0.01380539, -0.01303847,
+ -0.01227154, -0.01150460, -0.01073766, -0.00997071, -0.00920375, -0.00843679, -0.00766983, -0.00690286,
+ -0.00613588, -0.00536891, -0.00460193, -0.00383494, -0.00306796, -0.00230097, -0.00153398, -0.00076699,
+ -0.00000000, 0.00076699, 0.00153398, 0.00230097, 0.00306796, 0.00383494, 0.00460193, 0.00536891,
+ 0.00613588, 0.00690286, 0.00766983, 0.00843679, 0.00920375, 0.00997071, 0.01073766, 0.01150460,
+ 0.01227154, 0.01303847, 0.01380539, 0.01457230, 0.01533921, 0.01610610, 0.01687299, 0.01763986,
+ 0.01840673, 0.01917358, 0.01994043, 0.02070726, 0.02147408, 0.02224089, 0.02300768, 0.02377446,
+ 0.02454123, 0.02530798, 0.02607472, 0.02684144, 0.02760815, 0.02837484, 0.02914151, 0.02990817,
+ 0.03067480, 0.03144142, 0.03220803, 0.03297461, 0.03374117, 0.03450771, 0.03527424, 0.03604074,
+ 0.03680722, 0.03757368, 0.03834012, 0.03910654, 0.03987293, 0.04063930, 0.04140564, 0.04217196,
+ 0.04293826, 0.04370453, 0.04447077, 0.04523699, 0.04600318, 0.04676935, 0.04753548, 0.04830159,
+ 0.04906768, 0.04983373, 0.05059975, 0.05136574, 0.05213170, 0.05289764, 0.05366354, 0.05442941,
+ 0.05519525, 0.05596105, 0.05672682, 0.05749256, 0.05825827, 0.05902394, 0.05978957, 0.06055517,
+ 0.06132074, 0.06208627, 0.06285176, 0.06361721, 0.06438263, 0.06514801, 0.06591335, 0.06667866,
+ 0.06744392, 0.06820914, 0.06897433, 0.06973947, 0.07050458, 0.07126963, 0.07203465, 0.07279963,
+ 0.07356457, 0.07432945, 0.07509430, 0.07585911, 0.07662386, 0.07738858, 0.07815325, 0.07891786,
+ 0.07968244, 0.08044697, 0.08121145, 0.08197588, 0.08274026, 0.08350460, 0.08426889, 0.08503313,
+ 0.08579731, 0.08656145, 0.08732554, 0.08808957, 0.08885355, 0.08961748, 0.09038136, 0.09114519,
+ 0.09190895, 0.09267268, 0.09343634, 0.09419994, 0.09496350, 0.09572699, 0.09649043, 0.09725381,
+ 0.09801714, 0.09878041, 0.09954362, 0.10030677, 0.10106986, 0.10183290, 0.10259587, 0.10335878,
+ 0.10412163, 0.10488442, 0.10564715, 0.10640982, 0.10717242, 0.10793497, 0.10869744, 0.10945985,
+ 0.11022221, 0.11098449, 0.11174671, 0.11250886, 0.11327095, 0.11403298, 0.11479492, 0.11555681,
+ 0.11631863, 0.11708038, 0.11784206, 0.11860368, 0.11936522, 0.12012669, 0.12088808, 0.12164941,
+ 0.12241068, 0.12317186, 0.12393297, 0.12469402, 0.12545498, 0.12621588, 0.12697670, 0.12773745,
+ 0.12849811, 0.12925871, 0.13001922, 0.13077967, 0.13154003, 0.13230032, 0.13306053, 0.13382065,
+ 0.13458070, 0.13534068, 0.13610058, 0.13686039, 0.13762012, 0.13837977, 0.13913934, 0.13989884,
+ 0.14065824, 0.14141756, 0.14217681, 0.14293596, 0.14369503, 0.14445402, 0.14521292, 0.14597175,
+ 0.14673047, 0.14748912, 0.14824767, 0.14900614, 0.14976454, 0.15052283, 0.15128104, 0.15203916,
+ 0.15279719, 0.15355512, 0.15431297, 0.15507074, 0.15582840, 0.15658598, 0.15734346, 0.15810084,
+ 0.15885815, 0.15961535, 0.16037245, 0.16112947, 0.16188639, 0.16264322, 0.16339995, 0.16415659,
+ 0.16491312, 0.16566956, 0.16642590, 0.16718215, 0.16793829, 0.16869435, 0.16945030, 0.17020614,
+ 0.17096189, 0.17171754, 0.17247309, 0.17322853, 0.17398387, 0.17473911, 0.17549425, 0.17624930,
+ 0.17700422, 0.17775905, 0.17851377, 0.17926839, 0.18002290, 0.18077731, 0.18153161, 0.18228580,
+ 0.18303989, 0.18379387, 0.18454774, 0.18530150, 0.18605515, 0.18680869, 0.18756212, 0.18831545,
+ 0.18906866, 0.18982176, 0.19057475, 0.19132763, 0.19208039, 0.19283305, 0.19358559, 0.19433801,
+ 0.19509032, 0.19584252, 0.19659460, 0.19734657, 0.19809841, 0.19885014, 0.19960175, 0.20035325,
+ 0.20110464, 0.20185590, 0.20260704, 0.20335807, 0.20410897, 0.20485975, 0.20561041, 0.20636095,
+ 0.20711137, 0.20786168, 0.20861185, 0.20936191, 0.21011184, 0.21086164, 0.21161133, 0.21236089,
+ 0.21311031, 0.21385963, 0.21460882, 0.21535787, 0.21610680, 0.21685560, 0.21760428, 0.21835282,
+ 0.21910124, 0.21984953, 0.22059768, 0.22134572, 0.22209363, 0.22284140, 0.22358903, 0.22433653,
+ 0.22508392, 0.22583115, 0.22657827, 0.22732525, 0.22807208, 0.22881879, 0.22956537, 0.23031181,
+ 0.23105811, 0.23180428, 0.23255031, 0.23329620, 0.23404196, 0.23478758, 0.23553306, 0.23627840,
+ 0.23702361, 0.23776866, 0.23851359, 0.23925838, 0.24000302, 0.24074753, 0.24149188, 0.24223611,
+ 0.24298018, 0.24372411, 0.24446790, 0.24521154, 0.24595505, 0.24669841, 0.24744162, 0.24818468,
+ 0.24892761, 0.24967039, 0.25041300, 0.25115550, 0.25189781, 0.25264001, 0.25338203, 0.25412393,
+ 0.25486565, 0.25560725, 0.25634867, 0.25708997, 0.25783110, 0.25857207, 0.25931293, 0.26005360,
+ 0.26079410, 0.26153448, 0.26227471, 0.26301476, 0.26375467, 0.26449442, 0.26523402, 0.26597348,
+ 0.26671275, 0.26745188, 0.26819086, 0.26892966, 0.26966831, 0.27040681, 0.27114516, 0.27188334,
+ 0.27262136, 0.27335921, 0.27409691, 0.27483445, 0.27557182, 0.27630904, 0.27704608, 0.27778298,
+ 0.27851969, 0.27925625, 0.27999264, 0.28072888, 0.28146493, 0.28220084, 0.28293657, 0.28367212,
+ 0.28440753, 0.28514278, 0.28587782, 0.28661272, 0.28734747, 0.28808203, 0.28881642, 0.28955063,
+ 0.29028466, 0.29101855, 0.29175225, 0.29248580, 0.29321915, 0.29395235, 0.29468536, 0.29541820,
+ 0.29615089, 0.29688337, 0.29761571, 0.29834786, 0.29907984, 0.29981163, 0.30054325, 0.30127469,
+ 0.30200595, 0.30273703, 0.30346796, 0.30419868, 0.30492923, 0.30565959, 0.30638981, 0.30711982,
+ 0.30784965, 0.30857930, 0.30930877, 0.31003806, 0.31076714, 0.31149608, 0.31222481, 0.31295338,
+ 0.31368175, 0.31440994, 0.31513792, 0.31586576, 0.31659338, 0.31732082, 0.31804809, 0.31877515,
+ 0.31950203, 0.32022873, 0.32095525, 0.32168156, 0.32240769, 0.32313362, 0.32385936, 0.32458493,
+ 0.32531029, 0.32603547, 0.32676044, 0.32748523, 0.32820985, 0.32893425, 0.32965845, 0.33038250,
+ 0.33110631, 0.33182994, 0.33255336, 0.33327660, 0.33399966, 0.33472249, 0.33544514, 0.33616760,
+ 0.33688986, 0.33761191, 0.33833376, 0.33905542, 0.33977687, 0.34049815, 0.34121922, 0.34194008,
+ 0.34266073, 0.34338117, 0.34410143, 0.34482148, 0.34554133, 0.34626096, 0.34698042, 0.34769964,
+ 0.34841868, 0.34913751, 0.34985614, 0.35057455, 0.35129276, 0.35201076, 0.35272855, 0.35344616,
+ 0.35416353, 0.35488069, 0.35559767, 0.35631442, 0.35703096, 0.35774729, 0.35846341, 0.35917935,
+ 0.35989505, 0.36061051, 0.36132580, 0.36204088, 0.36275572, 0.36347038, 0.36418480, 0.36489901,
+ 0.36561298, 0.36632678, 0.36704034, 0.36775368, 0.36846682, 0.36917976, 0.36989245, 0.37060493,
+ 0.37131721, 0.37202924, 0.37274107, 0.37345266, 0.37416407, 0.37487522, 0.37558618, 0.37629691,
+ 0.37700742, 0.37771770, 0.37842774, 0.37913761, 0.37984720, 0.38055661, 0.38126576, 0.38197473,
+ 0.38268343, 0.38339192, 0.38410020, 0.38480824, 0.38551605, 0.38622364, 0.38693100, 0.38763815,
+ 0.38834503, 0.38905174, 0.38975817, 0.39046440, 0.39117038, 0.39187613, 0.39258167, 0.39328697,
+ 0.39399204, 0.39469686, 0.39540148, 0.39610586, 0.39681000, 0.39751390, 0.39821756, 0.39892101,
+ 0.39962420, 0.40032718, 0.40102988, 0.40173239, 0.40243465, 0.40313667, 0.40383846, 0.40454000,
+ 0.40524131, 0.40594238, 0.40664321, 0.40734380, 0.40804416, 0.40874428, 0.40944415, 0.41014379,
+ 0.41084316, 0.41154233, 0.41224122, 0.41293988, 0.41363832, 0.41433650, 0.41503441, 0.41573212,
+ 0.41642955, 0.41712677, 0.41782370, 0.41852042, 0.41921690, 0.41991311, 0.42060909, 0.42130479,
+ 0.42200026, 0.42269549, 0.42339048, 0.42408520, 0.42477968, 0.42547390, 0.42616788, 0.42686161,
+ 0.42755508, 0.42824832, 0.42894128, 0.42963400, 0.43032649, 0.43101871, 0.43171066, 0.43240237,
+ 0.43309382, 0.43378502, 0.43447596, 0.43516666, 0.43585709, 0.43654725, 0.43723717, 0.43792683,
+ 0.43861625, 0.43930539, 0.43999428, 0.44068289, 0.44137126, 0.44205937, 0.44274724, 0.44343480,
+ 0.44412214, 0.44480920, 0.44549602, 0.44618255, 0.44686884, 0.44755486, 0.44824061, 0.44892609,
+ 0.44961134, 0.45029628, 0.45098099, 0.45166543, 0.45234957, 0.45303348, 0.45371711, 0.45440048,
+ 0.45508358, 0.45576641, 0.45644897, 0.45713127, 0.45781329, 0.45849505, 0.45917654, 0.45985776,
+ 0.46053872, 0.46121940, 0.46189979, 0.46257994, 0.46325979, 0.46393937, 0.46461868, 0.46529773,
+ 0.46597651, 0.46665499, 0.46733320, 0.46801114, 0.46868882, 0.46936622, 0.47004333, 0.47072017,
+ 0.47139674, 0.47207302, 0.47274902, 0.47342476, 0.47410020, 0.47477537, 0.47545028, 0.47612488,
+ 0.47679922, 0.47747329, 0.47814706, 0.47882056, 0.47949377, 0.48016667, 0.48083934, 0.48151168,
+ 0.48218378, 0.48285556, 0.48352706, 0.48419830, 0.48486924, 0.48553991, 0.48621029, 0.48688036,
+ 0.48755017, 0.48821968, 0.48888889, 0.48955783, 0.49022648, 0.49089485, 0.49156290, 0.49223071,
+ 0.49289820, 0.49356541, 0.49423230, 0.49489895, 0.49556527, 0.49623129, 0.49689704, 0.49756250,
+ 0.49822766, 0.49889255, 0.49955711, 0.50022137, 0.50088537, 0.50154907, 0.50221246, 0.50287557,
+ 0.50353837, 0.50420088, 0.50486308, 0.50552505, 0.50618666, 0.50684798, 0.50750899, 0.50816971,
+ 0.50883013, 0.50949025, 0.51015007, 0.51080960, 0.51146883, 0.51212776, 0.51278639, 0.51344472,
+ 0.51410276, 0.51476043, 0.51541787, 0.51607502, 0.51673180, 0.51738828, 0.51804453, 0.51870042,
+ 0.51935601, 0.52001125, 0.52066624, 0.52132094, 0.52197528, 0.52262938, 0.52328312, 0.52393657,
+ 0.52458966, 0.52524251, 0.52589500, 0.52654725, 0.52719915, 0.52785075, 0.52850199, 0.52915299,
+ 0.52980363, 0.53045398, 0.53110403, 0.53175372, 0.53240311, 0.53305221, 0.53370100, 0.53434944,
+ 0.53499764, 0.53564548, 0.53629297, 0.53694016, 0.53758705, 0.53823364, 0.53887993, 0.53952587,
+ 0.54017144, 0.54081678, 0.54146177, 0.54210645, 0.54275078, 0.54339480, 0.54403853, 0.54468191,
+ 0.54532498, 0.54596776, 0.54661018, 0.54725230, 0.54789406, 0.54853553, 0.54917663, 0.54981750,
+ 0.55045795, 0.55109817, 0.55173796, 0.55237752, 0.55301672, 0.55365556, 0.55429411, 0.55493236,
+ 0.55557024, 0.55620778, 0.55684501, 0.55748194, 0.55811852, 0.55875480, 0.55939072, 0.56002629,
+ 0.56066155, 0.56129652, 0.56193113, 0.56256539, 0.56319934, 0.56383294, 0.56446624, 0.56509918,
+ 0.56573182, 0.56636411, 0.56699604, 0.56762767, 0.56825894, 0.56888992, 0.56952053, 0.57015079,
+ 0.57078075, 0.57141036, 0.57203960, 0.57266855, 0.57329714, 0.57392544, 0.57455337, 0.57518095,
+ 0.57580817, 0.57643509, 0.57706165, 0.57768792, 0.57831377, 0.57893932, 0.57956457, 0.58018941,
+ 0.58081394, 0.58143812, 0.58206201, 0.58268547, 0.58330864, 0.58393145, 0.58455396, 0.58517605,
+ 0.58579785, 0.58641928, 0.58704036, 0.58766115, 0.58828157, 0.58890158, 0.58952129, 0.59014070,
+ 0.59075969, 0.59137839, 0.59199667, 0.59261465, 0.59323227, 0.59384960, 0.59446651, 0.59508306,
+ 0.59569931, 0.59631521, 0.59693068, 0.59754586, 0.59816068, 0.59877521, 0.59938931, 0.60000306,
+ 0.60061646, 0.60122955, 0.60184222, 0.60245460, 0.60306662, 0.60367823, 0.60428953, 0.60490048,
+ 0.60551107, 0.60612124, 0.60673112, 0.60734063, 0.60794979, 0.60855860, 0.60916704, 0.60977507,
+ 0.61038280, 0.61099017, 0.61159718, 0.61220378, 0.61281008, 0.61341602, 0.61402154, 0.61462677,
+ 0.61523157, 0.61583608, 0.61644018, 0.61704391, 0.61764729, 0.61825031, 0.61885297, 0.61945528,
+ 0.62005723, 0.62065876, 0.62125999, 0.62186080, 0.62246126, 0.62306136, 0.62366110, 0.62426049,
+ 0.62485951, 0.62545812, 0.62605637, 0.62665427, 0.62725180, 0.62784898, 0.62844574, 0.62904221,
+ 0.62963825, 0.63023394, 0.63082922, 0.63142419, 0.63201874, 0.63261294, 0.63320678, 0.63380021,
+ 0.63439327, 0.63498598, 0.63557833, 0.63617027, 0.63676184, 0.63735306, 0.63794392, 0.63853437,
+ 0.63912445, 0.63971418, 0.64030349, 0.64089245, 0.64148104, 0.64206922, 0.64265704, 0.64324450,
+ 0.64383155, 0.64441824, 0.64500451, 0.64559048, 0.64617604, 0.64676118, 0.64734596, 0.64793038,
+ 0.64851439, 0.64909804, 0.64968133, 0.65026420, 0.65084666, 0.65142882, 0.65201056, 0.65259188,
+ 0.65317285, 0.65375340, 0.65433359, 0.65491343, 0.65549284, 0.65607190, 0.65665054, 0.65722883,
+ 0.65780669, 0.65838420, 0.65896130, 0.65953803, 0.66011435, 0.66069031, 0.66126585, 0.66184098,
+ 0.66241580, 0.66299015, 0.66356415, 0.66413778, 0.66471100, 0.66528380, 0.66585624, 0.66642827,
+ 0.66699994, 0.66757119, 0.66814202, 0.66871250, 0.66928262, 0.66985226, 0.67042154, 0.67099047,
+ 0.67155898, 0.67212707, 0.67269474, 0.67326206, 0.67382902, 0.67439550, 0.67496163, 0.67552739,
+ 0.67609268, 0.67665762, 0.67722219, 0.67778629, 0.67835003, 0.67891335, 0.67947632, 0.68003887,
+ 0.68060100, 0.68116271, 0.68172407, 0.68228501, 0.68284553, 0.68340570, 0.68396538, 0.68452471,
+ 0.68508369, 0.68564218, 0.68620032, 0.68675804, 0.68731534, 0.68787223, 0.68842876, 0.68898487,
+ 0.68954057, 0.69009584, 0.69065070, 0.69120520, 0.69175923, 0.69231290, 0.69286615, 0.69341904,
+ 0.69397146, 0.69452351, 0.69507509, 0.69562632, 0.69617712, 0.69672751, 0.69727749, 0.69782710,
+ 0.69837624, 0.69892502, 0.69947332, 0.70002127, 0.70056880, 0.70111591, 0.70166260, 0.70220888,
+ 0.70275474, 0.70330018, 0.70384526, 0.70438987, 0.70493406, 0.70547789, 0.70602125, 0.70656425,
+ 0.70710677, 0.70764893, 0.70819062, 0.70873195, 0.70927280, 0.70981330, 0.71035337, 0.71089298,
+ 0.71143222, 0.71197098, 0.71250939, 0.71304733, 0.71358484, 0.71412200, 0.71465868, 0.71519494,
+ 0.71573085, 0.71626627, 0.71680129, 0.71733588, 0.71787006, 0.71840382, 0.71893710, 0.71947002,
+ 0.72000253, 0.72053456, 0.72106618, 0.72159743, 0.72212821, 0.72265857, 0.72318846, 0.72371799,
+ 0.72424710, 0.72477573, 0.72530395, 0.72583181, 0.72635913, 0.72688609, 0.72741264, 0.72793871,
+ 0.72846437, 0.72898960, 0.72951442, 0.73003882, 0.73056275, 0.73108631, 0.73160940, 0.73213202,
+ 0.73265427, 0.73317605, 0.73369741, 0.73421836, 0.73473889, 0.73525894, 0.73577857, 0.73629779,
+ 0.73681659, 0.73733491, 0.73785281, 0.73837030, 0.73888731, 0.73940390, 0.73992008, 0.74043584,
+ 0.74095112, 0.74146599, 0.74198043, 0.74249440, 0.74300796, 0.74352109, 0.74403375, 0.74454600,
+ 0.74505776, 0.74556917, 0.74608010, 0.74659055, 0.74710059, 0.74761021, 0.74811935, 0.74862808,
+ 0.74913639, 0.74964422, 0.75015163, 0.75065863, 0.75116515, 0.75167120, 0.75217682, 0.75268203,
+ 0.75318682, 0.75369114, 0.75419497, 0.75469840, 0.75520140, 0.75570393, 0.75620598, 0.75670767,
+ 0.75720882, 0.75770962, 0.75820988, 0.75870979, 0.75920922, 0.75970817, 0.76020670, 0.76070476,
+ 0.76120239, 0.76169956, 0.76219630, 0.76269257, 0.76318842, 0.76368380, 0.76417875, 0.76467323,
+ 0.76516724, 0.76566088, 0.76615399, 0.76664668, 0.76713890, 0.76763070, 0.76812202, 0.76861292,
+ 0.76910335, 0.76959330, 0.77008283, 0.77057189, 0.77106053, 0.77154869, 0.77203637, 0.77252364,
+ 0.77301043, 0.77349681, 0.77398270, 0.77446812, 0.77495313, 0.77543765, 0.77592170, 0.77640533,
+ 0.77688849, 0.77737117, 0.77785343, 0.77833521, 0.77881652, 0.77929735, 0.77977777, 0.78025776,
+ 0.78073722, 0.78121626, 0.78169483, 0.78217292, 0.78265059, 0.78312778, 0.78360450, 0.78408080,
+ 0.78455657, 0.78503191, 0.78550684, 0.78598124, 0.78645521, 0.78692871, 0.78740174, 0.78787434,
+ 0.78834641, 0.78881806, 0.78928924, 0.78975999, 0.79023021, 0.79070002, 0.79116935, 0.79163820,
+ 0.79210657, 0.79257452, 0.79304194, 0.79350895, 0.79397547, 0.79444152, 0.79490715, 0.79537225,
+ 0.79583693, 0.79630107, 0.79676479, 0.79722804, 0.79769087, 0.79815316, 0.79861498, 0.79907638,
+ 0.79953724, 0.79999769, 0.80045766, 0.80091715, 0.80137616, 0.80183470, 0.80229282, 0.80275041,
+ 0.80320752, 0.80366421, 0.80412036, 0.80457610, 0.80503136, 0.80548608, 0.80594039, 0.80639422,
+ 0.80684757, 0.80730045, 0.80775285, 0.80820471, 0.80865616, 0.80910712, 0.80955762, 0.81000763,
+ 0.81045717, 0.81090623, 0.81135488, 0.81180298, 0.81225061, 0.81269777, 0.81314439, 0.81359059,
+ 0.81403631, 0.81448156, 0.81492633, 0.81537062, 0.81581444, 0.81625772, 0.81670058, 0.81714290,
+ 0.81758481, 0.81802619, 0.81846714, 0.81890756, 0.81934750, 0.81978697, 0.82022595, 0.82066447,
+ 0.82110250, 0.82154006, 0.82197714, 0.82241368, 0.82284981, 0.82328540, 0.82372051, 0.82415515,
+ 0.82458931, 0.82502300, 0.82545614, 0.82588887, 0.82632107, 0.82675278, 0.82718402, 0.82761478,
+ 0.82804507, 0.82847482, 0.82890409, 0.82933295, 0.82976121, 0.83018905, 0.83061641, 0.83104324,
+ 0.83146960, 0.83189547, 0.83232087, 0.83274579, 0.83317018, 0.83359408, 0.83401752, 0.83444041,
+ 0.83486289, 0.83528483, 0.83570629, 0.83612728, 0.83654773, 0.83696771, 0.83738720, 0.83780622,
+ 0.83822471, 0.83864272, 0.83906025, 0.83947724, 0.83989382, 0.84030986, 0.84072536, 0.84114045,
+ 0.84155500, 0.84196901, 0.84238261, 0.84279567, 0.84320825, 0.84362030, 0.84403187, 0.84444296,
+ 0.84485358, 0.84526366, 0.84567326, 0.84608233, 0.84649092, 0.84689903, 0.84730661, 0.84771377,
+ 0.84812033, 0.84852648, 0.84893203, 0.84933716, 0.84974176, 0.85014588, 0.85054946, 0.85095257,
+ 0.85135520, 0.85175729, 0.85215890, 0.85255998, 0.85296059, 0.85336071, 0.85376030, 0.85415941,
+ 0.85455799, 0.85495609, 0.85535365, 0.85575074, 0.85614735, 0.85654342, 0.85693896, 0.85733402,
+ 0.85772860, 0.85812265, 0.85851622, 0.85890925, 0.85930181, 0.85969388, 0.86008537, 0.86047643,
+ 0.86086696, 0.86125696, 0.86164647, 0.86203545, 0.86242396, 0.86281192, 0.86319941, 0.86358637,
+ 0.86397284, 0.86435878, 0.86474425, 0.86512917, 0.86551362, 0.86589754, 0.86628097, 0.86666387,
+ 0.86704624, 0.86742812, 0.86780947, 0.86819035, 0.86857069, 0.86895055, 0.86932987, 0.86970866,
+ 0.87008697, 0.87046480, 0.87084204, 0.87121886, 0.87159508, 0.87197083, 0.87234604, 0.87272078,
+ 0.87309498, 0.87346870, 0.87384182, 0.87421453, 0.87458664, 0.87495828, 0.87532938, 0.87570000,
+ 0.87607008, 0.87643969, 0.87680870, 0.87717724, 0.87754530, 0.87791282, 0.87827981, 0.87864625,
+ 0.87901223, 0.87937766, 0.87974262, 0.88010699, 0.88047087, 0.88083428, 0.88119709, 0.88155943,
+ 0.88192129, 0.88228256, 0.88264334, 0.88300359, 0.88336337, 0.88372254, 0.88408124, 0.88443947,
+ 0.88479710, 0.88515425, 0.88551086, 0.88586694, 0.88622254, 0.88657761, 0.88693213, 0.88728613,
+ 0.88763964, 0.88799256, 0.88834506, 0.88869697, 0.88904834, 0.88939923, 0.88974959, 0.89009941,
+ 0.89044875, 0.89079750, 0.89114577, 0.89149350, 0.89184070, 0.89218742, 0.89253354, 0.89287919,
+ 0.89322430, 0.89356887, 0.89391297, 0.89425647, 0.89459950, 0.89494199, 0.89528394, 0.89562535,
+ 0.89596623, 0.89630663, 0.89664650, 0.89698577, 0.89732456, 0.89766282, 0.89800060, 0.89833778,
+ 0.89867449, 0.89901060, 0.89934623, 0.89968133, 0.90001589, 0.90034992, 0.90068340, 0.90101641,
+ 0.90134883, 0.90168077, 0.90201217, 0.90234298, 0.90267330, 0.90300310, 0.90333235, 0.90366107,
+ 0.90398932, 0.90431696, 0.90464407, 0.90497071, 0.90529674, 0.90562230, 0.90594727, 0.90627176,
+ 0.90659571, 0.90691912, 0.90724200, 0.90756434, 0.90788609, 0.90820736, 0.90852809, 0.90884835,
+ 0.90916800, 0.90948713, 0.90980572, 0.91012377, 0.91044128, 0.91075826, 0.91107476, 0.91139066,
+ 0.91170603, 0.91202086, 0.91233516, 0.91264898, 0.91296220, 0.91327488, 0.91358703, 0.91389865,
+ 0.91420978, 0.91452032, 0.91483033, 0.91513979, 0.91544873, 0.91575712, 0.91606498, 0.91637230,
+ 0.91667908, 0.91698527, 0.91729099, 0.91759616, 0.91790080, 0.91820484, 0.91850841, 0.91881138,
+ 0.91911387, 0.91941577, 0.91971713, 0.92001796, 0.92031831, 0.92061806, 0.92091721, 0.92121589,
+ 0.92151403, 0.92181164, 0.92210865, 0.92240518, 0.92270112, 0.92299652, 0.92329144, 0.92358577,
+ 0.92387950, 0.92417276, 0.92446548, 0.92475760, 0.92504925, 0.92534029, 0.92563081, 0.92592078,
+ 0.92621022, 0.92649913, 0.92678750, 0.92707527, 0.92736250, 0.92764926, 0.92793542, 0.92822099,
+ 0.92850608, 0.92879063, 0.92907459, 0.92935801, 0.92964089, 0.92992324, 0.93020505, 0.93048626,
+ 0.93076694, 0.93104708, 0.93132669, 0.93160576, 0.93188429, 0.93216223, 0.93243963, 0.93271649,
+ 0.93299282, 0.93326855, 0.93354380, 0.93381846, 0.93409252, 0.93436611, 0.93463916, 0.93491161,
+ 0.93518353, 0.93545485, 0.93572569, 0.93599594, 0.93626565, 0.93653482, 0.93680346, 0.93707150,
+ 0.93733901, 0.93760598, 0.93787235, 0.93813825, 0.93840355, 0.93866831, 0.93893248, 0.93919611,
+ 0.93945920, 0.93972176, 0.93998373, 0.94024521, 0.94050604, 0.94076639, 0.94102615, 0.94128537,
+ 0.94154406, 0.94180220, 0.94205976, 0.94231677, 0.94257319, 0.94282907, 0.94308442, 0.94333923,
+ 0.94359344, 0.94384712, 0.94410026, 0.94435281, 0.94460481, 0.94485629, 0.94510722, 0.94535756,
+ 0.94560730, 0.94585657, 0.94610524, 0.94635338, 0.94660091, 0.94684792, 0.94709438, 0.94734025,
+ 0.94758558, 0.94783038, 0.94807458, 0.94831824, 0.94856137, 0.94880390, 0.94904590, 0.94928730,
+ 0.94952816, 0.94976848, 0.95000827, 0.95024747, 0.95048606, 0.95072412, 0.95096165, 0.95119864,
+ 0.95143503, 0.95167089, 0.95190614, 0.95214087, 0.95237499, 0.95260859, 0.95284164, 0.95307410,
+ 0.95330602, 0.95353740, 0.95376819, 0.95399845, 0.95422810, 0.95445722, 0.95468575, 0.95491374,
+ 0.95514119, 0.95536804, 0.95559436, 0.95582008, 0.95604527, 0.95626986, 0.95649391, 0.95671743,
+ 0.95694035, 0.95716268, 0.95738453, 0.95760572, 0.95782644, 0.95804650, 0.95826608, 0.95848507,
+ 0.95870346, 0.95892131, 0.95913863, 0.95935535, 0.95957154, 0.95978713, 0.96000212, 0.96021664,
+ 0.96043050, 0.96064389, 0.96085662, 0.96106887, 0.96128047, 0.96149158, 0.96170205, 0.96191204,
+ 0.96212143, 0.96233022, 0.96253848, 0.96274614, 0.96295327, 0.96315980, 0.96336579, 0.96357119,
+ 0.96377605, 0.96398038, 0.96418405, 0.96438724, 0.96458977, 0.96479183, 0.96499324, 0.96519411,
+ 0.96539444, 0.96559417, 0.96579337, 0.96599197, 0.96618998, 0.96638745, 0.96658438, 0.96678072,
+ 0.96697646, 0.96717167, 0.96736628, 0.96756035, 0.96775383, 0.96794677, 0.96813911, 0.96833086,
+ 0.96852207, 0.96871275, 0.96890283, 0.96909231, 0.96928126, 0.96946961, 0.96965736, 0.96984458,
+ 0.97003126, 0.97021735, 0.97040284, 0.97058779, 0.97077215, 0.97095591, 0.97113913, 0.97132182,
+ 0.97150391, 0.97168541, 0.97186631, 0.97204673, 0.97222650, 0.97240573, 0.97258437, 0.97276247,
+ 0.97293997, 0.97311687, 0.97329324, 0.97346902, 0.97364426, 0.97381890, 0.97399294, 0.97416645,
+ 0.97433937, 0.97451174, 0.97468352, 0.97485471, 0.97502536, 0.97519541, 0.97536486, 0.97553378,
+ 0.97570211, 0.97586989, 0.97603709, 0.97620368, 0.97636974, 0.97653520, 0.97670007, 0.97686440,
+ 0.97702813, 0.97719133, 0.97735387, 0.97751594, 0.97767735, 0.97783822, 0.97799850, 0.97815824,
+ 0.97831738, 0.97847593, 0.97863394, 0.97879136, 0.97894818, 0.97910446, 0.97926015, 0.97941524,
+ 0.97956979, 0.97972375, 0.97987711, 0.98002988, 0.98018211, 0.98033381, 0.98048484, 0.98063534,
+ 0.98078525, 0.98093462, 0.98108339, 0.98123157, 0.98137921, 0.98152626, 0.98167270, 0.98181856,
+ 0.98196387, 0.98210859, 0.98225272, 0.98239630, 0.98253930, 0.98268169, 0.98282355, 0.98296481,
+ 0.98310548, 0.98324561, 0.98338509, 0.98352402, 0.98366243, 0.98380023, 0.98393744, 0.98407406,
+ 0.98421007, 0.98434556, 0.98448044, 0.98461479, 0.98474848, 0.98488164, 0.98501426, 0.98514622,
+ 0.98527765, 0.98540848, 0.98553872, 0.98566842, 0.98579752, 0.98592603, 0.98605394, 0.98618132,
+ 0.98630810, 0.98643428, 0.98655993, 0.98668492, 0.98680937, 0.98693329, 0.98705655, 0.98717928,
+ 0.98730141, 0.98742294, 0.98754394, 0.98766434, 0.98778415, 0.98790336, 0.98802203, 0.98814011,
+ 0.98825759, 0.98837447, 0.98849082, 0.98860651, 0.98872167, 0.98883629, 0.98895025, 0.98906368,
+ 0.98917651, 0.98928875, 0.98940045, 0.98951149, 0.98962200, 0.98973197, 0.98984128, 0.98995006,
+ 0.99005818, 0.99016583, 0.99027282, 0.99037921, 0.99048507, 0.99059033, 0.99069500, 0.99079913,
+ 0.99090266, 0.99100554, 0.99110794, 0.99120969, 0.99131083, 0.99141145, 0.99151146, 0.99161088,
+ 0.99170977, 0.99180800, 0.99190569, 0.99200279, 0.99209929, 0.99219525, 0.99229062, 0.99238533,
+ 0.99247956, 0.99257314, 0.99266613, 0.99275857, 0.99285042, 0.99294168, 0.99303234, 0.99312246,
+ 0.99321193, 0.99330086, 0.99338919, 0.99347699, 0.99356413, 0.99365073, 0.99373674, 0.99382216,
+ 0.99390697, 0.99399120, 0.99407488, 0.99415797, 0.99424046, 0.99432236, 0.99440366, 0.99448442,
+ 0.99456459, 0.99464417, 0.99472314, 0.99480152, 0.99487931, 0.99495655, 0.99503320, 0.99510926,
+ 0.99518472, 0.99525958, 0.99533391, 0.99540764, 0.99548078, 0.99555331, 0.99562526, 0.99569660,
+ 0.99576741, 0.99583763, 0.99590725, 0.99597627, 0.99604470, 0.99611259, 0.99617982, 0.99624652,
+ 0.99631262, 0.99637812, 0.99644303, 0.99650741, 0.99657112, 0.99663430, 0.99669689, 0.99675888,
+ 0.99682027, 0.99688113, 0.99694133, 0.99700099, 0.99706006, 0.99711853, 0.99717641, 0.99723375,
+ 0.99729043, 0.99734658, 0.99740213, 0.99745709, 0.99751145, 0.99756521, 0.99761844, 0.99767107,
+ 0.99772304, 0.99777448, 0.99782532, 0.99787563, 0.99792528, 0.99797440, 0.99802285, 0.99807078,
+ 0.99811810, 0.99816483, 0.99821103, 0.99825656, 0.99830157, 0.99834591, 0.99838972, 0.99843293,
+ 0.99847555, 0.99851763, 0.99855906, 0.99859995, 0.99864024, 0.99867994, 0.99871904, 0.99875754,
+ 0.99879545, 0.99883282, 0.99886954, 0.99890572, 0.99894130, 0.99897629, 0.99901068, 0.99904448,
+ 0.99907774, 0.99911034, 0.99914241, 0.99917388, 0.99920475, 0.99923503, 0.99926478, 0.99929386,
+ 0.99932235, 0.99935031, 0.99937767, 0.99940443, 0.99943060, 0.99945617, 0.99948120, 0.99950558,
+ 0.99952942, 0.99955267, 0.99957532, 0.99959737, 0.99961883, 0.99963969, 0.99966002, 0.99967968,
+ 0.99969882, 0.99971735, 0.99973530, 0.99975264, 0.99976939, 0.99978560, 0.99980116, 0.99981618,
+ 0.99983060, 0.99984443, 0.99985766, 0.99987030, 0.99988234, 0.99989384, 0.99990469, 0.99991500,
+ 0.99992472, 0.99993384, 0.99994236, 0.99995029, 0.99995762, 0.99996442, 0.99997061, 0.99997616,
+ 0.99998116, 0.99998558, 0.99998939, 0.99999267, 0.99999529, 0.99999738, 0.99999881, 0.99999970
+ };
+
+static const float sinTable[FFT_TABLE_SIZE]={
+ 0.00000000, 0.00076699, 0.00153398, 0.00230097, 0.00306796, 0.00383494, 0.00460193, 0.00536891,
+ 0.00613588, 0.00690286, 0.00766983, 0.00843679, 0.00920375, 0.00997071, 0.01073766, 0.01150460,
+ 0.01227154, 0.01303847, 0.01380539, 0.01457230, 0.01533921, 0.01610610, 0.01687299, 0.01763986,
+ 0.01840673, 0.01917358, 0.01994043, 0.02070726, 0.02147408, 0.02224089, 0.02300768, 0.02377446,
+ 0.02454123, 0.02530798, 0.02607472, 0.02684144, 0.02760815, 0.02837484, 0.02914151, 0.02990817,
+ 0.03067480, 0.03144142, 0.03220803, 0.03297461, 0.03374117, 0.03450771, 0.03527424, 0.03604074,
+ 0.03680722, 0.03757368, 0.03834012, 0.03910654, 0.03987293, 0.04063930, 0.04140564, 0.04217196,
+ 0.04293826, 0.04370453, 0.04447077, 0.04523699, 0.04600318, 0.04676935, 0.04753548, 0.04830159,
+ 0.04906768, 0.04983373, 0.05059975, 0.05136574, 0.05213170, 0.05289764, 0.05366354, 0.05442941,
+ 0.05519525, 0.05596105, 0.05672682, 0.05749256, 0.05825827, 0.05902394, 0.05978957, 0.06055517,
+ 0.06132074, 0.06208627, 0.06285176, 0.06361721, 0.06438263, 0.06514801, 0.06591335, 0.06667866,
+ 0.06744392, 0.06820914, 0.06897433, 0.06973947, 0.07050458, 0.07126963, 0.07203465, 0.07279963,
+ 0.07356457, 0.07432945, 0.07509430, 0.07585911, 0.07662386, 0.07738858, 0.07815325, 0.07891786,
+ 0.07968244, 0.08044697, 0.08121145, 0.08197588, 0.08274026, 0.08350460, 0.08426889, 0.08503313,
+ 0.08579731, 0.08656145, 0.08732554, 0.08808957, 0.08885355, 0.08961748, 0.09038136, 0.09114519,
+ 0.09190895, 0.09267268, 0.09343634, 0.09419994, 0.09496350, 0.09572699, 0.09649043, 0.09725381,
+ 0.09801714, 0.09878041, 0.09954362, 0.10030677, 0.10106986, 0.10183290, 0.10259587, 0.10335878,
+ 0.10412163, 0.10488442, 0.10564715, 0.10640982, 0.10717242, 0.10793497, 0.10869744, 0.10945985,
+ 0.11022221, 0.11098449, 0.11174671, 0.11250886, 0.11327095, 0.11403298, 0.11479492, 0.11555681,
+ 0.11631863, 0.11708038, 0.11784206, 0.11860368, 0.11936522, 0.12012669, 0.12088808, 0.12164941,
+ 0.12241068, 0.12317186, 0.12393297, 0.12469402, 0.12545498, 0.12621588, 0.12697670, 0.12773745,
+ 0.12849811, 0.12925871, 0.13001922, 0.13077967, 0.13154003, 0.13230032, 0.13306053, 0.13382065,
+ 0.13458070, 0.13534068, 0.13610058, 0.13686039, 0.13762012, 0.13837977, 0.13913934, 0.13989884,
+ 0.14065824, 0.14141756, 0.14217681, 0.14293596, 0.14369503, 0.14445402, 0.14521292, 0.14597175,
+ 0.14673047, 0.14748912, 0.14824767, 0.14900614, 0.14976454, 0.15052283, 0.15128104, 0.15203916,
+ 0.15279719, 0.15355512, 0.15431297, 0.15507074, 0.15582840, 0.15658598, 0.15734346, 0.15810084,
+ 0.15885815, 0.15961535, 0.16037245, 0.16112947, 0.16188639, 0.16264322, 0.16339995, 0.16415659,
+ 0.16491312, 0.16566956, 0.16642590, 0.16718215, 0.16793829, 0.16869435, 0.16945030, 0.17020614,
+ 0.17096189, 0.17171754, 0.17247309, 0.17322853, 0.17398387, 0.17473911, 0.17549425, 0.17624930,
+ 0.17700422, 0.17775905, 0.17851377, 0.17926839, 0.18002290, 0.18077731, 0.18153161, 0.18228580,
+ 0.18303989, 0.18379387, 0.18454774, 0.18530150, 0.18605515, 0.18680869, 0.18756212, 0.18831545,
+ 0.18906866, 0.18982176, 0.19057475, 0.19132763, 0.19208039, 0.19283305, 0.19358559, 0.19433801,
+ 0.19509032, 0.19584252, 0.19659460, 0.19734657, 0.19809841, 0.19885014, 0.19960175, 0.20035325,
+ 0.20110464, 0.20185590, 0.20260704, 0.20335807, 0.20410897, 0.20485975, 0.20561041, 0.20636095,
+ 0.20711137, 0.20786168, 0.20861185, 0.20936191, 0.21011184, 0.21086164, 0.21161133, 0.21236089,
+ 0.21311031, 0.21385963, 0.21460882, 0.21535787, 0.21610680, 0.21685560, 0.21760428, 0.21835282,
+ 0.21910124, 0.21984953, 0.22059768, 0.22134572, 0.22209363, 0.22284140, 0.22358903, 0.22433653,
+ 0.22508392, 0.22583115, 0.22657827, 0.22732525, 0.22807208, 0.22881879, 0.22956537, 0.23031181,
+ 0.23105811, 0.23180428, 0.23255031, 0.23329620, 0.23404196, 0.23478758, 0.23553306, 0.23627840,
+ 0.23702361, 0.23776866, 0.23851359, 0.23925838, 0.24000302, 0.24074753, 0.24149188, 0.24223611,
+ 0.24298018, 0.24372411, 0.24446790, 0.24521154, 0.24595505, 0.24669841, 0.24744162, 0.24818468,
+ 0.24892761, 0.24967039, 0.25041300, 0.25115550, 0.25189781, 0.25264001, 0.25338203, 0.25412393,
+ 0.25486565, 0.25560725, 0.25634867, 0.25708997, 0.25783110, 0.25857207, 0.25931293, 0.26005360,
+ 0.26079410, 0.26153448, 0.26227471, 0.26301476, 0.26375467, 0.26449442, 0.26523402, 0.26597348,
+ 0.26671275, 0.26745188, 0.26819086, 0.26892966, 0.26966831, 0.27040681, 0.27114516, 0.27188334,
+ 0.27262136, 0.27335921, 0.27409691, 0.27483445, 0.27557182, 0.27630904, 0.27704608, 0.27778298,
+ 0.27851969, 0.27925625, 0.27999264, 0.28072888, 0.28146493, 0.28220084, 0.28293657, 0.28367212,
+ 0.28440753, 0.28514278, 0.28587782, 0.28661272, 0.28734747, 0.28808203, 0.28881642, 0.28955063,
+ 0.29028466, 0.29101855, 0.29175225, 0.29248580, 0.29321915, 0.29395235, 0.29468536, 0.29541820,
+ 0.29615089, 0.29688337, 0.29761571, 0.29834786, 0.29907984, 0.29981163, 0.30054325, 0.30127469,
+ 0.30200595, 0.30273703, 0.30346796, 0.30419868, 0.30492923, 0.30565959, 0.30638981, 0.30711982,
+ 0.30784965, 0.30857930, 0.30930877, 0.31003806, 0.31076714, 0.31149608, 0.31222481, 0.31295338,
+ 0.31368175, 0.31440994, 0.31513792, 0.31586576, 0.31659338, 0.31732082, 0.31804809, 0.31877515,
+ 0.31950203, 0.32022873, 0.32095525, 0.32168156, 0.32240769, 0.32313362, 0.32385936, 0.32458493,
+ 0.32531029, 0.32603547, 0.32676044, 0.32748523, 0.32820985, 0.32893425, 0.32965845, 0.33038250,
+ 0.33110631, 0.33182994, 0.33255336, 0.33327660, 0.33399966, 0.33472249, 0.33544514, 0.33616760,
+ 0.33688986, 0.33761191, 0.33833376, 0.33905542, 0.33977687, 0.34049815, 0.34121922, 0.34194008,
+ 0.34266073, 0.34338117, 0.34410143, 0.34482148, 0.34554133, 0.34626096, 0.34698042, 0.34769964,
+ 0.34841868, 0.34913751, 0.34985614, 0.35057455, 0.35129276, 0.35201076, 0.35272855, 0.35344616,
+ 0.35416353, 0.35488069, 0.35559767, 0.35631442, 0.35703096, 0.35774729, 0.35846341, 0.35917935,
+ 0.35989505, 0.36061051, 0.36132580, 0.36204088, 0.36275572, 0.36347038, 0.36418480, 0.36489901,
+ 0.36561298, 0.36632678, 0.36704034, 0.36775368, 0.36846682, 0.36917976, 0.36989245, 0.37060493,
+ 0.37131721, 0.37202924, 0.37274107, 0.37345266, 0.37416407, 0.37487522, 0.37558618, 0.37629691,
+ 0.37700742, 0.37771770, 0.37842774, 0.37913761, 0.37984720, 0.38055661, 0.38126576, 0.38197473,
+ 0.38268343, 0.38339192, 0.38410020, 0.38480824, 0.38551605, 0.38622364, 0.38693100, 0.38763815,
+ 0.38834503, 0.38905174, 0.38975817, 0.39046440, 0.39117038, 0.39187613, 0.39258167, 0.39328697,
+ 0.39399204, 0.39469686, 0.39540148, 0.39610586, 0.39681000, 0.39751390, 0.39821756, 0.39892101,
+ 0.39962420, 0.40032718, 0.40102988, 0.40173239, 0.40243465, 0.40313667, 0.40383846, 0.40454000,
+ 0.40524131, 0.40594238, 0.40664321, 0.40734380, 0.40804416, 0.40874428, 0.40944415, 0.41014379,
+ 0.41084316, 0.41154233, 0.41224122, 0.41293988, 0.41363832, 0.41433650, 0.41503441, 0.41573212,
+ 0.41642955, 0.41712677, 0.41782370, 0.41852042, 0.41921690, 0.41991311, 0.42060909, 0.42130479,
+ 0.42200026, 0.42269549, 0.42339048, 0.42408520, 0.42477968, 0.42547390, 0.42616788, 0.42686161,
+ 0.42755508, 0.42824832, 0.42894128, 0.42963400, 0.43032649, 0.43101871, 0.43171066, 0.43240237,
+ 0.43309382, 0.43378502, 0.43447596, 0.43516666, 0.43585709, 0.43654725, 0.43723717, 0.43792683,
+ 0.43861625, 0.43930539, 0.43999428, 0.44068289, 0.44137126, 0.44205937, 0.44274724, 0.44343480,
+ 0.44412214, 0.44480920, 0.44549602, 0.44618255, 0.44686884, 0.44755486, 0.44824061, 0.44892609,
+ 0.44961134, 0.45029628, 0.45098099, 0.45166543, 0.45234957, 0.45303348, 0.45371711, 0.45440048,
+ 0.45508358, 0.45576641, 0.45644897, 0.45713127, 0.45781329, 0.45849505, 0.45917654, 0.45985776,
+ 0.46053872, 0.46121940, 0.46189979, 0.46257994, 0.46325979, 0.46393937, 0.46461868, 0.46529773,
+ 0.46597651, 0.46665499, 0.46733320, 0.46801114, 0.46868882, 0.46936622, 0.47004333, 0.47072017,
+ 0.47139674, 0.47207302, 0.47274902, 0.47342476, 0.47410020, 0.47477537, 0.47545028, 0.47612488,
+ 0.47679922, 0.47747329, 0.47814706, 0.47882056, 0.47949377, 0.48016667, 0.48083934, 0.48151168,
+ 0.48218378, 0.48285556, 0.48352706, 0.48419830, 0.48486924, 0.48553991, 0.48621029, 0.48688036,
+ 0.48755017, 0.48821968, 0.48888889, 0.48955783, 0.49022648, 0.49089485, 0.49156290, 0.49223071,
+ 0.49289820, 0.49356541, 0.49423230, 0.49489895, 0.49556527, 0.49623129, 0.49689704, 0.49756250,
+ 0.49822766, 0.49889255, 0.49955711, 0.50022137, 0.50088537, 0.50154907, 0.50221246, 0.50287557,
+ 0.50353837, 0.50420088, 0.50486308, 0.50552505, 0.50618666, 0.50684798, 0.50750899, 0.50816971,
+ 0.50883013, 0.50949025, 0.51015007, 0.51080960, 0.51146883, 0.51212776, 0.51278639, 0.51344472,
+ 0.51410276, 0.51476043, 0.51541787, 0.51607502, 0.51673180, 0.51738828, 0.51804453, 0.51870042,
+ 0.51935601, 0.52001125, 0.52066624, 0.52132094, 0.52197528, 0.52262938, 0.52328312, 0.52393657,
+ 0.52458966, 0.52524251, 0.52589500, 0.52654725, 0.52719915, 0.52785075, 0.52850199, 0.52915299,
+ 0.52980363, 0.53045398, 0.53110403, 0.53175372, 0.53240311, 0.53305221, 0.53370100, 0.53434944,
+ 0.53499764, 0.53564548, 0.53629297, 0.53694016, 0.53758705, 0.53823364, 0.53887993, 0.53952587,
+ 0.54017144, 0.54081678, 0.54146177, 0.54210645, 0.54275078, 0.54339480, 0.54403853, 0.54468191,
+ 0.54532498, 0.54596776, 0.54661018, 0.54725230, 0.54789406, 0.54853553, 0.54917663, 0.54981750,
+ 0.55045795, 0.55109817, 0.55173796, 0.55237752, 0.55301672, 0.55365556, 0.55429411, 0.55493236,
+ 0.55557024, 0.55620778, 0.55684501, 0.55748194, 0.55811852, 0.55875480, 0.55939072, 0.56002629,
+ 0.56066155, 0.56129652, 0.56193113, 0.56256539, 0.56319934, 0.56383294, 0.56446624, 0.56509918,
+ 0.56573182, 0.56636411, 0.56699604, 0.56762767, 0.56825894, 0.56888992, 0.56952053, 0.57015079,
+ 0.57078075, 0.57141036, 0.57203960, 0.57266855, 0.57329714, 0.57392544, 0.57455337, 0.57518095,
+ 0.57580817, 0.57643509, 0.57706165, 0.57768792, 0.57831377, 0.57893932, 0.57956457, 0.58018941,
+ 0.58081394, 0.58143812, 0.58206201, 0.58268547, 0.58330864, 0.58393145, 0.58455396, 0.58517605,
+ 0.58579785, 0.58641928, 0.58704036, 0.58766115, 0.58828157, 0.58890158, 0.58952129, 0.59014070,
+ 0.59075969, 0.59137839, 0.59199667, 0.59261465, 0.59323227, 0.59384960, 0.59446651, 0.59508306,
+ 0.59569931, 0.59631521, 0.59693068, 0.59754586, 0.59816068, 0.59877521, 0.59938931, 0.60000306,
+ 0.60061646, 0.60122955, 0.60184222, 0.60245460, 0.60306662, 0.60367823, 0.60428953, 0.60490048,
+ 0.60551107, 0.60612124, 0.60673112, 0.60734063, 0.60794979, 0.60855860, 0.60916704, 0.60977507,
+ 0.61038280, 0.61099017, 0.61159718, 0.61220378, 0.61281008, 0.61341602, 0.61402154, 0.61462677,
+ 0.61523157, 0.61583608, 0.61644018, 0.61704391, 0.61764729, 0.61825031, 0.61885297, 0.61945528,
+ 0.62005723, 0.62065876, 0.62125999, 0.62186080, 0.62246126, 0.62306136, 0.62366110, 0.62426049,
+ 0.62485951, 0.62545812, 0.62605637, 0.62665427, 0.62725180, 0.62784898, 0.62844574, 0.62904221,
+ 0.62963825, 0.63023394, 0.63082922, 0.63142419, 0.63201874, 0.63261294, 0.63320678, 0.63380021,
+ 0.63439327, 0.63498598, 0.63557833, 0.63617027, 0.63676184, 0.63735306, 0.63794392, 0.63853437,
+ 0.63912445, 0.63971418, 0.64030349, 0.64089245, 0.64148104, 0.64206922, 0.64265704, 0.64324450,
+ 0.64383155, 0.64441824, 0.64500451, 0.64559048, 0.64617604, 0.64676118, 0.64734596, 0.64793038,
+ 0.64851439, 0.64909804, 0.64968133, 0.65026420, 0.65084666, 0.65142882, 0.65201056, 0.65259188,
+ 0.65317285, 0.65375340, 0.65433359, 0.65491343, 0.65549284, 0.65607190, 0.65665054, 0.65722883,
+ 0.65780669, 0.65838420, 0.65896130, 0.65953803, 0.66011435, 0.66069031, 0.66126585, 0.66184098,
+ 0.66241580, 0.66299015, 0.66356415, 0.66413778, 0.66471100, 0.66528380, 0.66585624, 0.66642827,
+ 0.66699994, 0.66757119, 0.66814202, 0.66871250, 0.66928262, 0.66985226, 0.67042154, 0.67099047,
+ 0.67155898, 0.67212707, 0.67269474, 0.67326206, 0.67382902, 0.67439550, 0.67496163, 0.67552739,
+ 0.67609268, 0.67665762, 0.67722219, 0.67778629, 0.67835003, 0.67891335, 0.67947632, 0.68003887,
+ 0.68060100, 0.68116271, 0.68172407, 0.68228501, 0.68284553, 0.68340570, 0.68396538, 0.68452471,
+ 0.68508369, 0.68564218, 0.68620032, 0.68675804, 0.68731534, 0.68787223, 0.68842876, 0.68898487,
+ 0.68954057, 0.69009584, 0.69065070, 0.69120520, 0.69175923, 0.69231290, 0.69286615, 0.69341904,
+ 0.69397146, 0.69452351, 0.69507509, 0.69562632, 0.69617712, 0.69672751, 0.69727749, 0.69782710,
+ 0.69837624, 0.69892502, 0.69947332, 0.70002127, 0.70056880, 0.70111591, 0.70166260, 0.70220888,
+ 0.70275474, 0.70330018, 0.70384526, 0.70438987, 0.70493406, 0.70547789, 0.70602125, 0.70656425,
+ 0.70710677, 0.70764893, 0.70819062, 0.70873195, 0.70927280, 0.70981330, 0.71035337, 0.71089298,
+ 0.71143222, 0.71197098, 0.71250939, 0.71304733, 0.71358484, 0.71412200, 0.71465868, 0.71519494,
+ 0.71573085, 0.71626627, 0.71680129, 0.71733588, 0.71787006, 0.71840382, 0.71893710, 0.71947002,
+ 0.72000253, 0.72053456, 0.72106618, 0.72159743, 0.72212821, 0.72265857, 0.72318846, 0.72371799,
+ 0.72424710, 0.72477573, 0.72530395, 0.72583181, 0.72635913, 0.72688609, 0.72741264, 0.72793871,
+ 0.72846437, 0.72898960, 0.72951442, 0.73003882, 0.73056275, 0.73108631, 0.73160940, 0.73213202,
+ 0.73265427, 0.73317605, 0.73369741, 0.73421836, 0.73473889, 0.73525894, 0.73577857, 0.73629779,
+ 0.73681659, 0.73733491, 0.73785281, 0.73837030, 0.73888731, 0.73940390, 0.73992008, 0.74043584,
+ 0.74095112, 0.74146599, 0.74198043, 0.74249440, 0.74300796, 0.74352109, 0.74403375, 0.74454600,
+ 0.74505776, 0.74556917, 0.74608010, 0.74659055, 0.74710059, 0.74761021, 0.74811935, 0.74862808,
+ 0.74913639, 0.74964422, 0.75015163, 0.75065863, 0.75116515, 0.75167120, 0.75217682, 0.75268203,
+ 0.75318682, 0.75369114, 0.75419497, 0.75469840, 0.75520140, 0.75570393, 0.75620598, 0.75670767,
+ 0.75720882, 0.75770962, 0.75820988, 0.75870979, 0.75920922, 0.75970817, 0.76020670, 0.76070476,
+ 0.76120239, 0.76169956, 0.76219630, 0.76269257, 0.76318842, 0.76368380, 0.76417875, 0.76467323,
+ 0.76516724, 0.76566088, 0.76615399, 0.76664668, 0.76713890, 0.76763070, 0.76812202, 0.76861292,
+ 0.76910335, 0.76959330, 0.77008283, 0.77057189, 0.77106053, 0.77154869, 0.77203637, 0.77252364,
+ 0.77301043, 0.77349681, 0.77398270, 0.77446812, 0.77495313, 0.77543765, 0.77592170, 0.77640533,
+ 0.77688849, 0.77737117, 0.77785343, 0.77833521, 0.77881652, 0.77929735, 0.77977777, 0.78025776,
+ 0.78073722, 0.78121626, 0.78169483, 0.78217292, 0.78265059, 0.78312778, 0.78360450, 0.78408080,
+ 0.78455657, 0.78503191, 0.78550684, 0.78598124, 0.78645521, 0.78692871, 0.78740174, 0.78787434,
+ 0.78834641, 0.78881806, 0.78928924, 0.78975999, 0.79023021, 0.79070002, 0.79116935, 0.79163820,
+ 0.79210657, 0.79257452, 0.79304194, 0.79350895, 0.79397547, 0.79444152, 0.79490715, 0.79537225,
+ 0.79583693, 0.79630107, 0.79676479, 0.79722804, 0.79769087, 0.79815316, 0.79861498, 0.79907638,
+ 0.79953724, 0.79999769, 0.80045766, 0.80091715, 0.80137616, 0.80183470, 0.80229282, 0.80275041,
+ 0.80320752, 0.80366421, 0.80412036, 0.80457610, 0.80503136, 0.80548608, 0.80594039, 0.80639422,
+ 0.80684757, 0.80730045, 0.80775285, 0.80820471, 0.80865616, 0.80910712, 0.80955762, 0.81000763,
+ 0.81045717, 0.81090623, 0.81135488, 0.81180298, 0.81225061, 0.81269777, 0.81314439, 0.81359059,
+ 0.81403631, 0.81448156, 0.81492633, 0.81537062, 0.81581444, 0.81625772, 0.81670058, 0.81714290,
+ 0.81758481, 0.81802619, 0.81846714, 0.81890756, 0.81934750, 0.81978697, 0.82022595, 0.82066447,
+ 0.82110250, 0.82154006, 0.82197714, 0.82241368, 0.82284981, 0.82328540, 0.82372051, 0.82415515,
+ 0.82458931, 0.82502300, 0.82545614, 0.82588887, 0.82632107, 0.82675278, 0.82718402, 0.82761478,
+ 0.82804507, 0.82847482, 0.82890409, 0.82933295, 0.82976121, 0.83018905, 0.83061641, 0.83104324,
+ 0.83146960, 0.83189547, 0.83232087, 0.83274579, 0.83317018, 0.83359408, 0.83401752, 0.83444041,
+ 0.83486289, 0.83528483, 0.83570629, 0.83612728, 0.83654773, 0.83696771, 0.83738720, 0.83780622,
+ 0.83822471, 0.83864272, 0.83906025, 0.83947724, 0.83989382, 0.84030986, 0.84072536, 0.84114045,
+ 0.84155500, 0.84196901, 0.84238261, 0.84279567, 0.84320825, 0.84362030, 0.84403187, 0.84444296,
+ 0.84485358, 0.84526366, 0.84567326, 0.84608233, 0.84649092, 0.84689903, 0.84730661, 0.84771377,
+ 0.84812033, 0.84852648, 0.84893203, 0.84933716, 0.84974176, 0.85014588, 0.85054946, 0.85095257,
+ 0.85135520, 0.85175729, 0.85215890, 0.85255998, 0.85296059, 0.85336071, 0.85376030, 0.85415941,
+ 0.85455799, 0.85495609, 0.85535365, 0.85575074, 0.85614735, 0.85654342, 0.85693896, 0.85733402,
+ 0.85772860, 0.85812265, 0.85851622, 0.85890925, 0.85930181, 0.85969388, 0.86008537, 0.86047643,
+ 0.86086696, 0.86125696, 0.86164647, 0.86203545, 0.86242396, 0.86281192, 0.86319941, 0.86358637,
+ 0.86397284, 0.86435878, 0.86474425, 0.86512917, 0.86551362, 0.86589754, 0.86628097, 0.86666387,
+ 0.86704624, 0.86742812, 0.86780947, 0.86819035, 0.86857069, 0.86895055, 0.86932987, 0.86970866,
+ 0.87008697, 0.87046480, 0.87084204, 0.87121886, 0.87159508, 0.87197083, 0.87234604, 0.87272078,
+ 0.87309498, 0.87346870, 0.87384182, 0.87421453, 0.87458664, 0.87495828, 0.87532938, 0.87570000,
+ 0.87607008, 0.87643969, 0.87680870, 0.87717724, 0.87754530, 0.87791282, 0.87827981, 0.87864625,
+ 0.87901223, 0.87937766, 0.87974262, 0.88010699, 0.88047087, 0.88083428, 0.88119709, 0.88155943,
+ 0.88192129, 0.88228256, 0.88264334, 0.88300359, 0.88336337, 0.88372254, 0.88408124, 0.88443947,
+ 0.88479710, 0.88515425, 0.88551086, 0.88586694, 0.88622254, 0.88657761, 0.88693213, 0.88728613,
+ 0.88763964, 0.88799256, 0.88834506, 0.88869697, 0.88904834, 0.88939923, 0.88974959, 0.89009941,
+ 0.89044875, 0.89079750, 0.89114577, 0.89149350, 0.89184070, 0.89218742, 0.89253354, 0.89287919,
+ 0.89322430, 0.89356887, 0.89391297, 0.89425647, 0.89459950, 0.89494199, 0.89528394, 0.89562535,
+ 0.89596623, 0.89630663, 0.89664650, 0.89698577, 0.89732456, 0.89766282, 0.89800060, 0.89833778,
+ 0.89867449, 0.89901060, 0.89934623, 0.89968133, 0.90001589, 0.90034992, 0.90068340, 0.90101641,
+ 0.90134883, 0.90168077, 0.90201217, 0.90234298, 0.90267330, 0.90300310, 0.90333235, 0.90366107,
+ 0.90398932, 0.90431696, 0.90464407, 0.90497071, 0.90529674, 0.90562230, 0.90594727, 0.90627176,
+ 0.90659571, 0.90691912, 0.90724200, 0.90756434, 0.90788609, 0.90820736, 0.90852809, 0.90884835,
+ 0.90916800, 0.90948713, 0.90980572, 0.91012377, 0.91044128, 0.91075826, 0.91107476, 0.91139066,
+ 0.91170603, 0.91202086, 0.91233516, 0.91264898, 0.91296220, 0.91327488, 0.91358703, 0.91389865,
+ 0.91420978, 0.91452032, 0.91483033, 0.91513979, 0.91544873, 0.91575712, 0.91606498, 0.91637230,
+ 0.91667908, 0.91698527, 0.91729099, 0.91759616, 0.91790080, 0.91820484, 0.91850841, 0.91881138,
+ 0.91911387, 0.91941577, 0.91971713, 0.92001796, 0.92031831, 0.92061806, 0.92091721, 0.92121589,
+ 0.92151403, 0.92181164, 0.92210865, 0.92240518, 0.92270112, 0.92299652, 0.92329144, 0.92358577,
+ 0.92387950, 0.92417276, 0.92446548, 0.92475760, 0.92504925, 0.92534029, 0.92563081, 0.92592078,
+ 0.92621022, 0.92649913, 0.92678750, 0.92707527, 0.92736250, 0.92764926, 0.92793542, 0.92822099,
+ 0.92850608, 0.92879063, 0.92907459, 0.92935801, 0.92964089, 0.92992324, 0.93020505, 0.93048626,
+ 0.93076694, 0.93104708, 0.93132669, 0.93160576, 0.93188429, 0.93216223, 0.93243963, 0.93271649,
+ 0.93299282, 0.93326855, 0.93354380, 0.93381846, 0.93409252, 0.93436611, 0.93463916, 0.93491161,
+ 0.93518353, 0.93545485, 0.93572569, 0.93599594, 0.93626565, 0.93653482, 0.93680346, 0.93707150,
+ 0.93733901, 0.93760598, 0.93787235, 0.93813825, 0.93840355, 0.93866831, 0.93893248, 0.93919611,
+ 0.93945920, 0.93972176, 0.93998373, 0.94024521, 0.94050604, 0.94076639, 0.94102615, 0.94128537,
+ 0.94154406, 0.94180220, 0.94205976, 0.94231677, 0.94257319, 0.94282907, 0.94308442, 0.94333923,
+ 0.94359344, 0.94384712, 0.94410026, 0.94435281, 0.94460481, 0.94485629, 0.94510722, 0.94535756,
+ 0.94560730, 0.94585657, 0.94610524, 0.94635338, 0.94660091, 0.94684792, 0.94709438, 0.94734025,
+ 0.94758558, 0.94783038, 0.94807458, 0.94831824, 0.94856137, 0.94880390, 0.94904590, 0.94928730,
+ 0.94952816, 0.94976848, 0.95000827, 0.95024747, 0.95048606, 0.95072412, 0.95096165, 0.95119864,
+ 0.95143503, 0.95167089, 0.95190614, 0.95214087, 0.95237499, 0.95260859, 0.95284164, 0.95307410,
+ 0.95330602, 0.95353740, 0.95376819, 0.95399845, 0.95422810, 0.95445722, 0.95468575, 0.95491374,
+ 0.95514119, 0.95536804, 0.95559436, 0.95582008, 0.95604527, 0.95626986, 0.95649391, 0.95671743,
+ 0.95694035, 0.95716268, 0.95738453, 0.95760572, 0.95782644, 0.95804650, 0.95826608, 0.95848507,
+ 0.95870346, 0.95892131, 0.95913863, 0.95935535, 0.95957154, 0.95978713, 0.96000212, 0.96021664,
+ 0.96043050, 0.96064389, 0.96085662, 0.96106887, 0.96128047, 0.96149158, 0.96170205, 0.96191204,
+ 0.96212143, 0.96233022, 0.96253848, 0.96274614, 0.96295327, 0.96315980, 0.96336579, 0.96357119,
+ 0.96377605, 0.96398038, 0.96418405, 0.96438724, 0.96458977, 0.96479183, 0.96499324, 0.96519411,
+ 0.96539444, 0.96559417, 0.96579337, 0.96599197, 0.96618998, 0.96638745, 0.96658438, 0.96678072,
+ 0.96697646, 0.96717167, 0.96736628, 0.96756035, 0.96775383, 0.96794677, 0.96813911, 0.96833086,
+ 0.96852207, 0.96871275, 0.96890283, 0.96909231, 0.96928126, 0.96946961, 0.96965736, 0.96984458,
+ 0.97003126, 0.97021735, 0.97040284, 0.97058779, 0.97077215, 0.97095591, 0.97113913, 0.97132182,
+ 0.97150391, 0.97168541, 0.97186631, 0.97204673, 0.97222650, 0.97240573, 0.97258437, 0.97276247,
+ 0.97293997, 0.97311687, 0.97329324, 0.97346902, 0.97364426, 0.97381890, 0.97399294, 0.97416645,
+ 0.97433937, 0.97451174, 0.97468352, 0.97485471, 0.97502536, 0.97519541, 0.97536486, 0.97553378,
+ 0.97570211, 0.97586989, 0.97603709, 0.97620368, 0.97636974, 0.97653520, 0.97670007, 0.97686440,
+ 0.97702813, 0.97719133, 0.97735387, 0.97751594, 0.97767735, 0.97783822, 0.97799850, 0.97815824,
+ 0.97831738, 0.97847593, 0.97863394, 0.97879136, 0.97894818, 0.97910446, 0.97926015, 0.97941524,
+ 0.97956979, 0.97972375, 0.97987711, 0.98002988, 0.98018211, 0.98033381, 0.98048484, 0.98063534,
+ 0.98078525, 0.98093462, 0.98108339, 0.98123157, 0.98137921, 0.98152626, 0.98167270, 0.98181856,
+ 0.98196387, 0.98210859, 0.98225272, 0.98239630, 0.98253930, 0.98268169, 0.98282355, 0.98296481,
+ 0.98310548, 0.98324561, 0.98338509, 0.98352402, 0.98366243, 0.98380023, 0.98393744, 0.98407406,
+ 0.98421007, 0.98434556, 0.98448044, 0.98461479, 0.98474848, 0.98488164, 0.98501426, 0.98514622,
+ 0.98527765, 0.98540848, 0.98553872, 0.98566842, 0.98579752, 0.98592603, 0.98605394, 0.98618132,
+ 0.98630810, 0.98643428, 0.98655993, 0.98668492, 0.98680937, 0.98693329, 0.98705655, 0.98717928,
+ 0.98730141, 0.98742294, 0.98754394, 0.98766434, 0.98778415, 0.98790336, 0.98802203, 0.98814011,
+ 0.98825759, 0.98837447, 0.98849082, 0.98860651, 0.98872167, 0.98883629, 0.98895025, 0.98906368,
+ 0.98917651, 0.98928875, 0.98940045, 0.98951149, 0.98962200, 0.98973197, 0.98984128, 0.98995006,
+ 0.99005818, 0.99016583, 0.99027282, 0.99037921, 0.99048507, 0.99059033, 0.99069500, 0.99079913,
+ 0.99090266, 0.99100554, 0.99110794, 0.99120969, 0.99131083, 0.99141145, 0.99151146, 0.99161088,
+ 0.99170977, 0.99180800, 0.99190569, 0.99200279, 0.99209929, 0.99219525, 0.99229062, 0.99238533,
+ 0.99247956, 0.99257314, 0.99266613, 0.99275857, 0.99285042, 0.99294168, 0.99303234, 0.99312246,
+ 0.99321193, 0.99330086, 0.99338919, 0.99347699, 0.99356413, 0.99365073, 0.99373674, 0.99382216,
+ 0.99390697, 0.99399120, 0.99407488, 0.99415797, 0.99424046, 0.99432236, 0.99440366, 0.99448442,
+ 0.99456459, 0.99464417, 0.99472314, 0.99480152, 0.99487931, 0.99495655, 0.99503320, 0.99510926,
+ 0.99518472, 0.99525958, 0.99533391, 0.99540764, 0.99548078, 0.99555331, 0.99562526, 0.99569660,
+ 0.99576741, 0.99583763, 0.99590725, 0.99597627, 0.99604470, 0.99611259, 0.99617982, 0.99624652,
+ 0.99631262, 0.99637812, 0.99644303, 0.99650741, 0.99657112, 0.99663430, 0.99669689, 0.99675888,
+ 0.99682027, 0.99688113, 0.99694133, 0.99700099, 0.99706006, 0.99711853, 0.99717641, 0.99723375,
+ 0.99729043, 0.99734658, 0.99740213, 0.99745709, 0.99751145, 0.99756521, 0.99761844, 0.99767107,
+ 0.99772304, 0.99777448, 0.99782532, 0.99787563, 0.99792528, 0.99797440, 0.99802285, 0.99807078,
+ 0.99811810, 0.99816483, 0.99821103, 0.99825656, 0.99830157, 0.99834591, 0.99838972, 0.99843293,
+ 0.99847555, 0.99851763, 0.99855906, 0.99859995, 0.99864024, 0.99867994, 0.99871904, 0.99875754,
+ 0.99879545, 0.99883282, 0.99886954, 0.99890572, 0.99894130, 0.99897629, 0.99901068, 0.99904448,
+ 0.99907774, 0.99911034, 0.99914241, 0.99917388, 0.99920475, 0.99923503, 0.99926478, 0.99929386,
+ 0.99932235, 0.99935031, 0.99937767, 0.99940443, 0.99943060, 0.99945617, 0.99948120, 0.99950558,
+ 0.99952942, 0.99955267, 0.99957532, 0.99959737, 0.99961883, 0.99963969, 0.99966002, 0.99967968,
+ 0.99969882, 0.99971735, 0.99973530, 0.99975264, 0.99976939, 0.99978560, 0.99980116, 0.99981618,
+ 0.99983060, 0.99984443, 0.99985766, 0.99987030, 0.99988234, 0.99989384, 0.99990469, 0.99991500,
+ 0.99992472, 0.99993384, 0.99994236, 0.99995029, 0.99995762, 0.99996442, 0.99997061, 0.99997616,
+ 0.99998116, 0.99998558, 0.99998939, 0.99999267, 0.99999529, 0.99999738, 0.99999881, 0.99999970,
+ 1.00000000, 0.99999970, 0.99999881, 0.99999738, 0.99999529, 0.99999267, 0.99998939, 0.99998558,
+ 0.99998116, 0.99997616, 0.99997061, 0.99996442, 0.99995762, 0.99995029, 0.99994236, 0.99993384,
+ 0.99992472, 0.99991500, 0.99990469, 0.99989384, 0.99988234, 0.99987030, 0.99985766, 0.99984443,
+ 0.99983060, 0.99981618, 0.99980116, 0.99978560, 0.99976939, 0.99975264, 0.99973530, 0.99971735,
+ 0.99969882, 0.99967968, 0.99966002, 0.99963969, 0.99961883, 0.99959737, 0.99957532, 0.99955267,
+ 0.99952942, 0.99950558, 0.99948120, 0.99945617, 0.99943060, 0.99940443, 0.99937767, 0.99935031,
+ 0.99932235, 0.99929386, 0.99926478, 0.99923503, 0.99920475, 0.99917388, 0.99914241, 0.99911034,
+ 0.99907774, 0.99904448, 0.99901068, 0.99897629, 0.99894130, 0.99890572, 0.99886954, 0.99883282,
+ 0.99879545, 0.99875754, 0.99871904, 0.99867994, 0.99864024, 0.99859995, 0.99855906, 0.99851763,
+ 0.99847555, 0.99843293, 0.99838972, 0.99834591, 0.99830157, 0.99825656, 0.99821103, 0.99816483,
+ 0.99811810, 0.99807078, 0.99802285, 0.99797440, 0.99792528, 0.99787563, 0.99782532, 0.99777448,
+ 0.99772304, 0.99767107, 0.99761844, 0.99756521, 0.99751145, 0.99745709, 0.99740213, 0.99734658,
+ 0.99729043, 0.99723375, 0.99717641, 0.99711853, 0.99706006, 0.99700099, 0.99694133, 0.99688113,
+ 0.99682027, 0.99675888, 0.99669689, 0.99663430, 0.99657112, 0.99650741, 0.99644303, 0.99637812,
+ 0.99631262, 0.99624652, 0.99617982, 0.99611259, 0.99604470, 0.99597627, 0.99590725, 0.99583763,
+ 0.99576741, 0.99569660, 0.99562526, 0.99555331, 0.99548078, 0.99540764, 0.99533391, 0.99525958,
+ 0.99518472, 0.99510926, 0.99503320, 0.99495655, 0.99487931, 0.99480152, 0.99472314, 0.99464417,
+ 0.99456459, 0.99448442, 0.99440366, 0.99432236, 0.99424046, 0.99415797, 0.99407488, 0.99399120,
+ 0.99390697, 0.99382216, 0.99373674, 0.99365073, 0.99356413, 0.99347699, 0.99338919, 0.99330086,
+ 0.99321193, 0.99312246, 0.99303234, 0.99294168, 0.99285042, 0.99275857, 0.99266613, 0.99257314,
+ 0.99247956, 0.99238533, 0.99229062, 0.99219525, 0.99209929, 0.99200279, 0.99190569, 0.99180800,
+ 0.99170977, 0.99161088, 0.99151146, 0.99141145, 0.99131083, 0.99120969, 0.99110794, 0.99100554,
+ 0.99090266, 0.99079913, 0.99069500, 0.99059033, 0.99048507, 0.99037921, 0.99027282, 0.99016583,
+ 0.99005818, 0.98995006, 0.98984128, 0.98973197, 0.98962200, 0.98951149, 0.98940045, 0.98928875,
+ 0.98917651, 0.98906368, 0.98895025, 0.98883629, 0.98872167, 0.98860651, 0.98849082, 0.98837447,
+ 0.98825759, 0.98814011, 0.98802203, 0.98790336, 0.98778415, 0.98766434, 0.98754394, 0.98742294,
+ 0.98730141, 0.98717928, 0.98705655, 0.98693329, 0.98680937, 0.98668492, 0.98655993, 0.98643428,
+ 0.98630810, 0.98618132, 0.98605394, 0.98592603, 0.98579752, 0.98566842, 0.98553872, 0.98540848,
+ 0.98527765, 0.98514622, 0.98501426, 0.98488164, 0.98474848, 0.98461479, 0.98448044, 0.98434556,
+ 0.98421007, 0.98407406, 0.98393744, 0.98380023, 0.98366243, 0.98352402, 0.98338509, 0.98324561,
+ 0.98310548, 0.98296481, 0.98282355, 0.98268169, 0.98253930, 0.98239630, 0.98225272, 0.98210859,
+ 0.98196387, 0.98181856, 0.98167270, 0.98152626, 0.98137921, 0.98123157, 0.98108339, 0.98093462,
+ 0.98078525, 0.98063534, 0.98048484, 0.98033381, 0.98018211, 0.98002988, 0.97987711, 0.97972375,
+ 0.97956979, 0.97941524, 0.97926015, 0.97910446, 0.97894818, 0.97879136, 0.97863394, 0.97847593,
+ 0.97831738, 0.97815824, 0.97799850, 0.97783822, 0.97767735, 0.97751594, 0.97735387, 0.97719133,
+ 0.97702813, 0.97686440, 0.97670007, 0.97653520, 0.97636974, 0.97620368, 0.97603709, 0.97586989,
+ 0.97570211, 0.97553378, 0.97536486, 0.97519541, 0.97502536, 0.97485471, 0.97468352, 0.97451174,
+ 0.97433937, 0.97416645, 0.97399294, 0.97381890, 0.97364426, 0.97346902, 0.97329324, 0.97311687,
+ 0.97293997, 0.97276247, 0.97258437, 0.97240573, 0.97222650, 0.97204673, 0.97186631, 0.97168541,
+ 0.97150391, 0.97132182, 0.97113913, 0.97095591, 0.97077215, 0.97058779, 0.97040284, 0.97021735,
+ 0.97003126, 0.96984458, 0.96965736, 0.96946961, 0.96928126, 0.96909231, 0.96890283, 0.96871275,
+ 0.96852207, 0.96833086, 0.96813911, 0.96794677, 0.96775383, 0.96756035, 0.96736628, 0.96717167,
+ 0.96697646, 0.96678072, 0.96658438, 0.96638745, 0.96618998, 0.96599197, 0.96579337, 0.96559417,
+ 0.96539444, 0.96519411, 0.96499324, 0.96479183, 0.96458977, 0.96438724, 0.96418405, 0.96398038,
+ 0.96377605, 0.96357119, 0.96336579, 0.96315980, 0.96295327, 0.96274614, 0.96253848, 0.96233022,
+ 0.96212143, 0.96191204, 0.96170205, 0.96149158, 0.96128047, 0.96106887, 0.96085662, 0.96064389,
+ 0.96043050, 0.96021664, 0.96000212, 0.95978713, 0.95957154, 0.95935535, 0.95913863, 0.95892131,
+ 0.95870346, 0.95848507, 0.95826608, 0.95804650, 0.95782644, 0.95760572, 0.95738453, 0.95716268,
+ 0.95694035, 0.95671743, 0.95649391, 0.95626986, 0.95604527, 0.95582008, 0.95559436, 0.95536804,
+ 0.95514119, 0.95491374, 0.95468575, 0.95445722, 0.95422810, 0.95399845, 0.95376819, 0.95353740,
+ 0.95330602, 0.95307410, 0.95284164, 0.95260859, 0.95237499, 0.95214087, 0.95190614, 0.95167089,
+ 0.95143503, 0.95119864, 0.95096165, 0.95072412, 0.95048606, 0.95024747, 0.95000827, 0.94976848,
+ 0.94952816, 0.94928730, 0.94904590, 0.94880390, 0.94856137, 0.94831824, 0.94807458, 0.94783038,
+ 0.94758558, 0.94734025, 0.94709438, 0.94684792, 0.94660091, 0.94635338, 0.94610524, 0.94585657,
+ 0.94560730, 0.94535756, 0.94510722, 0.94485629, 0.94460481, 0.94435281, 0.94410026, 0.94384712,
+ 0.94359344, 0.94333923, 0.94308442, 0.94282907, 0.94257319, 0.94231677, 0.94205976, 0.94180220,
+ 0.94154406, 0.94128537, 0.94102615, 0.94076639, 0.94050604, 0.94024521, 0.93998373, 0.93972176,
+ 0.93945920, 0.93919611, 0.93893248, 0.93866831, 0.93840355, 0.93813825, 0.93787235, 0.93760598,
+ 0.93733901, 0.93707150, 0.93680346, 0.93653482, 0.93626565, 0.93599594, 0.93572569, 0.93545485,
+ 0.93518353, 0.93491161, 0.93463916, 0.93436611, 0.93409252, 0.93381846, 0.93354380, 0.93326855,
+ 0.93299282, 0.93271649, 0.93243963, 0.93216223, 0.93188429, 0.93160576, 0.93132669, 0.93104708,
+ 0.93076694, 0.93048626, 0.93020505, 0.92992324, 0.92964089, 0.92935801, 0.92907459, 0.92879063,
+ 0.92850608, 0.92822099, 0.92793542, 0.92764926, 0.92736250, 0.92707527, 0.92678750, 0.92649913,
+ 0.92621022, 0.92592078, 0.92563081, 0.92534029, 0.92504925, 0.92475760, 0.92446548, 0.92417276,
+ 0.92387950, 0.92358577, 0.92329144, 0.92299652, 0.92270112, 0.92240518, 0.92210865, 0.92181164,
+ 0.92151403, 0.92121589, 0.92091721, 0.92061806, 0.92031831, 0.92001796, 0.91971713, 0.91941577,
+ 0.91911387, 0.91881138, 0.91850841, 0.91820484, 0.91790080, 0.91759616, 0.91729099, 0.91698527,
+ 0.91667908, 0.91637230, 0.91606498, 0.91575712, 0.91544873, 0.91513979, 0.91483033, 0.91452032,
+ 0.91420978, 0.91389865, 0.91358703, 0.91327488, 0.91296220, 0.91264898, 0.91233516, 0.91202086,
+ 0.91170603, 0.91139066, 0.91107476, 0.91075826, 0.91044128, 0.91012377, 0.90980572, 0.90948713,
+ 0.90916800, 0.90884835, 0.90852809, 0.90820736, 0.90788609, 0.90756434, 0.90724200, 0.90691912,
+ 0.90659571, 0.90627176, 0.90594727, 0.90562230, 0.90529674, 0.90497071, 0.90464407, 0.90431696,
+ 0.90398932, 0.90366107, 0.90333235, 0.90300310, 0.90267330, 0.90234298, 0.90201217, 0.90168077,
+ 0.90134883, 0.90101641, 0.90068340, 0.90034992, 0.90001589, 0.89968133, 0.89934623, 0.89901060,
+ 0.89867449, 0.89833778, 0.89800060, 0.89766282, 0.89732456, 0.89698577, 0.89664650, 0.89630663,
+ 0.89596623, 0.89562535, 0.89528394, 0.89494199, 0.89459950, 0.89425647, 0.89391297, 0.89356887,
+ 0.89322430, 0.89287919, 0.89253354, 0.89218742, 0.89184070, 0.89149350, 0.89114577, 0.89079750,
+ 0.89044875, 0.89009941, 0.88974959, 0.88939923, 0.88904834, 0.88869697, 0.88834506, 0.88799256,
+ 0.88763964, 0.88728613, 0.88693213, 0.88657761, 0.88622254, 0.88586694, 0.88551086, 0.88515425,
+ 0.88479710, 0.88443947, 0.88408124, 0.88372254, 0.88336337, 0.88300359, 0.88264334, 0.88228256,
+ 0.88192129, 0.88155943, 0.88119709, 0.88083428, 0.88047087, 0.88010699, 0.87974262, 0.87937766,
+ 0.87901223, 0.87864625, 0.87827981, 0.87791282, 0.87754530, 0.87717724, 0.87680870, 0.87643969,
+ 0.87607008, 0.87570000, 0.87532938, 0.87495828, 0.87458664, 0.87421453, 0.87384182, 0.87346870,
+ 0.87309498, 0.87272078, 0.87234604, 0.87197083, 0.87159508, 0.87121886, 0.87084204, 0.87046480,
+ 0.87008697, 0.86970866, 0.86932987, 0.86895055, 0.86857069, 0.86819035, 0.86780947, 0.86742812,
+ 0.86704624, 0.86666387, 0.86628097, 0.86589754, 0.86551362, 0.86512917, 0.86474425, 0.86435878,
+ 0.86397284, 0.86358637, 0.86319941, 0.86281192, 0.86242396, 0.86203545, 0.86164647, 0.86125696,
+ 0.86086696, 0.86047643, 0.86008537, 0.85969388, 0.85930181, 0.85890925, 0.85851622, 0.85812265,
+ 0.85772860, 0.85733402, 0.85693896, 0.85654342, 0.85614735, 0.85575074, 0.85535365, 0.85495609,
+ 0.85455799, 0.85415941, 0.85376030, 0.85336071, 0.85296059, 0.85255998, 0.85215890, 0.85175729,
+ 0.85135520, 0.85095257, 0.85054946, 0.85014588, 0.84974176, 0.84933716, 0.84893203, 0.84852648,
+ 0.84812033, 0.84771377, 0.84730661, 0.84689903, 0.84649092, 0.84608233, 0.84567326, 0.84526366,
+ 0.84485358, 0.84444296, 0.84403187, 0.84362030, 0.84320825, 0.84279567, 0.84238261, 0.84196901,
+ 0.84155500, 0.84114045, 0.84072536, 0.84030986, 0.83989382, 0.83947724, 0.83906025, 0.83864272,
+ 0.83822471, 0.83780622, 0.83738720, 0.83696771, 0.83654773, 0.83612728, 0.83570629, 0.83528483,
+ 0.83486289, 0.83444041, 0.83401752, 0.83359408, 0.83317018, 0.83274579, 0.83232087, 0.83189547,
+ 0.83146960, 0.83104324, 0.83061641, 0.83018905, 0.82976121, 0.82933295, 0.82890409, 0.82847482,
+ 0.82804507, 0.82761478, 0.82718402, 0.82675278, 0.82632107, 0.82588887, 0.82545614, 0.82502300,
+ 0.82458931, 0.82415515, 0.82372051, 0.82328540, 0.82284981, 0.82241368, 0.82197714, 0.82154006,
+ 0.82110250, 0.82066447, 0.82022595, 0.81978697, 0.81934750, 0.81890756, 0.81846714, 0.81802619,
+ 0.81758481, 0.81714290, 0.81670058, 0.81625772, 0.81581444, 0.81537062, 0.81492633, 0.81448156,
+ 0.81403631, 0.81359059, 0.81314439, 0.81269777, 0.81225061, 0.81180298, 0.81135488, 0.81090623,
+ 0.81045717, 0.81000763, 0.80955762, 0.80910712, 0.80865616, 0.80820471, 0.80775285, 0.80730045,
+ 0.80684757, 0.80639422, 0.80594039, 0.80548608, 0.80503136, 0.80457610, 0.80412036, 0.80366421,
+ 0.80320752, 0.80275041, 0.80229282, 0.80183470, 0.80137616, 0.80091715, 0.80045766, 0.79999769,
+ 0.79953724, 0.79907638, 0.79861498, 0.79815316, 0.79769087, 0.79722804, 0.79676479, 0.79630107,
+ 0.79583693, 0.79537225, 0.79490715, 0.79444152, 0.79397547, 0.79350895, 0.79304194, 0.79257452,
+ 0.79210657, 0.79163820, 0.79116935, 0.79070002, 0.79023021, 0.78975999, 0.78928924, 0.78881806,
+ 0.78834641, 0.78787434, 0.78740174, 0.78692871, 0.78645521, 0.78598124, 0.78550684, 0.78503191,
+ 0.78455657, 0.78408080, 0.78360450, 0.78312778, 0.78265059, 0.78217292, 0.78169483, 0.78121626,
+ 0.78073722, 0.78025776, 0.77977777, 0.77929735, 0.77881652, 0.77833521, 0.77785343, 0.77737117,
+ 0.77688849, 0.77640533, 0.77592170, 0.77543765, 0.77495313, 0.77446812, 0.77398270, 0.77349681,
+ 0.77301043, 0.77252364, 0.77203637, 0.77154869, 0.77106053, 0.77057189, 0.77008283, 0.76959330,
+ 0.76910335, 0.76861292, 0.76812202, 0.76763070, 0.76713890, 0.76664668, 0.76615399, 0.76566088,
+ 0.76516724, 0.76467323, 0.76417875, 0.76368380, 0.76318842, 0.76269257, 0.76219630, 0.76169956,
+ 0.76120239, 0.76070476, 0.76020670, 0.75970817, 0.75920922, 0.75870979, 0.75820988, 0.75770962,
+ 0.75720882, 0.75670767, 0.75620598, 0.75570393, 0.75520140, 0.75469840, 0.75419497, 0.75369114,
+ 0.75318682, 0.75268203, 0.75217682, 0.75167120, 0.75116515, 0.75065863, 0.75015163, 0.74964422,
+ 0.74913639, 0.74862808, 0.74811935, 0.74761021, 0.74710059, 0.74659055, 0.74608010, 0.74556917,
+ 0.74505776, 0.74454600, 0.74403375, 0.74352109, 0.74300796, 0.74249440, 0.74198043, 0.74146599,
+ 0.74095112, 0.74043584, 0.73992008, 0.73940390, 0.73888731, 0.73837030, 0.73785281, 0.73733491,
+ 0.73681659, 0.73629779, 0.73577857, 0.73525894, 0.73473889, 0.73421836, 0.73369741, 0.73317605,
+ 0.73265427, 0.73213202, 0.73160940, 0.73108631, 0.73056275, 0.73003882, 0.72951442, 0.72898960,
+ 0.72846437, 0.72793871, 0.72741264, 0.72688609, 0.72635913, 0.72583181, 0.72530395, 0.72477573,
+ 0.72424710, 0.72371799, 0.72318846, 0.72265857, 0.72212821, 0.72159743, 0.72106618, 0.72053456,
+ 0.72000253, 0.71947002, 0.71893710, 0.71840382, 0.71787006, 0.71733588, 0.71680129, 0.71626627,
+ 0.71573085, 0.71519494, 0.71465868, 0.71412200, 0.71358484, 0.71304733, 0.71250939, 0.71197098,
+ 0.71143222, 0.71089298, 0.71035337, 0.70981330, 0.70927280, 0.70873195, 0.70819062, 0.70764893,
+ 0.70710677, 0.70656425, 0.70602125, 0.70547789, 0.70493406, 0.70438987, 0.70384526, 0.70330018,
+ 0.70275474, 0.70220888, 0.70166260, 0.70111591, 0.70056880, 0.70002127, 0.69947332, 0.69892502,
+ 0.69837624, 0.69782710, 0.69727749, 0.69672751, 0.69617712, 0.69562632, 0.69507509, 0.69452351,
+ 0.69397146, 0.69341904, 0.69286615, 0.69231290, 0.69175923, 0.69120520, 0.69065070, 0.69009584,
+ 0.68954057, 0.68898487, 0.68842876, 0.68787223, 0.68731534, 0.68675804, 0.68620032, 0.68564218,
+ 0.68508369, 0.68452471, 0.68396538, 0.68340570, 0.68284553, 0.68228501, 0.68172407, 0.68116271,
+ 0.68060100, 0.68003887, 0.67947632, 0.67891335, 0.67835003, 0.67778629, 0.67722219, 0.67665762,
+ 0.67609268, 0.67552739, 0.67496163, 0.67439550, 0.67382902, 0.67326206, 0.67269474, 0.67212707,
+ 0.67155898, 0.67099047, 0.67042154, 0.66985226, 0.66928262, 0.66871250, 0.66814202, 0.66757119,
+ 0.66699994, 0.66642827, 0.66585624, 0.66528380, 0.66471100, 0.66413778, 0.66356415, 0.66299015,
+ 0.66241580, 0.66184098, 0.66126585, 0.66069031, 0.66011435, 0.65953803, 0.65896130, 0.65838420,
+ 0.65780669, 0.65722883, 0.65665054, 0.65607190, 0.65549284, 0.65491343, 0.65433359, 0.65375340,
+ 0.65317285, 0.65259188, 0.65201056, 0.65142882, 0.65084666, 0.65026420, 0.64968133, 0.64909804,
+ 0.64851439, 0.64793038, 0.64734596, 0.64676118, 0.64617604, 0.64559048, 0.64500451, 0.64441824,
+ 0.64383155, 0.64324450, 0.64265704, 0.64206922, 0.64148104, 0.64089245, 0.64030349, 0.63971418,
+ 0.63912445, 0.63853437, 0.63794392, 0.63735306, 0.63676184, 0.63617027, 0.63557833, 0.63498598,
+ 0.63439327, 0.63380021, 0.63320678, 0.63261294, 0.63201874, 0.63142419, 0.63082922, 0.63023394,
+ 0.62963825, 0.62904221, 0.62844574, 0.62784898, 0.62725180, 0.62665427, 0.62605637, 0.62545812,
+ 0.62485951, 0.62426049, 0.62366110, 0.62306136, 0.62246126, 0.62186080, 0.62125999, 0.62065876,
+ 0.62005723, 0.61945528, 0.61885297, 0.61825031, 0.61764729, 0.61704391, 0.61644018, 0.61583608,
+ 0.61523157, 0.61462677, 0.61402154, 0.61341602, 0.61281008, 0.61220378, 0.61159718, 0.61099017,
+ 0.61038280, 0.60977507, 0.60916704, 0.60855860, 0.60794979, 0.60734063, 0.60673112, 0.60612124,
+ 0.60551107, 0.60490048, 0.60428953, 0.60367823, 0.60306662, 0.60245460, 0.60184222, 0.60122955,
+ 0.60061646, 0.60000306, 0.59938931, 0.59877521, 0.59816068, 0.59754586, 0.59693068, 0.59631521,
+ 0.59569931, 0.59508306, 0.59446651, 0.59384960, 0.59323227, 0.59261465, 0.59199667, 0.59137839,
+ 0.59075969, 0.59014070, 0.58952129, 0.58890158, 0.58828157, 0.58766115, 0.58704036, 0.58641928,
+ 0.58579785, 0.58517605, 0.58455396, 0.58393145, 0.58330864, 0.58268547, 0.58206201, 0.58143812,
+ 0.58081394, 0.58018941, 0.57956457, 0.57893932, 0.57831377, 0.57768792, 0.57706165, 0.57643509,
+ 0.57580817, 0.57518095, 0.57455337, 0.57392544, 0.57329714, 0.57266855, 0.57203960, 0.57141036,
+ 0.57078075, 0.57015079, 0.56952053, 0.56888992, 0.56825894, 0.56762767, 0.56699604, 0.56636411,
+ 0.56573182, 0.56509918, 0.56446624, 0.56383294, 0.56319934, 0.56256539, 0.56193113, 0.56129652,
+ 0.56066155, 0.56002629, 0.55939072, 0.55875480, 0.55811852, 0.55748194, 0.55684501, 0.55620778,
+ 0.55557024, 0.55493236, 0.55429411, 0.55365556, 0.55301672, 0.55237752, 0.55173796, 0.55109817,
+ 0.55045795, 0.54981750, 0.54917663, 0.54853553, 0.54789406, 0.54725230, 0.54661018, 0.54596776,
+ 0.54532498, 0.54468191, 0.54403853, 0.54339480, 0.54275078, 0.54210645, 0.54146177, 0.54081678,
+ 0.54017144, 0.53952587, 0.53887993, 0.53823364, 0.53758705, 0.53694016, 0.53629297, 0.53564548,
+ 0.53499764, 0.53434944, 0.53370100, 0.53305221, 0.53240311, 0.53175372, 0.53110403, 0.53045398,
+ 0.52980363, 0.52915299, 0.52850199, 0.52785075, 0.52719915, 0.52654725, 0.52589500, 0.52524251,
+ 0.52458966, 0.52393657, 0.52328312, 0.52262938, 0.52197528, 0.52132094, 0.52066624, 0.52001125,
+ 0.51935601, 0.51870042, 0.51804453, 0.51738828, 0.51673180, 0.51607502, 0.51541787, 0.51476043,
+ 0.51410276, 0.51344472, 0.51278639, 0.51212776, 0.51146883, 0.51080960, 0.51015007, 0.50949025,
+ 0.50883013, 0.50816971, 0.50750899, 0.50684798, 0.50618666, 0.50552505, 0.50486308, 0.50420088,
+ 0.50353837, 0.50287557, 0.50221246, 0.50154907, 0.50088537, 0.50022137, 0.49955711, 0.49889255,
+ 0.49822766, 0.49756250, 0.49689704, 0.49623129, 0.49556527, 0.49489895, 0.49423230, 0.49356541,
+ 0.49289820, 0.49223071, 0.49156290, 0.49089485, 0.49022648, 0.48955783, 0.48888889, 0.48821968,
+ 0.48755017, 0.48688036, 0.48621029, 0.48553991, 0.48486924, 0.48419830, 0.48352706, 0.48285556,
+ 0.48218378, 0.48151168, 0.48083934, 0.48016667, 0.47949377, 0.47882056, 0.47814706, 0.47747329,
+ 0.47679922, 0.47612488, 0.47545028, 0.47477537, 0.47410020, 0.47342476, 0.47274902, 0.47207302,
+ 0.47139674, 0.47072017, 0.47004333, 0.46936622, 0.46868882, 0.46801114, 0.46733320, 0.46665499,
+ 0.46597651, 0.46529773, 0.46461868, 0.46393937, 0.46325979, 0.46257994, 0.46189979, 0.46121940,
+ 0.46053872, 0.45985776, 0.45917654, 0.45849505, 0.45781329, 0.45713127, 0.45644897, 0.45576641,
+ 0.45508358, 0.45440048, 0.45371711, 0.45303348, 0.45234957, 0.45166543, 0.45098099, 0.45029628,
+ 0.44961134, 0.44892609, 0.44824061, 0.44755486, 0.44686884, 0.44618255, 0.44549602, 0.44480920,
+ 0.44412214, 0.44343480, 0.44274724, 0.44205937, 0.44137126, 0.44068289, 0.43999428, 0.43930539,
+ 0.43861625, 0.43792683, 0.43723717, 0.43654725, 0.43585709, 0.43516666, 0.43447596, 0.43378502,
+ 0.43309382, 0.43240237, 0.43171066, 0.43101871, 0.43032649, 0.42963400, 0.42894128, 0.42824832,
+ 0.42755508, 0.42686161, 0.42616788, 0.42547390, 0.42477968, 0.42408520, 0.42339048, 0.42269549,
+ 0.42200026, 0.42130479, 0.42060909, 0.41991311, 0.41921690, 0.41852042, 0.41782370, 0.41712677,
+ 0.41642955, 0.41573212, 0.41503441, 0.41433650, 0.41363832, 0.41293988, 0.41224122, 0.41154233,
+ 0.41084316, 0.41014379, 0.40944415, 0.40874428, 0.40804416, 0.40734380, 0.40664321, 0.40594238,
+ 0.40524131, 0.40454000, 0.40383846, 0.40313667, 0.40243465, 0.40173239, 0.40102988, 0.40032718,
+ 0.39962420, 0.39892101, 0.39821756, 0.39751390, 0.39681000, 0.39610586, 0.39540148, 0.39469686,
+ 0.39399204, 0.39328697, 0.39258167, 0.39187613, 0.39117038, 0.39046440, 0.38975817, 0.38905174,
+ 0.38834503, 0.38763815, 0.38693100, 0.38622364, 0.38551605, 0.38480824, 0.38410020, 0.38339192,
+ 0.38268343, 0.38197473, 0.38126576, 0.38055661, 0.37984720, 0.37913761, 0.37842774, 0.37771770,
+ 0.37700742, 0.37629691, 0.37558618, 0.37487522, 0.37416407, 0.37345266, 0.37274107, 0.37202924,
+ 0.37131721, 0.37060493, 0.36989245, 0.36917976, 0.36846682, 0.36775368, 0.36704034, 0.36632678,
+ 0.36561298, 0.36489901, 0.36418480, 0.36347038, 0.36275572, 0.36204088, 0.36132580, 0.36061051,
+ 0.35989505, 0.35917935, 0.35846341, 0.35774729, 0.35703096, 0.35631442, 0.35559767, 0.35488069,
+ 0.35416353, 0.35344616, 0.35272855, 0.35201076, 0.35129276, 0.35057455, 0.34985614, 0.34913751,
+ 0.34841868, 0.34769964, 0.34698042, 0.34626096, 0.34554133, 0.34482148, 0.34410143, 0.34338117,
+ 0.34266073, 0.34194008, 0.34121922, 0.34049815, 0.33977687, 0.33905542, 0.33833376, 0.33761191,
+ 0.33688986, 0.33616760, 0.33544514, 0.33472249, 0.33399966, 0.33327660, 0.33255336, 0.33182994,
+ 0.33110631, 0.33038250, 0.32965845, 0.32893425, 0.32820985, 0.32748523, 0.32676044, 0.32603547,
+ 0.32531029, 0.32458493, 0.32385936, 0.32313362, 0.32240769, 0.32168156, 0.32095525, 0.32022873,
+ 0.31950203, 0.31877515, 0.31804809, 0.31732082, 0.31659338, 0.31586576, 0.31513792, 0.31440994,
+ 0.31368175, 0.31295338, 0.31222481, 0.31149608, 0.31076714, 0.31003806, 0.30930877, 0.30857930,
+ 0.30784965, 0.30711982, 0.30638981, 0.30565959, 0.30492923, 0.30419868, 0.30346796, 0.30273703,
+ 0.30200595, 0.30127469, 0.30054325, 0.29981163, 0.29907984, 0.29834786, 0.29761571, 0.29688337,
+ 0.29615089, 0.29541820, 0.29468536, 0.29395235, 0.29321915, 0.29248580, 0.29175225, 0.29101855,
+ 0.29028466, 0.28955063, 0.28881642, 0.28808203, 0.28734747, 0.28661272, 0.28587782, 0.28514278,
+ 0.28440753, 0.28367212, 0.28293657, 0.28220084, 0.28146493, 0.28072888, 0.27999264, 0.27925625,
+ 0.27851969, 0.27778298, 0.27704608, 0.27630904, 0.27557182, 0.27483445, 0.27409691, 0.27335921,
+ 0.27262136, 0.27188334, 0.27114516, 0.27040681, 0.26966831, 0.26892966, 0.26819086, 0.26745188,
+ 0.26671275, 0.26597348, 0.26523402, 0.26449442, 0.26375467, 0.26301476, 0.26227471, 0.26153448,
+ 0.26079410, 0.26005360, 0.25931293, 0.25857207, 0.25783110, 0.25708997, 0.25634867, 0.25560725,
+ 0.25486565, 0.25412393, 0.25338203, 0.25264001, 0.25189781, 0.25115550, 0.25041300, 0.24967039,
+ 0.24892761, 0.24818468, 0.24744162, 0.24669841, 0.24595505, 0.24521154, 0.24446790, 0.24372411,
+ 0.24298018, 0.24223611, 0.24149188, 0.24074753, 0.24000302, 0.23925838, 0.23851359, 0.23776866,
+ 0.23702361, 0.23627840, 0.23553306, 0.23478758, 0.23404196, 0.23329620, 0.23255031, 0.23180428,
+ 0.23105811, 0.23031181, 0.22956537, 0.22881879, 0.22807208, 0.22732525, 0.22657827, 0.22583115,
+ 0.22508392, 0.22433653, 0.22358903, 0.22284140, 0.22209363, 0.22134572, 0.22059768, 0.21984953,
+ 0.21910124, 0.21835282, 0.21760428, 0.21685560, 0.21610680, 0.21535787, 0.21460882, 0.21385963,
+ 0.21311031, 0.21236089, 0.21161133, 0.21086164, 0.21011184, 0.20936191, 0.20861185, 0.20786168,
+ 0.20711137, 0.20636095, 0.20561041, 0.20485975, 0.20410897, 0.20335807, 0.20260704, 0.20185590,
+ 0.20110464, 0.20035325, 0.19960175, 0.19885014, 0.19809841, 0.19734657, 0.19659460, 0.19584252,
+ 0.19509032, 0.19433801, 0.19358559, 0.19283305, 0.19208039, 0.19132763, 0.19057475, 0.18982176,
+ 0.18906866, 0.18831545, 0.18756212, 0.18680869, 0.18605515, 0.18530150, 0.18454774, 0.18379387,
+ 0.18303989, 0.18228580, 0.18153161, 0.18077731, 0.18002290, 0.17926839, 0.17851377, 0.17775905,
+ 0.17700422, 0.17624930, 0.17549425, 0.17473911, 0.17398387, 0.17322853, 0.17247309, 0.17171754,
+ 0.17096189, 0.17020614, 0.16945030, 0.16869435, 0.16793829, 0.16718215, 0.16642590, 0.16566956,
+ 0.16491312, 0.16415659, 0.16339995, 0.16264322, 0.16188639, 0.16112947, 0.16037245, 0.15961535,
+ 0.15885815, 0.15810084, 0.15734346, 0.15658598, 0.15582840, 0.15507074, 0.15431297, 0.15355512,
+ 0.15279719, 0.15203916, 0.15128104, 0.15052283, 0.14976454, 0.14900614, 0.14824767, 0.14748912,
+ 0.14673047, 0.14597175, 0.14521292, 0.14445402, 0.14369503, 0.14293596, 0.14217681, 0.14141756,
+ 0.14065824, 0.13989884, 0.13913934, 0.13837977, 0.13762012, 0.13686039, 0.13610058, 0.13534068,
+ 0.13458070, 0.13382065, 0.13306053, 0.13230032, 0.13154003, 0.13077967, 0.13001922, 0.12925871,
+ 0.12849811, 0.12773745, 0.12697670, 0.12621588, 0.12545498, 0.12469402, 0.12393297, 0.12317186,
+ 0.12241068, 0.12164941, 0.12088808, 0.12012669, 0.11936522, 0.11860368, 0.11784206, 0.11708038,
+ 0.11631863, 0.11555681, 0.11479492, 0.11403298, 0.11327095, 0.11250886, 0.11174671, 0.11098449,
+ 0.11022221, 0.10945985, 0.10869744, 0.10793497, 0.10717242, 0.10640982, 0.10564715, 0.10488442,
+ 0.10412163, 0.10335878, 0.10259587, 0.10183290, 0.10106986, 0.10030677, 0.09954362, 0.09878041,
+ 0.09801714, 0.09725381, 0.09649043, 0.09572699, 0.09496350, 0.09419994, 0.09343634, 0.09267268,
+ 0.09190895, 0.09114519, 0.09038136, 0.08961748, 0.08885355, 0.08808957, 0.08732554, 0.08656145,
+ 0.08579731, 0.08503313, 0.08426889, 0.08350460, 0.08274026, 0.08197588, 0.08121145, 0.08044697,
+ 0.07968244, 0.07891786, 0.07815325, 0.07738858, 0.07662386, 0.07585911, 0.07509430, 0.07432945,
+ 0.07356457, 0.07279963, 0.07203465, 0.07126963, 0.07050458, 0.06973947, 0.06897433, 0.06820914,
+ 0.06744392, 0.06667866, 0.06591335, 0.06514801, 0.06438263, 0.06361721, 0.06285176, 0.06208627,
+ 0.06132074, 0.06055517, 0.05978957, 0.05902394, 0.05825827, 0.05749256, 0.05672682, 0.05596105,
+ 0.05519525, 0.05442941, 0.05366354, 0.05289764, 0.05213170, 0.05136574, 0.05059975, 0.04983373,
+ 0.04906768, 0.04830159, 0.04753548, 0.04676935, 0.04600318, 0.04523699, 0.04447077, 0.04370453,
+ 0.04293826, 0.04217196, 0.04140564, 0.04063930, 0.03987293, 0.03910654, 0.03834012, 0.03757368,
+ 0.03680722, 0.03604074, 0.03527424, 0.03450771, 0.03374117, 0.03297461, 0.03220803, 0.03144142,
+ 0.03067480, 0.02990817, 0.02914151, 0.02837484, 0.02760815, 0.02684144, 0.02607472, 0.02530798,
+ 0.02454123, 0.02377446, 0.02300768, 0.02224089, 0.02147408, 0.02070726, 0.01994043, 0.01917358,
+ 0.01840673, 0.01763986, 0.01687299, 0.01610610, 0.01533921, 0.01457230, 0.01380539, 0.01303847,
+ 0.01227154, 0.01150460, 0.01073766, 0.00997071, 0.00920375, 0.00843679, 0.00766983, 0.00690286,
+ 0.00613588, 0.00536891, 0.00460193, 0.00383494, 0.00306796, 0.00230097, 0.00153398, 0.00076699,
+ 0.00000000, -0.00076699, -0.00153398, -0.00230097, -0.00306796, -0.00383494, -0.00460193, -0.00536891,
+ -0.00613588, -0.00690286, -0.00766983, -0.00843679, -0.00920375, -0.00997071, -0.01073766, -0.01150460,
+ -0.01227154, -0.01303847, -0.01380539, -0.01457230, -0.01533921, -0.01610610, -0.01687299, -0.01763986,
+ -0.01840673, -0.01917358, -0.01994043, -0.02070726, -0.02147408, -0.02224089, -0.02300768, -0.02377446,
+ -0.02454123, -0.02530798, -0.02607472, -0.02684144, -0.02760815, -0.02837484, -0.02914151, -0.02990817,
+ -0.03067480, -0.03144142, -0.03220803, -0.03297461, -0.03374117, -0.03450771, -0.03527424, -0.03604074,
+ -0.03680722, -0.03757368, -0.03834012, -0.03910654, -0.03987293, -0.04063930, -0.04140564, -0.04217196,
+ -0.04293826, -0.04370453, -0.04447077, -0.04523699, -0.04600318, -0.04676935, -0.04753548, -0.04830159,
+ -0.04906768, -0.04983373, -0.05059975, -0.05136574, -0.05213170, -0.05289764, -0.05366354, -0.05442941,
+ -0.05519525, -0.05596105, -0.05672682, -0.05749256, -0.05825827, -0.05902394, -0.05978957, -0.06055517,
+ -0.06132074, -0.06208627, -0.06285176, -0.06361721, -0.06438263, -0.06514801, -0.06591335, -0.06667866,
+ -0.06744392, -0.06820914, -0.06897433, -0.06973947, -0.07050458, -0.07126963, -0.07203465, -0.07279963,
+ -0.07356457, -0.07432945, -0.07509430, -0.07585911, -0.07662386, -0.07738858, -0.07815325, -0.07891786,
+ -0.07968244, -0.08044697, -0.08121145, -0.08197588, -0.08274026, -0.08350460, -0.08426889, -0.08503313,
+ -0.08579731, -0.08656145, -0.08732554, -0.08808957, -0.08885355, -0.08961748, -0.09038136, -0.09114519,
+ -0.09190895, -0.09267268, -0.09343634, -0.09419994, -0.09496350, -0.09572699, -0.09649043, -0.09725381,
+ -0.09801714, -0.09878041, -0.09954362, -0.10030677, -0.10106986, -0.10183290, -0.10259587, -0.10335878,
+ -0.10412163, -0.10488442, -0.10564715, -0.10640982, -0.10717242, -0.10793497, -0.10869744, -0.10945985,
+ -0.11022221, -0.11098449, -0.11174671, -0.11250886, -0.11327095, -0.11403298, -0.11479492, -0.11555681,
+ -0.11631863, -0.11708038, -0.11784206, -0.11860368, -0.11936522, -0.12012669, -0.12088808, -0.12164941,
+ -0.12241068, -0.12317186, -0.12393297, -0.12469402, -0.12545498, -0.12621588, -0.12697670, -0.12773745,
+ -0.12849811, -0.12925871, -0.13001922, -0.13077967, -0.13154003, -0.13230032, -0.13306053, -0.13382065,
+ -0.13458070, -0.13534068, -0.13610058, -0.13686039, -0.13762012, -0.13837977, -0.13913934, -0.13989884,
+ -0.14065824, -0.14141756, -0.14217681, -0.14293596, -0.14369503, -0.14445402, -0.14521292, -0.14597175,
+ -0.14673047, -0.14748912, -0.14824767, -0.14900614, -0.14976454, -0.15052283, -0.15128104, -0.15203916,
+ -0.15279719, -0.15355512, -0.15431297, -0.15507074, -0.15582840, -0.15658598, -0.15734346, -0.15810084,
+ -0.15885815, -0.15961535, -0.16037245, -0.16112947, -0.16188639, -0.16264322, -0.16339995, -0.16415659,
+ -0.16491312, -0.16566956, -0.16642590, -0.16718215, -0.16793829, -0.16869435, -0.16945030, -0.17020614,
+ -0.17096189, -0.17171754, -0.17247309, -0.17322853, -0.17398387, -0.17473911, -0.17549425, -0.17624930,
+ -0.17700422, -0.17775905, -0.17851377, -0.17926839, -0.18002290, -0.18077731, -0.18153161, -0.18228580,
+ -0.18303989, -0.18379387, -0.18454774, -0.18530150, -0.18605515, -0.18680869, -0.18756212, -0.18831545,
+ -0.18906866, -0.18982176, -0.19057475, -0.19132763, -0.19208039, -0.19283305, -0.19358559, -0.19433801,
+ -0.19509032, -0.19584252, -0.19659460, -0.19734657, -0.19809841, -0.19885014, -0.19960175, -0.20035325,
+ -0.20110464, -0.20185590, -0.20260704, -0.20335807, -0.20410897, -0.20485975, -0.20561041, -0.20636095,
+ -0.20711137, -0.20786168, -0.20861185, -0.20936191, -0.21011184, -0.21086164, -0.21161133, -0.21236089,
+ -0.21311031, -0.21385963, -0.21460882, -0.21535787, -0.21610680, -0.21685560, -0.21760428, -0.21835282,
+ -0.21910124, -0.21984953, -0.22059768, -0.22134572, -0.22209363, -0.22284140, -0.22358903, -0.22433653,
+ -0.22508392, -0.22583115, -0.22657827, -0.22732525, -0.22807208, -0.22881879, -0.22956537, -0.23031181,
+ -0.23105811, -0.23180428, -0.23255031, -0.23329620, -0.23404196, -0.23478758, -0.23553306, -0.23627840,
+ -0.23702361, -0.23776866, -0.23851359, -0.23925838, -0.24000302, -0.24074753, -0.24149188, -0.24223611,
+ -0.24298018, -0.24372411, -0.24446790, -0.24521154, -0.24595505, -0.24669841, -0.24744162, -0.24818468,
+ -0.24892761, -0.24967039, -0.25041300, -0.25115550, -0.25189781, -0.25264001, -0.25338203, -0.25412393,
+ -0.25486565, -0.25560725, -0.25634867, -0.25708997, -0.25783110, -0.25857207, -0.25931293, -0.26005360,
+ -0.26079410, -0.26153448, -0.26227471, -0.26301476, -0.26375467, -0.26449442, -0.26523402, -0.26597348,
+ -0.26671275, -0.26745188, -0.26819086, -0.26892966, -0.26966831, -0.27040681, -0.27114516, -0.27188334,
+ -0.27262136, -0.27335921, -0.27409691, -0.27483445, -0.27557182, -0.27630904, -0.27704608, -0.27778298,
+ -0.27851969, -0.27925625, -0.27999264, -0.28072888, -0.28146493, -0.28220084, -0.28293657, -0.28367212,
+ -0.28440753, -0.28514278, -0.28587782, -0.28661272, -0.28734747, -0.28808203, -0.28881642, -0.28955063,
+ -0.29028466, -0.29101855, -0.29175225, -0.29248580, -0.29321915, -0.29395235, -0.29468536, -0.29541820,
+ -0.29615089, -0.29688337, -0.29761571, -0.29834786, -0.29907984, -0.29981163, -0.30054325, -0.30127469,
+ -0.30200595, -0.30273703, -0.30346796, -0.30419868, -0.30492923, -0.30565959, -0.30638981, -0.30711982,
+ -0.30784965, -0.30857930, -0.30930877, -0.31003806, -0.31076714, -0.31149608, -0.31222481, -0.31295338,
+ -0.31368175, -0.31440994, -0.31513792, -0.31586576, -0.31659338, -0.31732082, -0.31804809, -0.31877515,
+ -0.31950203, -0.32022873, -0.32095525, -0.32168156, -0.32240769, -0.32313362, -0.32385936, -0.32458493,
+ -0.32531029, -0.32603547, -0.32676044, -0.32748523, -0.32820985, -0.32893425, -0.32965845, -0.33038250,
+ -0.33110631, -0.33182994, -0.33255336, -0.33327660, -0.33399966, -0.33472249, -0.33544514, -0.33616760,
+ -0.33688986, -0.33761191, -0.33833376, -0.33905542, -0.33977687, -0.34049815, -0.34121922, -0.34194008,
+ -0.34266073, -0.34338117, -0.34410143, -0.34482148, -0.34554133, -0.34626096, -0.34698042, -0.34769964,
+ -0.34841868, -0.34913751, -0.34985614, -0.35057455, -0.35129276, -0.35201076, -0.35272855, -0.35344616,
+ -0.35416353, -0.35488069, -0.35559767, -0.35631442, -0.35703096, -0.35774729, -0.35846341, -0.35917935,
+ -0.35989505, -0.36061051, -0.36132580, -0.36204088, -0.36275572, -0.36347038, -0.36418480, -0.36489901,
+ -0.36561298, -0.36632678, -0.36704034, -0.36775368, -0.36846682, -0.36917976, -0.36989245, -0.37060493,
+ -0.37131721, -0.37202924, -0.37274107, -0.37345266, -0.37416407, -0.37487522, -0.37558618, -0.37629691,
+ -0.37700742, -0.37771770, -0.37842774, -0.37913761, -0.37984720, -0.38055661, -0.38126576, -0.38197473,
+ -0.38268343, -0.38339192, -0.38410020, -0.38480824, -0.38551605, -0.38622364, -0.38693100, -0.38763815,
+ -0.38834503, -0.38905174, -0.38975817, -0.39046440, -0.39117038, -0.39187613, -0.39258167, -0.39328697,
+ -0.39399204, -0.39469686, -0.39540148, -0.39610586, -0.39681000, -0.39751390, -0.39821756, -0.39892101,
+ -0.39962420, -0.40032718, -0.40102988, -0.40173239, -0.40243465, -0.40313667, -0.40383846, -0.40454000,
+ -0.40524131, -0.40594238, -0.40664321, -0.40734380, -0.40804416, -0.40874428, -0.40944415, -0.41014379,
+ -0.41084316, -0.41154233, -0.41224122, -0.41293988, -0.41363832, -0.41433650, -0.41503441, -0.41573212,
+ -0.41642955, -0.41712677, -0.41782370, -0.41852042, -0.41921690, -0.41991311, -0.42060909, -0.42130479,
+ -0.42200026, -0.42269549, -0.42339048, -0.42408520, -0.42477968, -0.42547390, -0.42616788, -0.42686161,
+ -0.42755508, -0.42824832, -0.42894128, -0.42963400, -0.43032649, -0.43101871, -0.43171066, -0.43240237,
+ -0.43309382, -0.43378502, -0.43447596, -0.43516666, -0.43585709, -0.43654725, -0.43723717, -0.43792683,
+ -0.43861625, -0.43930539, -0.43999428, -0.44068289, -0.44137126, -0.44205937, -0.44274724, -0.44343480,
+ -0.44412214, -0.44480920, -0.44549602, -0.44618255, -0.44686884, -0.44755486, -0.44824061, -0.44892609,
+ -0.44961134, -0.45029628, -0.45098099, -0.45166543, -0.45234957, -0.45303348, -0.45371711, -0.45440048,
+ -0.45508358, -0.45576641, -0.45644897, -0.45713127, -0.45781329, -0.45849505, -0.45917654, -0.45985776,
+ -0.46053872, -0.46121940, -0.46189979, -0.46257994, -0.46325979, -0.46393937, -0.46461868, -0.46529773,
+ -0.46597651, -0.46665499, -0.46733320, -0.46801114, -0.46868882, -0.46936622, -0.47004333, -0.47072017,
+ -0.47139674, -0.47207302, -0.47274902, -0.47342476, -0.47410020, -0.47477537, -0.47545028, -0.47612488,
+ -0.47679922, -0.47747329, -0.47814706, -0.47882056, -0.47949377, -0.48016667, -0.48083934, -0.48151168,
+ -0.48218378, -0.48285556, -0.48352706, -0.48419830, -0.48486924, -0.48553991, -0.48621029, -0.48688036,
+ -0.48755017, -0.48821968, -0.48888889, -0.48955783, -0.49022648, -0.49089485, -0.49156290, -0.49223071,
+ -0.49289820, -0.49356541, -0.49423230, -0.49489895, -0.49556527, -0.49623129, -0.49689704, -0.49756250,
+ -0.49822766, -0.49889255, -0.49955711, -0.50022137, -0.50088537, -0.50154907, -0.50221246, -0.50287557,
+ -0.50353837, -0.50420088, -0.50486308, -0.50552505, -0.50618666, -0.50684798, -0.50750899, -0.50816971,
+ -0.50883013, -0.50949025, -0.51015007, -0.51080960, -0.51146883, -0.51212776, -0.51278639, -0.51344472,
+ -0.51410276, -0.51476043, -0.51541787, -0.51607502, -0.51673180, -0.51738828, -0.51804453, -0.51870042,
+ -0.51935601, -0.52001125, -0.52066624, -0.52132094, -0.52197528, -0.52262938, -0.52328312, -0.52393657,
+ -0.52458966, -0.52524251, -0.52589500, -0.52654725, -0.52719915, -0.52785075, -0.52850199, -0.52915299,
+ -0.52980363, -0.53045398, -0.53110403, -0.53175372, -0.53240311, -0.53305221, -0.53370100, -0.53434944,
+ -0.53499764, -0.53564548, -0.53629297, -0.53694016, -0.53758705, -0.53823364, -0.53887993, -0.53952587,
+ -0.54017144, -0.54081678, -0.54146177, -0.54210645, -0.54275078, -0.54339480, -0.54403853, -0.54468191,
+ -0.54532498, -0.54596776, -0.54661018, -0.54725230, -0.54789406, -0.54853553, -0.54917663, -0.54981750,
+ -0.55045795, -0.55109817, -0.55173796, -0.55237752, -0.55301672, -0.55365556, -0.55429411, -0.55493236,
+ -0.55557024, -0.55620778, -0.55684501, -0.55748194, -0.55811852, -0.55875480, -0.55939072, -0.56002629,
+ -0.56066155, -0.56129652, -0.56193113, -0.56256539, -0.56319934, -0.56383294, -0.56446624, -0.56509918,
+ -0.56573182, -0.56636411, -0.56699604, -0.56762767, -0.56825894, -0.56888992, -0.56952053, -0.57015079,
+ -0.57078075, -0.57141036, -0.57203960, -0.57266855, -0.57329714, -0.57392544, -0.57455337, -0.57518095,
+ -0.57580817, -0.57643509, -0.57706165, -0.57768792, -0.57831377, -0.57893932, -0.57956457, -0.58018941,
+ -0.58081394, -0.58143812, -0.58206201, -0.58268547, -0.58330864, -0.58393145, -0.58455396, -0.58517605,
+ -0.58579785, -0.58641928, -0.58704036, -0.58766115, -0.58828157, -0.58890158, -0.58952129, -0.59014070,
+ -0.59075969, -0.59137839, -0.59199667, -0.59261465, -0.59323227, -0.59384960, -0.59446651, -0.59508306,
+ -0.59569931, -0.59631521, -0.59693068, -0.59754586, -0.59816068, -0.59877521, -0.59938931, -0.60000306,
+ -0.60061646, -0.60122955, -0.60184222, -0.60245460, -0.60306662, -0.60367823, -0.60428953, -0.60490048,
+ -0.60551107, -0.60612124, -0.60673112, -0.60734063, -0.60794979, -0.60855860, -0.60916704, -0.60977507,
+ -0.61038280, -0.61099017, -0.61159718, -0.61220378, -0.61281008, -0.61341602, -0.61402154, -0.61462677,
+ -0.61523157, -0.61583608, -0.61644018, -0.61704391, -0.61764729, -0.61825031, -0.61885297, -0.61945528,
+ -0.62005723, -0.62065876, -0.62125999, -0.62186080, -0.62246126, -0.62306136, -0.62366110, -0.62426049,
+ -0.62485951, -0.62545812, -0.62605637, -0.62665427, -0.62725180, -0.62784898, -0.62844574, -0.62904221,
+ -0.62963825, -0.63023394, -0.63082922, -0.63142419, -0.63201874, -0.63261294, -0.63320678, -0.63380021,
+ -0.63439327, -0.63498598, -0.63557833, -0.63617027, -0.63676184, -0.63735306, -0.63794392, -0.63853437,
+ -0.63912445, -0.63971418, -0.64030349, -0.64089245, -0.64148104, -0.64206922, -0.64265704, -0.64324450,
+ -0.64383155, -0.64441824, -0.64500451, -0.64559048, -0.64617604, -0.64676118, -0.64734596, -0.64793038,
+ -0.64851439, -0.64909804, -0.64968133, -0.65026420, -0.65084666, -0.65142882, -0.65201056, -0.65259188,
+ -0.65317285, -0.65375340, -0.65433359, -0.65491343, -0.65549284, -0.65607190, -0.65665054, -0.65722883,
+ -0.65780669, -0.65838420, -0.65896130, -0.65953803, -0.66011435, -0.66069031, -0.66126585, -0.66184098,
+ -0.66241580, -0.66299015, -0.66356415, -0.66413778, -0.66471100, -0.66528380, -0.66585624, -0.66642827,
+ -0.66699994, -0.66757119, -0.66814202, -0.66871250, -0.66928262, -0.66985226, -0.67042154, -0.67099047,
+ -0.67155898, -0.67212707, -0.67269474, -0.67326206, -0.67382902, -0.67439550, -0.67496163, -0.67552739,
+ -0.67609268, -0.67665762, -0.67722219, -0.67778629, -0.67835003, -0.67891335, -0.67947632, -0.68003887,
+ -0.68060100, -0.68116271, -0.68172407, -0.68228501, -0.68284553, -0.68340570, -0.68396538, -0.68452471,
+ -0.68508369, -0.68564218, -0.68620032, -0.68675804, -0.68731534, -0.68787223, -0.68842876, -0.68898487,
+ -0.68954057, -0.69009584, -0.69065070, -0.69120520, -0.69175923, -0.69231290, -0.69286615, -0.69341904,
+ -0.69397146, -0.69452351, -0.69507509, -0.69562632, -0.69617712, -0.69672751, -0.69727749, -0.69782710,
+ -0.69837624, -0.69892502, -0.69947332, -0.70002127, -0.70056880, -0.70111591, -0.70166260, -0.70220888,
+ -0.70275474, -0.70330018, -0.70384526, -0.70438987, -0.70493406, -0.70547789, -0.70602125, -0.70656425,
+ -0.70710677, -0.70764893, -0.70819062, -0.70873195, -0.70927280, -0.70981330, -0.71035337, -0.71089298,
+ -0.71143222, -0.71197098, -0.71250939, -0.71304733, -0.71358484, -0.71412200, -0.71465868, -0.71519494,
+ -0.71573085, -0.71626627, -0.71680129, -0.71733588, -0.71787006, -0.71840382, -0.71893710, -0.71947002,
+ -0.72000253, -0.72053456, -0.72106618, -0.72159743, -0.72212821, -0.72265857, -0.72318846, -0.72371799,
+ -0.72424710, -0.72477573, -0.72530395, -0.72583181, -0.72635913, -0.72688609, -0.72741264, -0.72793871,
+ -0.72846437, -0.72898960, -0.72951442, -0.73003882, -0.73056275, -0.73108631, -0.73160940, -0.73213202,
+ -0.73265427, -0.73317605, -0.73369741, -0.73421836, -0.73473889, -0.73525894, -0.73577857, -0.73629779,
+ -0.73681659, -0.73733491, -0.73785281, -0.73837030, -0.73888731, -0.73940390, -0.73992008, -0.74043584,
+ -0.74095112, -0.74146599, -0.74198043, -0.74249440, -0.74300796, -0.74352109, -0.74403375, -0.74454600,
+ -0.74505776, -0.74556917, -0.74608010, -0.74659055, -0.74710059, -0.74761021, -0.74811935, -0.74862808,
+ -0.74913639, -0.74964422, -0.75015163, -0.75065863, -0.75116515, -0.75167120, -0.75217682, -0.75268203,
+ -0.75318682, -0.75369114, -0.75419497, -0.75469840, -0.75520140, -0.75570393, -0.75620598, -0.75670767,
+ -0.75720882, -0.75770962, -0.75820988, -0.75870979, -0.75920922, -0.75970817, -0.76020670, -0.76070476,
+ -0.76120239, -0.76169956, -0.76219630, -0.76269257, -0.76318842, -0.76368380, -0.76417875, -0.76467323,
+ -0.76516724, -0.76566088, -0.76615399, -0.76664668, -0.76713890, -0.76763070, -0.76812202, -0.76861292,
+ -0.76910335, -0.76959330, -0.77008283, -0.77057189, -0.77106053, -0.77154869, -0.77203637, -0.77252364,
+ -0.77301043, -0.77349681, -0.77398270, -0.77446812, -0.77495313, -0.77543765, -0.77592170, -0.77640533,
+ -0.77688849, -0.77737117, -0.77785343, -0.77833521, -0.77881652, -0.77929735, -0.77977777, -0.78025776,
+ -0.78073722, -0.78121626, -0.78169483, -0.78217292, -0.78265059, -0.78312778, -0.78360450, -0.78408080,
+ -0.78455657, -0.78503191, -0.78550684, -0.78598124, -0.78645521, -0.78692871, -0.78740174, -0.78787434,
+ -0.78834641, -0.78881806, -0.78928924, -0.78975999, -0.79023021, -0.79070002, -0.79116935, -0.79163820,
+ -0.79210657, -0.79257452, -0.79304194, -0.79350895, -0.79397547, -0.79444152, -0.79490715, -0.79537225,
+ -0.79583693, -0.79630107, -0.79676479, -0.79722804, -0.79769087, -0.79815316, -0.79861498, -0.79907638,
+ -0.79953724, -0.79999769, -0.80045766, -0.80091715, -0.80137616, -0.80183470, -0.80229282, -0.80275041,
+ -0.80320752, -0.80366421, -0.80412036, -0.80457610, -0.80503136, -0.80548608, -0.80594039, -0.80639422,
+ -0.80684757, -0.80730045, -0.80775285, -0.80820471, -0.80865616, -0.80910712, -0.80955762, -0.81000763,
+ -0.81045717, -0.81090623, -0.81135488, -0.81180298, -0.81225061, -0.81269777, -0.81314439, -0.81359059,
+ -0.81403631, -0.81448156, -0.81492633, -0.81537062, -0.81581444, -0.81625772, -0.81670058, -0.81714290,
+ -0.81758481, -0.81802619, -0.81846714, -0.81890756, -0.81934750, -0.81978697, -0.82022595, -0.82066447,
+ -0.82110250, -0.82154006, -0.82197714, -0.82241368, -0.82284981, -0.82328540, -0.82372051, -0.82415515,
+ -0.82458931, -0.82502300, -0.82545614, -0.82588887, -0.82632107, -0.82675278, -0.82718402, -0.82761478,
+ -0.82804507, -0.82847482, -0.82890409, -0.82933295, -0.82976121, -0.83018905, -0.83061641, -0.83104324,
+ -0.83146960, -0.83189547, -0.83232087, -0.83274579, -0.83317018, -0.83359408, -0.83401752, -0.83444041,
+ -0.83486289, -0.83528483, -0.83570629, -0.83612728, -0.83654773, -0.83696771, -0.83738720, -0.83780622,
+ -0.83822471, -0.83864272, -0.83906025, -0.83947724, -0.83989382, -0.84030986, -0.84072536, -0.84114045,
+ -0.84155500, -0.84196901, -0.84238261, -0.84279567, -0.84320825, -0.84362030, -0.84403187, -0.84444296,
+ -0.84485358, -0.84526366, -0.84567326, -0.84608233, -0.84649092, -0.84689903, -0.84730661, -0.84771377,
+ -0.84812033, -0.84852648, -0.84893203, -0.84933716, -0.84974176, -0.85014588, -0.85054946, -0.85095257,
+ -0.85135520, -0.85175729, -0.85215890, -0.85255998, -0.85296059, -0.85336071, -0.85376030, -0.85415941,
+ -0.85455799, -0.85495609, -0.85535365, -0.85575074, -0.85614735, -0.85654342, -0.85693896, -0.85733402,
+ -0.85772860, -0.85812265, -0.85851622, -0.85890925, -0.85930181, -0.85969388, -0.86008537, -0.86047643,
+ -0.86086696, -0.86125696, -0.86164647, -0.86203545, -0.86242396, -0.86281192, -0.86319941, -0.86358637,
+ -0.86397284, -0.86435878, -0.86474425, -0.86512917, -0.86551362, -0.86589754, -0.86628097, -0.86666387,
+ -0.86704624, -0.86742812, -0.86780947, -0.86819035, -0.86857069, -0.86895055, -0.86932987, -0.86970866,
+ -0.87008697, -0.87046480, -0.87084204, -0.87121886, -0.87159508, -0.87197083, -0.87234604, -0.87272078,
+ -0.87309498, -0.87346870, -0.87384182, -0.87421453, -0.87458664, -0.87495828, -0.87532938, -0.87570000,
+ -0.87607008, -0.87643969, -0.87680870, -0.87717724, -0.87754530, -0.87791282, -0.87827981, -0.87864625,
+ -0.87901223, -0.87937766, -0.87974262, -0.88010699, -0.88047087, -0.88083428, -0.88119709, -0.88155943,
+ -0.88192129, -0.88228256, -0.88264334, -0.88300359, -0.88336337, -0.88372254, -0.88408124, -0.88443947,
+ -0.88479710, -0.88515425, -0.88551086, -0.88586694, -0.88622254, -0.88657761, -0.88693213, -0.88728613,
+ -0.88763964, -0.88799256, -0.88834506, -0.88869697, -0.88904834, -0.88939923, -0.88974959, -0.89009941,
+ -0.89044875, -0.89079750, -0.89114577, -0.89149350, -0.89184070, -0.89218742, -0.89253354, -0.89287919,
+ -0.89322430, -0.89356887, -0.89391297, -0.89425647, -0.89459950, -0.89494199, -0.89528394, -0.89562535,
+ -0.89596623, -0.89630663, -0.89664650, -0.89698577, -0.89732456, -0.89766282, -0.89800060, -0.89833778,
+ -0.89867449, -0.89901060, -0.89934623, -0.89968133, -0.90001589, -0.90034992, -0.90068340, -0.90101641,
+ -0.90134883, -0.90168077, -0.90201217, -0.90234298, -0.90267330, -0.90300310, -0.90333235, -0.90366107,
+ -0.90398932, -0.90431696, -0.90464407, -0.90497071, -0.90529674, -0.90562230, -0.90594727, -0.90627176,
+ -0.90659571, -0.90691912, -0.90724200, -0.90756434, -0.90788609, -0.90820736, -0.90852809, -0.90884835,
+ -0.90916800, -0.90948713, -0.90980572, -0.91012377, -0.91044128, -0.91075826, -0.91107476, -0.91139066,
+ -0.91170603, -0.91202086, -0.91233516, -0.91264898, -0.91296220, -0.91327488, -0.91358703, -0.91389865,
+ -0.91420978, -0.91452032, -0.91483033, -0.91513979, -0.91544873, -0.91575712, -0.91606498, -0.91637230,
+ -0.91667908, -0.91698527, -0.91729099, -0.91759616, -0.91790080, -0.91820484, -0.91850841, -0.91881138,
+ -0.91911387, -0.91941577, -0.91971713, -0.92001796, -0.92031831, -0.92061806, -0.92091721, -0.92121589,
+ -0.92151403, -0.92181164, -0.92210865, -0.92240518, -0.92270112, -0.92299652, -0.92329144, -0.92358577,
+ -0.92387950, -0.92417276, -0.92446548, -0.92475760, -0.92504925, -0.92534029, -0.92563081, -0.92592078,
+ -0.92621022, -0.92649913, -0.92678750, -0.92707527, -0.92736250, -0.92764926, -0.92793542, -0.92822099,
+ -0.92850608, -0.92879063, -0.92907459, -0.92935801, -0.92964089, -0.92992324, -0.93020505, -0.93048626,
+ -0.93076694, -0.93104708, -0.93132669, -0.93160576, -0.93188429, -0.93216223, -0.93243963, -0.93271649,
+ -0.93299282, -0.93326855, -0.93354380, -0.93381846, -0.93409252, -0.93436611, -0.93463916, -0.93491161,
+ -0.93518353, -0.93545485, -0.93572569, -0.93599594, -0.93626565, -0.93653482, -0.93680346, -0.93707150,
+ -0.93733901, -0.93760598, -0.93787235, -0.93813825, -0.93840355, -0.93866831, -0.93893248, -0.93919611,
+ -0.93945920, -0.93972176, -0.93998373, -0.94024521, -0.94050604, -0.94076639, -0.94102615, -0.94128537,
+ -0.94154406, -0.94180220, -0.94205976, -0.94231677, -0.94257319, -0.94282907, -0.94308442, -0.94333923,
+ -0.94359344, -0.94384712, -0.94410026, -0.94435281, -0.94460481, -0.94485629, -0.94510722, -0.94535756,
+ -0.94560730, -0.94585657, -0.94610524, -0.94635338, -0.94660091, -0.94684792, -0.94709438, -0.94734025,
+ -0.94758558, -0.94783038, -0.94807458, -0.94831824, -0.94856137, -0.94880390, -0.94904590, -0.94928730,
+ -0.94952816, -0.94976848, -0.95000827, -0.95024747, -0.95048606, -0.95072412, -0.95096165, -0.95119864,
+ -0.95143503, -0.95167089, -0.95190614, -0.95214087, -0.95237499, -0.95260859, -0.95284164, -0.95307410,
+ -0.95330602, -0.95353740, -0.95376819, -0.95399845, -0.95422810, -0.95445722, -0.95468575, -0.95491374,
+ -0.95514119, -0.95536804, -0.95559436, -0.95582008, -0.95604527, -0.95626986, -0.95649391, -0.95671743,
+ -0.95694035, -0.95716268, -0.95738453, -0.95760572, -0.95782644, -0.95804650, -0.95826608, -0.95848507,
+ -0.95870346, -0.95892131, -0.95913863, -0.95935535, -0.95957154, -0.95978713, -0.96000212, -0.96021664,
+ -0.96043050, -0.96064389, -0.96085662, -0.96106887, -0.96128047, -0.96149158, -0.96170205, -0.96191204,
+ -0.96212143, -0.96233022, -0.96253848, -0.96274614, -0.96295327, -0.96315980, -0.96336579, -0.96357119,
+ -0.96377605, -0.96398038, -0.96418405, -0.96438724, -0.96458977, -0.96479183, -0.96499324, -0.96519411,
+ -0.96539444, -0.96559417, -0.96579337, -0.96599197, -0.96618998, -0.96638745, -0.96658438, -0.96678072,
+ -0.96697646, -0.96717167, -0.96736628, -0.96756035, -0.96775383, -0.96794677, -0.96813911, -0.96833086,
+ -0.96852207, -0.96871275, -0.96890283, -0.96909231, -0.96928126, -0.96946961, -0.96965736, -0.96984458,
+ -0.97003126, -0.97021735, -0.97040284, -0.97058779, -0.97077215, -0.97095591, -0.97113913, -0.97132182,
+ -0.97150391, -0.97168541, -0.97186631, -0.97204673, -0.97222650, -0.97240573, -0.97258437, -0.97276247,
+ -0.97293997, -0.97311687, -0.97329324, -0.97346902, -0.97364426, -0.97381890, -0.97399294, -0.97416645,
+ -0.97433937, -0.97451174, -0.97468352, -0.97485471, -0.97502536, -0.97519541, -0.97536486, -0.97553378,
+ -0.97570211, -0.97586989, -0.97603709, -0.97620368, -0.97636974, -0.97653520, -0.97670007, -0.97686440,
+ -0.97702813, -0.97719133, -0.97735387, -0.97751594, -0.97767735, -0.97783822, -0.97799850, -0.97815824,
+ -0.97831738, -0.97847593, -0.97863394, -0.97879136, -0.97894818, -0.97910446, -0.97926015, -0.97941524,
+ -0.97956979, -0.97972375, -0.97987711, -0.98002988, -0.98018211, -0.98033381, -0.98048484, -0.98063534,
+ -0.98078525, -0.98093462, -0.98108339, -0.98123157, -0.98137921, -0.98152626, -0.98167270, -0.98181856,
+ -0.98196387, -0.98210859, -0.98225272, -0.98239630, -0.98253930, -0.98268169, -0.98282355, -0.98296481,
+ -0.98310548, -0.98324561, -0.98338509, -0.98352402, -0.98366243, -0.98380023, -0.98393744, -0.98407406,
+ -0.98421007, -0.98434556, -0.98448044, -0.98461479, -0.98474848, -0.98488164, -0.98501426, -0.98514622,
+ -0.98527765, -0.98540848, -0.98553872, -0.98566842, -0.98579752, -0.98592603, -0.98605394, -0.98618132,
+ -0.98630810, -0.98643428, -0.98655993, -0.98668492, -0.98680937, -0.98693329, -0.98705655, -0.98717928,
+ -0.98730141, -0.98742294, -0.98754394, -0.98766434, -0.98778415, -0.98790336, -0.98802203, -0.98814011,
+ -0.98825759, -0.98837447, -0.98849082, -0.98860651, -0.98872167, -0.98883629, -0.98895025, -0.98906368,
+ -0.98917651, -0.98928875, -0.98940045, -0.98951149, -0.98962200, -0.98973197, -0.98984128, -0.98995006,
+ -0.99005818, -0.99016583, -0.99027282, -0.99037921, -0.99048507, -0.99059033, -0.99069500, -0.99079913,
+ -0.99090266, -0.99100554, -0.99110794, -0.99120969, -0.99131083, -0.99141145, -0.99151146, -0.99161088,
+ -0.99170977, -0.99180800, -0.99190569, -0.99200279, -0.99209929, -0.99219525, -0.99229062, -0.99238533,
+ -0.99247956, -0.99257314, -0.99266613, -0.99275857, -0.99285042, -0.99294168, -0.99303234, -0.99312246,
+ -0.99321193, -0.99330086, -0.99338919, -0.99347699, -0.99356413, -0.99365073, -0.99373674, -0.99382216,
+ -0.99390697, -0.99399120, -0.99407488, -0.99415797, -0.99424046, -0.99432236, -0.99440366, -0.99448442,
+ -0.99456459, -0.99464417, -0.99472314, -0.99480152, -0.99487931, -0.99495655, -0.99503320, -0.99510926,
+ -0.99518472, -0.99525958, -0.99533391, -0.99540764, -0.99548078, -0.99555331, -0.99562526, -0.99569660,
+ -0.99576741, -0.99583763, -0.99590725, -0.99597627, -0.99604470, -0.99611259, -0.99617982, -0.99624652,
+ -0.99631262, -0.99637812, -0.99644303, -0.99650741, -0.99657112, -0.99663430, -0.99669689, -0.99675888,
+ -0.99682027, -0.99688113, -0.99694133, -0.99700099, -0.99706006, -0.99711853, -0.99717641, -0.99723375,
+ -0.99729043, -0.99734658, -0.99740213, -0.99745709, -0.99751145, -0.99756521, -0.99761844, -0.99767107,
+ -0.99772304, -0.99777448, -0.99782532, -0.99787563, -0.99792528, -0.99797440, -0.99802285, -0.99807078,
+ -0.99811810, -0.99816483, -0.99821103, -0.99825656, -0.99830157, -0.99834591, -0.99838972, -0.99843293,
+ -0.99847555, -0.99851763, -0.99855906, -0.99859995, -0.99864024, -0.99867994, -0.99871904, -0.99875754,
+ -0.99879545, -0.99883282, -0.99886954, -0.99890572, -0.99894130, -0.99897629, -0.99901068, -0.99904448,
+ -0.99907774, -0.99911034, -0.99914241, -0.99917388, -0.99920475, -0.99923503, -0.99926478, -0.99929386,
+ -0.99932235, -0.99935031, -0.99937767, -0.99940443, -0.99943060, -0.99945617, -0.99948120, -0.99950558,
+ -0.99952942, -0.99955267, -0.99957532, -0.99959737, -0.99961883, -0.99963969, -0.99966002, -0.99967968,
+ -0.99969882, -0.99971735, -0.99973530, -0.99975264, -0.99976939, -0.99978560, -0.99980116, -0.99981618,
+ -0.99983060, -0.99984443, -0.99985766, -0.99987030, -0.99988234, -0.99989384, -0.99990469, -0.99991500,
+ -0.99992472, -0.99993384, -0.99994236, -0.99995029, -0.99995762, -0.99996442, -0.99997061, -0.99997616,
+ -0.99998116, -0.99998558, -0.99998939, -0.99999267, -0.99999529, -0.99999738, -0.99999881, -0.99999970,
+ -1.00000000, -0.99999970, -0.99999881, -0.99999738, -0.99999529, -0.99999267, -0.99998939, -0.99998558,
+ -0.99998116, -0.99997616, -0.99997061, -0.99996442, -0.99995762, -0.99995029, -0.99994236, -0.99993384,
+ -0.99992472, -0.99991500, -0.99990469, -0.99989384, -0.99988234, -0.99987030, -0.99985766, -0.99984443,
+ -0.99983060, -0.99981618, -0.99980116, -0.99978560, -0.99976939, -0.99975264, -0.99973530, -0.99971735,
+ -0.99969882, -0.99967968, -0.99966002, -0.99963969, -0.99961883, -0.99959737, -0.99957532, -0.99955267,
+ -0.99952942, -0.99950558, -0.99948120, -0.99945617, -0.99943060, -0.99940443, -0.99937767, -0.99935031,
+ -0.99932235, -0.99929386, -0.99926478, -0.99923503, -0.99920475, -0.99917388, -0.99914241, -0.99911034,
+ -0.99907774, -0.99904448, -0.99901068, -0.99897629, -0.99894130, -0.99890572, -0.99886954, -0.99883282,
+ -0.99879545, -0.99875754, -0.99871904, -0.99867994, -0.99864024, -0.99859995, -0.99855906, -0.99851763,
+ -0.99847555, -0.99843293, -0.99838972, -0.99834591, -0.99830157, -0.99825656, -0.99821103, -0.99816483,
+ -0.99811810, -0.99807078, -0.99802285, -0.99797440, -0.99792528, -0.99787563, -0.99782532, -0.99777448,
+ -0.99772304, -0.99767107, -0.99761844, -0.99756521, -0.99751145, -0.99745709, -0.99740213, -0.99734658,
+ -0.99729043, -0.99723375, -0.99717641, -0.99711853, -0.99706006, -0.99700099, -0.99694133, -0.99688113,
+ -0.99682027, -0.99675888, -0.99669689, -0.99663430, -0.99657112, -0.99650741, -0.99644303, -0.99637812,
+ -0.99631262, -0.99624652, -0.99617982, -0.99611259, -0.99604470, -0.99597627, -0.99590725, -0.99583763,
+ -0.99576741, -0.99569660, -0.99562526, -0.99555331, -0.99548078, -0.99540764, -0.99533391, -0.99525958,
+ -0.99518472, -0.99510926, -0.99503320, -0.99495655, -0.99487931, -0.99480152, -0.99472314, -0.99464417,
+ -0.99456459, -0.99448442, -0.99440366, -0.99432236, -0.99424046, -0.99415797, -0.99407488, -0.99399120,
+ -0.99390697, -0.99382216, -0.99373674, -0.99365073, -0.99356413, -0.99347699, -0.99338919, -0.99330086,
+ -0.99321193, -0.99312246, -0.99303234, -0.99294168, -0.99285042, -0.99275857, -0.99266613, -0.99257314,
+ -0.99247956, -0.99238533, -0.99229062, -0.99219525, -0.99209929, -0.99200279, -0.99190569, -0.99180800,
+ -0.99170977, -0.99161088, -0.99151146, -0.99141145, -0.99131083, -0.99120969, -0.99110794, -0.99100554,
+ -0.99090266, -0.99079913, -0.99069500, -0.99059033, -0.99048507, -0.99037921, -0.99027282, -0.99016583,
+ -0.99005818, -0.98995006, -0.98984128, -0.98973197, -0.98962200, -0.98951149, -0.98940045, -0.98928875,
+ -0.98917651, -0.98906368, -0.98895025, -0.98883629, -0.98872167, -0.98860651, -0.98849082, -0.98837447,
+ -0.98825759, -0.98814011, -0.98802203, -0.98790336, -0.98778415, -0.98766434, -0.98754394, -0.98742294,
+ -0.98730141, -0.98717928, -0.98705655, -0.98693329, -0.98680937, -0.98668492, -0.98655993, -0.98643428,
+ -0.98630810, -0.98618132, -0.98605394, -0.98592603, -0.98579752, -0.98566842, -0.98553872, -0.98540848,
+ -0.98527765, -0.98514622, -0.98501426, -0.98488164, -0.98474848, -0.98461479, -0.98448044, -0.98434556,
+ -0.98421007, -0.98407406, -0.98393744, -0.98380023, -0.98366243, -0.98352402, -0.98338509, -0.98324561,
+ -0.98310548, -0.98296481, -0.98282355, -0.98268169, -0.98253930, -0.98239630, -0.98225272, -0.98210859,
+ -0.98196387, -0.98181856, -0.98167270, -0.98152626, -0.98137921, -0.98123157, -0.98108339, -0.98093462,
+ -0.98078525, -0.98063534, -0.98048484, -0.98033381, -0.98018211, -0.98002988, -0.97987711, -0.97972375,
+ -0.97956979, -0.97941524, -0.97926015, -0.97910446, -0.97894818, -0.97879136, -0.97863394, -0.97847593,
+ -0.97831738, -0.97815824, -0.97799850, -0.97783822, -0.97767735, -0.97751594, -0.97735387, -0.97719133,
+ -0.97702813, -0.97686440, -0.97670007, -0.97653520, -0.97636974, -0.97620368, -0.97603709, -0.97586989,
+ -0.97570211, -0.97553378, -0.97536486, -0.97519541, -0.97502536, -0.97485471, -0.97468352, -0.97451174,
+ -0.97433937, -0.97416645, -0.97399294, -0.97381890, -0.97364426, -0.97346902, -0.97329324, -0.97311687,
+ -0.97293997, -0.97276247, -0.97258437, -0.97240573, -0.97222650, -0.97204673, -0.97186631, -0.97168541,
+ -0.97150391, -0.97132182, -0.97113913, -0.97095591, -0.97077215, -0.97058779, -0.97040284, -0.97021735,
+ -0.97003126, -0.96984458, -0.96965736, -0.96946961, -0.96928126, -0.96909231, -0.96890283, -0.96871275,
+ -0.96852207, -0.96833086, -0.96813911, -0.96794677, -0.96775383, -0.96756035, -0.96736628, -0.96717167,
+ -0.96697646, -0.96678072, -0.96658438, -0.96638745, -0.96618998, -0.96599197, -0.96579337, -0.96559417,
+ -0.96539444, -0.96519411, -0.96499324, -0.96479183, -0.96458977, -0.96438724, -0.96418405, -0.96398038,
+ -0.96377605, -0.96357119, -0.96336579, -0.96315980, -0.96295327, -0.96274614, -0.96253848, -0.96233022,
+ -0.96212143, -0.96191204, -0.96170205, -0.96149158, -0.96128047, -0.96106887, -0.96085662, -0.96064389,
+ -0.96043050, -0.96021664, -0.96000212, -0.95978713, -0.95957154, -0.95935535, -0.95913863, -0.95892131,
+ -0.95870346, -0.95848507, -0.95826608, -0.95804650, -0.95782644, -0.95760572, -0.95738453, -0.95716268,
+ -0.95694035, -0.95671743, -0.95649391, -0.95626986, -0.95604527, -0.95582008, -0.95559436, -0.95536804,
+ -0.95514119, -0.95491374, -0.95468575, -0.95445722, -0.95422810, -0.95399845, -0.95376819, -0.95353740,
+ -0.95330602, -0.95307410, -0.95284164, -0.95260859, -0.95237499, -0.95214087, -0.95190614, -0.95167089,
+ -0.95143503, -0.95119864, -0.95096165, -0.95072412, -0.95048606, -0.95024747, -0.95000827, -0.94976848,
+ -0.94952816, -0.94928730, -0.94904590, -0.94880390, -0.94856137, -0.94831824, -0.94807458, -0.94783038,
+ -0.94758558, -0.94734025, -0.94709438, -0.94684792, -0.94660091, -0.94635338, -0.94610524, -0.94585657,
+ -0.94560730, -0.94535756, -0.94510722, -0.94485629, -0.94460481, -0.94435281, -0.94410026, -0.94384712,
+ -0.94359344, -0.94333923, -0.94308442, -0.94282907, -0.94257319, -0.94231677, -0.94205976, -0.94180220,
+ -0.94154406, -0.94128537, -0.94102615, -0.94076639, -0.94050604, -0.94024521, -0.93998373, -0.93972176,
+ -0.93945920, -0.93919611, -0.93893248, -0.93866831, -0.93840355, -0.93813825, -0.93787235, -0.93760598,
+ -0.93733901, -0.93707150, -0.93680346, -0.93653482, -0.93626565, -0.93599594, -0.93572569, -0.93545485,
+ -0.93518353, -0.93491161, -0.93463916, -0.93436611, -0.93409252, -0.93381846, -0.93354380, -0.93326855,
+ -0.93299282, -0.93271649, -0.93243963, -0.93216223, -0.93188429, -0.93160576, -0.93132669, -0.93104708,
+ -0.93076694, -0.93048626, -0.93020505, -0.92992324, -0.92964089, -0.92935801, -0.92907459, -0.92879063,
+ -0.92850608, -0.92822099, -0.92793542, -0.92764926, -0.92736250, -0.92707527, -0.92678750, -0.92649913,
+ -0.92621022, -0.92592078, -0.92563081, -0.92534029, -0.92504925, -0.92475760, -0.92446548, -0.92417276,
+ -0.92387950, -0.92358577, -0.92329144, -0.92299652, -0.92270112, -0.92240518, -0.92210865, -0.92181164,
+ -0.92151403, -0.92121589, -0.92091721, -0.92061806, -0.92031831, -0.92001796, -0.91971713, -0.91941577,
+ -0.91911387, -0.91881138, -0.91850841, -0.91820484, -0.91790080, -0.91759616, -0.91729099, -0.91698527,
+ -0.91667908, -0.91637230, -0.91606498, -0.91575712, -0.91544873, -0.91513979, -0.91483033, -0.91452032,
+ -0.91420978, -0.91389865, -0.91358703, -0.91327488, -0.91296220, -0.91264898, -0.91233516, -0.91202086,
+ -0.91170603, -0.91139066, -0.91107476, -0.91075826, -0.91044128, -0.91012377, -0.90980572, -0.90948713,
+ -0.90916800, -0.90884835, -0.90852809, -0.90820736, -0.90788609, -0.90756434, -0.90724200, -0.90691912,
+ -0.90659571, -0.90627176, -0.90594727, -0.90562230, -0.90529674, -0.90497071, -0.90464407, -0.90431696,
+ -0.90398932, -0.90366107, -0.90333235, -0.90300310, -0.90267330, -0.90234298, -0.90201217, -0.90168077,
+ -0.90134883, -0.90101641, -0.90068340, -0.90034992, -0.90001589, -0.89968133, -0.89934623, -0.89901060,
+ -0.89867449, -0.89833778, -0.89800060, -0.89766282, -0.89732456, -0.89698577, -0.89664650, -0.89630663,
+ -0.89596623, -0.89562535, -0.89528394, -0.89494199, -0.89459950, -0.89425647, -0.89391297, -0.89356887,
+ -0.89322430, -0.89287919, -0.89253354, -0.89218742, -0.89184070, -0.89149350, -0.89114577, -0.89079750,
+ -0.89044875, -0.89009941, -0.88974959, -0.88939923, -0.88904834, -0.88869697, -0.88834506, -0.88799256,
+ -0.88763964, -0.88728613, -0.88693213, -0.88657761, -0.88622254, -0.88586694, -0.88551086, -0.88515425,
+ -0.88479710, -0.88443947, -0.88408124, -0.88372254, -0.88336337, -0.88300359, -0.88264334, -0.88228256,
+ -0.88192129, -0.88155943, -0.88119709, -0.88083428, -0.88047087, -0.88010699, -0.87974262, -0.87937766,
+ -0.87901223, -0.87864625, -0.87827981, -0.87791282, -0.87754530, -0.87717724, -0.87680870, -0.87643969,
+ -0.87607008, -0.87570000, -0.87532938, -0.87495828, -0.87458664, -0.87421453, -0.87384182, -0.87346870,
+ -0.87309498, -0.87272078, -0.87234604, -0.87197083, -0.87159508, -0.87121886, -0.87084204, -0.87046480,
+ -0.87008697, -0.86970866, -0.86932987, -0.86895055, -0.86857069, -0.86819035, -0.86780947, -0.86742812,
+ -0.86704624, -0.86666387, -0.86628097, -0.86589754, -0.86551362, -0.86512917, -0.86474425, -0.86435878,
+ -0.86397284, -0.86358637, -0.86319941, -0.86281192, -0.86242396, -0.86203545, -0.86164647, -0.86125696,
+ -0.86086696, -0.86047643, -0.86008537, -0.85969388, -0.85930181, -0.85890925, -0.85851622, -0.85812265,
+ -0.85772860, -0.85733402, -0.85693896, -0.85654342, -0.85614735, -0.85575074, -0.85535365, -0.85495609,
+ -0.85455799, -0.85415941, -0.85376030, -0.85336071, -0.85296059, -0.85255998, -0.85215890, -0.85175729,
+ -0.85135520, -0.85095257, -0.85054946, -0.85014588, -0.84974176, -0.84933716, -0.84893203, -0.84852648,
+ -0.84812033, -0.84771377, -0.84730661, -0.84689903, -0.84649092, -0.84608233, -0.84567326, -0.84526366,
+ -0.84485358, -0.84444296, -0.84403187, -0.84362030, -0.84320825, -0.84279567, -0.84238261, -0.84196901,
+ -0.84155500, -0.84114045, -0.84072536, -0.84030986, -0.83989382, -0.83947724, -0.83906025, -0.83864272,
+ -0.83822471, -0.83780622, -0.83738720, -0.83696771, -0.83654773, -0.83612728, -0.83570629, -0.83528483,
+ -0.83486289, -0.83444041, -0.83401752, -0.83359408, -0.83317018, -0.83274579, -0.83232087, -0.83189547,
+ -0.83146960, -0.83104324, -0.83061641, -0.83018905, -0.82976121, -0.82933295, -0.82890409, -0.82847482,
+ -0.82804507, -0.82761478, -0.82718402, -0.82675278, -0.82632107, -0.82588887, -0.82545614, -0.82502300,
+ -0.82458931, -0.82415515, -0.82372051, -0.82328540, -0.82284981, -0.82241368, -0.82197714, -0.82154006,
+ -0.82110250, -0.82066447, -0.82022595, -0.81978697, -0.81934750, -0.81890756, -0.81846714, -0.81802619,
+ -0.81758481, -0.81714290, -0.81670058, -0.81625772, -0.81581444, -0.81537062, -0.81492633, -0.81448156,
+ -0.81403631, -0.81359059, -0.81314439, -0.81269777, -0.81225061, -0.81180298, -0.81135488, -0.81090623,
+ -0.81045717, -0.81000763, -0.80955762, -0.80910712, -0.80865616, -0.80820471, -0.80775285, -0.80730045,
+ -0.80684757, -0.80639422, -0.80594039, -0.80548608, -0.80503136, -0.80457610, -0.80412036, -0.80366421,
+ -0.80320752, -0.80275041, -0.80229282, -0.80183470, -0.80137616, -0.80091715, -0.80045766, -0.79999769,
+ -0.79953724, -0.79907638, -0.79861498, -0.79815316, -0.79769087, -0.79722804, -0.79676479, -0.79630107,
+ -0.79583693, -0.79537225, -0.79490715, -0.79444152, -0.79397547, -0.79350895, -0.79304194, -0.79257452,
+ -0.79210657, -0.79163820, -0.79116935, -0.79070002, -0.79023021, -0.78975999, -0.78928924, -0.78881806,
+ -0.78834641, -0.78787434, -0.78740174, -0.78692871, -0.78645521, -0.78598124, -0.78550684, -0.78503191,
+ -0.78455657, -0.78408080, -0.78360450, -0.78312778, -0.78265059, -0.78217292, -0.78169483, -0.78121626,
+ -0.78073722, -0.78025776, -0.77977777, -0.77929735, -0.77881652, -0.77833521, -0.77785343, -0.77737117,
+ -0.77688849, -0.77640533, -0.77592170, -0.77543765, -0.77495313, -0.77446812, -0.77398270, -0.77349681,
+ -0.77301043, -0.77252364, -0.77203637, -0.77154869, -0.77106053, -0.77057189, -0.77008283, -0.76959330,
+ -0.76910335, -0.76861292, -0.76812202, -0.76763070, -0.76713890, -0.76664668, -0.76615399, -0.76566088,
+ -0.76516724, -0.76467323, -0.76417875, -0.76368380, -0.76318842, -0.76269257, -0.76219630, -0.76169956,
+ -0.76120239, -0.76070476, -0.76020670, -0.75970817, -0.75920922, -0.75870979, -0.75820988, -0.75770962,
+ -0.75720882, -0.75670767, -0.75620598, -0.75570393, -0.75520140, -0.75469840, -0.75419497, -0.75369114,
+ -0.75318682, -0.75268203, -0.75217682, -0.75167120, -0.75116515, -0.75065863, -0.75015163, -0.74964422,
+ -0.74913639, -0.74862808, -0.74811935, -0.74761021, -0.74710059, -0.74659055, -0.74608010, -0.74556917,
+ -0.74505776, -0.74454600, -0.74403375, -0.74352109, -0.74300796, -0.74249440, -0.74198043, -0.74146599,
+ -0.74095112, -0.74043584, -0.73992008, -0.73940390, -0.73888731, -0.73837030, -0.73785281, -0.73733491,
+ -0.73681659, -0.73629779, -0.73577857, -0.73525894, -0.73473889, -0.73421836, -0.73369741, -0.73317605,
+ -0.73265427, -0.73213202, -0.73160940, -0.73108631, -0.73056275, -0.73003882, -0.72951442, -0.72898960,
+ -0.72846437, -0.72793871, -0.72741264, -0.72688609, -0.72635913, -0.72583181, -0.72530395, -0.72477573,
+ -0.72424710, -0.72371799, -0.72318846, -0.72265857, -0.72212821, -0.72159743, -0.72106618, -0.72053456,
+ -0.72000253, -0.71947002, -0.71893710, -0.71840382, -0.71787006, -0.71733588, -0.71680129, -0.71626627,
+ -0.71573085, -0.71519494, -0.71465868, -0.71412200, -0.71358484, -0.71304733, -0.71250939, -0.71197098,
+ -0.71143222, -0.71089298, -0.71035337, -0.70981330, -0.70927280, -0.70873195, -0.70819062, -0.70764893,
+ -0.70710677, -0.70656425, -0.70602125, -0.70547789, -0.70493406, -0.70438987, -0.70384526, -0.70330018,
+ -0.70275474, -0.70220888, -0.70166260, -0.70111591, -0.70056880, -0.70002127, -0.69947332, -0.69892502,
+ -0.69837624, -0.69782710, -0.69727749, -0.69672751, -0.69617712, -0.69562632, -0.69507509, -0.69452351,
+ -0.69397146, -0.69341904, -0.69286615, -0.69231290, -0.69175923, -0.69120520, -0.69065070, -0.69009584,
+ -0.68954057, -0.68898487, -0.68842876, -0.68787223, -0.68731534, -0.68675804, -0.68620032, -0.68564218,
+ -0.68508369, -0.68452471, -0.68396538, -0.68340570, -0.68284553, -0.68228501, -0.68172407, -0.68116271,
+ -0.68060100, -0.68003887, -0.67947632, -0.67891335, -0.67835003, -0.67778629, -0.67722219, -0.67665762,
+ -0.67609268, -0.67552739, -0.67496163, -0.67439550, -0.67382902, -0.67326206, -0.67269474, -0.67212707,
+ -0.67155898, -0.67099047, -0.67042154, -0.66985226, -0.66928262, -0.66871250, -0.66814202, -0.66757119,
+ -0.66699994, -0.66642827, -0.66585624, -0.66528380, -0.66471100, -0.66413778, -0.66356415, -0.66299015,
+ -0.66241580, -0.66184098, -0.66126585, -0.66069031, -0.66011435, -0.65953803, -0.65896130, -0.65838420,
+ -0.65780669, -0.65722883, -0.65665054, -0.65607190, -0.65549284, -0.65491343, -0.65433359, -0.65375340,
+ -0.65317285, -0.65259188, -0.65201056, -0.65142882, -0.65084666, -0.65026420, -0.64968133, -0.64909804,
+ -0.64851439, -0.64793038, -0.64734596, -0.64676118, -0.64617604, -0.64559048, -0.64500451, -0.64441824,
+ -0.64383155, -0.64324450, -0.64265704, -0.64206922, -0.64148104, -0.64089245, -0.64030349, -0.63971418,
+ -0.63912445, -0.63853437, -0.63794392, -0.63735306, -0.63676184, -0.63617027, -0.63557833, -0.63498598,
+ -0.63439327, -0.63380021, -0.63320678, -0.63261294, -0.63201874, -0.63142419, -0.63082922, -0.63023394,
+ -0.62963825, -0.62904221, -0.62844574, -0.62784898, -0.62725180, -0.62665427, -0.62605637, -0.62545812,
+ -0.62485951, -0.62426049, -0.62366110, -0.62306136, -0.62246126, -0.62186080, -0.62125999, -0.62065876,
+ -0.62005723, -0.61945528, -0.61885297, -0.61825031, -0.61764729, -0.61704391, -0.61644018, -0.61583608,
+ -0.61523157, -0.61462677, -0.61402154, -0.61341602, -0.61281008, -0.61220378, -0.61159718, -0.61099017,
+ -0.61038280, -0.60977507, -0.60916704, -0.60855860, -0.60794979, -0.60734063, -0.60673112, -0.60612124,
+ -0.60551107, -0.60490048, -0.60428953, -0.60367823, -0.60306662, -0.60245460, -0.60184222, -0.60122955,
+ -0.60061646, -0.60000306, -0.59938931, -0.59877521, -0.59816068, -0.59754586, -0.59693068, -0.59631521,
+ -0.59569931, -0.59508306, -0.59446651, -0.59384960, -0.59323227, -0.59261465, -0.59199667, -0.59137839,
+ -0.59075969, -0.59014070, -0.58952129, -0.58890158, -0.58828157, -0.58766115, -0.58704036, -0.58641928,
+ -0.58579785, -0.58517605, -0.58455396, -0.58393145, -0.58330864, -0.58268547, -0.58206201, -0.58143812,
+ -0.58081394, -0.58018941, -0.57956457, -0.57893932, -0.57831377, -0.57768792, -0.57706165, -0.57643509,
+ -0.57580817, -0.57518095, -0.57455337, -0.57392544, -0.57329714, -0.57266855, -0.57203960, -0.57141036,
+ -0.57078075, -0.57015079, -0.56952053, -0.56888992, -0.56825894, -0.56762767, -0.56699604, -0.56636411,
+ -0.56573182, -0.56509918, -0.56446624, -0.56383294, -0.56319934, -0.56256539, -0.56193113, -0.56129652,
+ -0.56066155, -0.56002629, -0.55939072, -0.55875480, -0.55811852, -0.55748194, -0.55684501, -0.55620778,
+ -0.55557024, -0.55493236, -0.55429411, -0.55365556, -0.55301672, -0.55237752, -0.55173796, -0.55109817,
+ -0.55045795, -0.54981750, -0.54917663, -0.54853553, -0.54789406, -0.54725230, -0.54661018, -0.54596776,
+ -0.54532498, -0.54468191, -0.54403853, -0.54339480, -0.54275078, -0.54210645, -0.54146177, -0.54081678,
+ -0.54017144, -0.53952587, -0.53887993, -0.53823364, -0.53758705, -0.53694016, -0.53629297, -0.53564548,
+ -0.53499764, -0.53434944, -0.53370100, -0.53305221, -0.53240311, -0.53175372, -0.53110403, -0.53045398,
+ -0.52980363, -0.52915299, -0.52850199, -0.52785075, -0.52719915, -0.52654725, -0.52589500, -0.52524251,
+ -0.52458966, -0.52393657, -0.52328312, -0.52262938, -0.52197528, -0.52132094, -0.52066624, -0.52001125,
+ -0.51935601, -0.51870042, -0.51804453, -0.51738828, -0.51673180, -0.51607502, -0.51541787, -0.51476043,
+ -0.51410276, -0.51344472, -0.51278639, -0.51212776, -0.51146883, -0.51080960, -0.51015007, -0.50949025,
+ -0.50883013, -0.50816971, -0.50750899, -0.50684798, -0.50618666, -0.50552505, -0.50486308, -0.50420088,
+ -0.50353837, -0.50287557, -0.50221246, -0.50154907, -0.50088537, -0.50022137, -0.49955711, -0.49889255,
+ -0.49822766, -0.49756250, -0.49689704, -0.49623129, -0.49556527, -0.49489895, -0.49423230, -0.49356541,
+ -0.49289820, -0.49223071, -0.49156290, -0.49089485, -0.49022648, -0.48955783, -0.48888889, -0.48821968,
+ -0.48755017, -0.48688036, -0.48621029, -0.48553991, -0.48486924, -0.48419830, -0.48352706, -0.48285556,
+ -0.48218378, -0.48151168, -0.48083934, -0.48016667, -0.47949377, -0.47882056, -0.47814706, -0.47747329,
+ -0.47679922, -0.47612488, -0.47545028, -0.47477537, -0.47410020, -0.47342476, -0.47274902, -0.47207302,
+ -0.47139674, -0.47072017, -0.47004333, -0.46936622, -0.46868882, -0.46801114, -0.46733320, -0.46665499,
+ -0.46597651, -0.46529773, -0.46461868, -0.46393937, -0.46325979, -0.46257994, -0.46189979, -0.46121940,
+ -0.46053872, -0.45985776, -0.45917654, -0.45849505, -0.45781329, -0.45713127, -0.45644897, -0.45576641,
+ -0.45508358, -0.45440048, -0.45371711, -0.45303348, -0.45234957, -0.45166543, -0.45098099, -0.45029628,
+ -0.44961134, -0.44892609, -0.44824061, -0.44755486, -0.44686884, -0.44618255, -0.44549602, -0.44480920,
+ -0.44412214, -0.44343480, -0.44274724, -0.44205937, -0.44137126, -0.44068289, -0.43999428, -0.43930539,
+ -0.43861625, -0.43792683, -0.43723717, -0.43654725, -0.43585709, -0.43516666, -0.43447596, -0.43378502,
+ -0.43309382, -0.43240237, -0.43171066, -0.43101871, -0.43032649, -0.42963400, -0.42894128, -0.42824832,
+ -0.42755508, -0.42686161, -0.42616788, -0.42547390, -0.42477968, -0.42408520, -0.42339048, -0.42269549,
+ -0.42200026, -0.42130479, -0.42060909, -0.41991311, -0.41921690, -0.41852042, -0.41782370, -0.41712677,
+ -0.41642955, -0.41573212, -0.41503441, -0.41433650, -0.41363832, -0.41293988, -0.41224122, -0.41154233,
+ -0.41084316, -0.41014379, -0.40944415, -0.40874428, -0.40804416, -0.40734380, -0.40664321, -0.40594238,
+ -0.40524131, -0.40454000, -0.40383846, -0.40313667, -0.40243465, -0.40173239, -0.40102988, -0.40032718,
+ -0.39962420, -0.39892101, -0.39821756, -0.39751390, -0.39681000, -0.39610586, -0.39540148, -0.39469686,
+ -0.39399204, -0.39328697, -0.39258167, -0.39187613, -0.39117038, -0.39046440, -0.38975817, -0.38905174,
+ -0.38834503, -0.38763815, -0.38693100, -0.38622364, -0.38551605, -0.38480824, -0.38410020, -0.38339192,
+ -0.38268343, -0.38197473, -0.38126576, -0.38055661, -0.37984720, -0.37913761, -0.37842774, -0.37771770,
+ -0.37700742, -0.37629691, -0.37558618, -0.37487522, -0.37416407, -0.37345266, -0.37274107, -0.37202924,
+ -0.37131721, -0.37060493, -0.36989245, -0.36917976, -0.36846682, -0.36775368, -0.36704034, -0.36632678,
+ -0.36561298, -0.36489901, -0.36418480, -0.36347038, -0.36275572, -0.36204088, -0.36132580, -0.36061051,
+ -0.35989505, -0.35917935, -0.35846341, -0.35774729, -0.35703096, -0.35631442, -0.35559767, -0.35488069,
+ -0.35416353, -0.35344616, -0.35272855, -0.35201076, -0.35129276, -0.35057455, -0.34985614, -0.34913751,
+ -0.34841868, -0.34769964, -0.34698042, -0.34626096, -0.34554133, -0.34482148, -0.34410143, -0.34338117,
+ -0.34266073, -0.34194008, -0.34121922, -0.34049815, -0.33977687, -0.33905542, -0.33833376, -0.33761191,
+ -0.33688986, -0.33616760, -0.33544514, -0.33472249, -0.33399966, -0.33327660, -0.33255336, -0.33182994,
+ -0.33110631, -0.33038250, -0.32965845, -0.32893425, -0.32820985, -0.32748523, -0.32676044, -0.32603547,
+ -0.32531029, -0.32458493, -0.32385936, -0.32313362, -0.32240769, -0.32168156, -0.32095525, -0.32022873,
+ -0.31950203, -0.31877515, -0.31804809, -0.31732082, -0.31659338, -0.31586576, -0.31513792, -0.31440994,
+ -0.31368175, -0.31295338, -0.31222481, -0.31149608, -0.31076714, -0.31003806, -0.30930877, -0.30857930,
+ -0.30784965, -0.30711982, -0.30638981, -0.30565959, -0.30492923, -0.30419868, -0.30346796, -0.30273703,
+ -0.30200595, -0.30127469, -0.30054325, -0.29981163, -0.29907984, -0.29834786, -0.29761571, -0.29688337,
+ -0.29615089, -0.29541820, -0.29468536, -0.29395235, -0.29321915, -0.29248580, -0.29175225, -0.29101855,
+ -0.29028466, -0.28955063, -0.28881642, -0.28808203, -0.28734747, -0.28661272, -0.28587782, -0.28514278,
+ -0.28440753, -0.28367212, -0.28293657, -0.28220084, -0.28146493, -0.28072888, -0.27999264, -0.27925625,
+ -0.27851969, -0.27778298, -0.27704608, -0.27630904, -0.27557182, -0.27483445, -0.27409691, -0.27335921,
+ -0.27262136, -0.27188334, -0.27114516, -0.27040681, -0.26966831, -0.26892966, -0.26819086, -0.26745188,
+ -0.26671275, -0.26597348, -0.26523402, -0.26449442, -0.26375467, -0.26301476, -0.26227471, -0.26153448,
+ -0.26079410, -0.26005360, -0.25931293, -0.25857207, -0.25783110, -0.25708997, -0.25634867, -0.25560725,
+ -0.25486565, -0.25412393, -0.25338203, -0.25264001, -0.25189781, -0.25115550, -0.25041300, -0.24967039,
+ -0.24892761, -0.24818468, -0.24744162, -0.24669841, -0.24595505, -0.24521154, -0.24446790, -0.24372411,
+ -0.24298018, -0.24223611, -0.24149188, -0.24074753, -0.24000302, -0.23925838, -0.23851359, -0.23776866,
+ -0.23702361, -0.23627840, -0.23553306, -0.23478758, -0.23404196, -0.23329620, -0.23255031, -0.23180428,
+ -0.23105811, -0.23031181, -0.22956537, -0.22881879, -0.22807208, -0.22732525, -0.22657827, -0.22583115,
+ -0.22508392, -0.22433653, -0.22358903, -0.22284140, -0.22209363, -0.22134572, -0.22059768, -0.21984953,
+ -0.21910124, -0.21835282, -0.21760428, -0.21685560, -0.21610680, -0.21535787, -0.21460882, -0.21385963,
+ -0.21311031, -0.21236089, -0.21161133, -0.21086164, -0.21011184, -0.20936191, -0.20861185, -0.20786168,
+ -0.20711137, -0.20636095, -0.20561041, -0.20485975, -0.20410897, -0.20335807, -0.20260704, -0.20185590,
+ -0.20110464, -0.20035325, -0.19960175, -0.19885014, -0.19809841, -0.19734657, -0.19659460, -0.19584252,
+ -0.19509032, -0.19433801, -0.19358559, -0.19283305, -0.19208039, -0.19132763, -0.19057475, -0.18982176,
+ -0.18906866, -0.18831545, -0.18756212, -0.18680869, -0.18605515, -0.18530150, -0.18454774, -0.18379387,
+ -0.18303989, -0.18228580, -0.18153161, -0.18077731, -0.18002290, -0.17926839, -0.17851377, -0.17775905,
+ -0.17700422, -0.17624930, -0.17549425, -0.17473911, -0.17398387, -0.17322853, -0.17247309, -0.17171754,
+ -0.17096189, -0.17020614, -0.16945030, -0.16869435, -0.16793829, -0.16718215, -0.16642590, -0.16566956,
+ -0.16491312, -0.16415659, -0.16339995, -0.16264322, -0.16188639, -0.16112947, -0.16037245, -0.15961535,
+ -0.15885815, -0.15810084, -0.15734346, -0.15658598, -0.15582840, -0.15507074, -0.15431297, -0.15355512,
+ -0.15279719, -0.15203916, -0.15128104, -0.15052283, -0.14976454, -0.14900614, -0.14824767, -0.14748912,
+ -0.14673047, -0.14597175, -0.14521292, -0.14445402, -0.14369503, -0.14293596, -0.14217681, -0.14141756,
+ -0.14065824, -0.13989884, -0.13913934, -0.13837977, -0.13762012, -0.13686039, -0.13610058, -0.13534068,
+ -0.13458070, -0.13382065, -0.13306053, -0.13230032, -0.13154003, -0.13077967, -0.13001922, -0.12925871,
+ -0.12849811, -0.12773745, -0.12697670, -0.12621588, -0.12545498, -0.12469402, -0.12393297, -0.12317186,
+ -0.12241068, -0.12164941, -0.12088808, -0.12012669, -0.11936522, -0.11860368, -0.11784206, -0.11708038,
+ -0.11631863, -0.11555681, -0.11479492, -0.11403298, -0.11327095, -0.11250886, -0.11174671, -0.11098449,
+ -0.11022221, -0.10945985, -0.10869744, -0.10793497, -0.10717242, -0.10640982, -0.10564715, -0.10488442,
+ -0.10412163, -0.10335878, -0.10259587, -0.10183290, -0.10106986, -0.10030677, -0.09954362, -0.09878041,
+ -0.09801714, -0.09725381, -0.09649043, -0.09572699, -0.09496350, -0.09419994, -0.09343634, -0.09267268,
+ -0.09190895, -0.09114519, -0.09038136, -0.08961748, -0.08885355, -0.08808957, -0.08732554, -0.08656145,
+ -0.08579731, -0.08503313, -0.08426889, -0.08350460, -0.08274026, -0.08197588, -0.08121145, -0.08044697,
+ -0.07968244, -0.07891786, -0.07815325, -0.07738858, -0.07662386, -0.07585911, -0.07509430, -0.07432945,
+ -0.07356457, -0.07279963, -0.07203465, -0.07126963, -0.07050458, -0.06973947, -0.06897433, -0.06820914,
+ -0.06744392, -0.06667866, -0.06591335, -0.06514801, -0.06438263, -0.06361721, -0.06285176, -0.06208627,
+ -0.06132074, -0.06055517, -0.05978957, -0.05902394, -0.05825827, -0.05749256, -0.05672682, -0.05596105,
+ -0.05519525, -0.05442941, -0.05366354, -0.05289764, -0.05213170, -0.05136574, -0.05059975, -0.04983373,
+ -0.04906768, -0.04830159, -0.04753548, -0.04676935, -0.04600318, -0.04523699, -0.04447077, -0.04370453,
+ -0.04293826, -0.04217196, -0.04140564, -0.04063930, -0.03987293, -0.03910654, -0.03834012, -0.03757368,
+ -0.03680722, -0.03604074, -0.03527424, -0.03450771, -0.03374117, -0.03297461, -0.03220803, -0.03144142,
+ -0.03067480, -0.02990817, -0.02914151, -0.02837484, -0.02760815, -0.02684144, -0.02607472, -0.02530798,
+ -0.02454123, -0.02377446, -0.02300768, -0.02224089, -0.02147408, -0.02070726, -0.01994043, -0.01917358,
+ -0.01840673, -0.01763986, -0.01687299, -0.01610610, -0.01533921, -0.01457230, -0.01380539, -0.01303847,
+ -0.01227154, -0.01150460, -0.01073766, -0.00997071, -0.00920375, -0.00843679, -0.00766983, -0.00690286,
+ -0.00613588, -0.00536891, -0.00460193, -0.00383494, -0.00306796, -0.00230097, -0.00153398, -0.00076699
+ };
+#endif
+ \ No newline at end of file
diff --git a/testsuites/isvv/shared/utils.c b/testsuites/isvv/shared/utils.c
new file mode 100644
index 0000000000..46b2321458
--- /dev/null
+++ b/testsuites/isvv/shared/utils.c
@@ -0,0 +1,397 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+#include <rtems/bspIo.h>
+#include <string.h>
+#include "utils.h"
+#include "isvv_rtems_aux.h"
+
+uint8_t TEST_SET[IMAGE_WIDTH][IMAGE_HEIGHT];
+
+void Loop(int16_t x) {
+ volatile int i;
+ for (i=0; i<100000* x; i++);
+}
+
+uint32_t crc32(const uint8_t *s,size_t n)
+{
+ uint32_t crc=0xFFFFFFFF;
+ for(size_t i=0;i<n;i++) {
+ char ch=s[i];
+ for(size_t j=0;j<8;j++) {
+ uint32_t b=(ch^crc)&1;
+ crc>>=1;
+ if(b) crc=crc^0xEDB88320;
+ ch>>=1;
+ }
+ }
+
+ return ~crc;
+}
+
+/* to print results */
+void print_test_results(void)
+{
+ char str[8*sizeof(uint32_t)+1];
+ uint32_t crc = crc32((uint8_t *)&TEST_SET[0][0], sizeof(TEST_SET));
+ print_string("Begin set {\n");
+ print_string("0x");
+ print_string(itoa(crc, &str[0], 16));
+ // print_string("P6 \n");
+ // print_string(itoa(IMAGE_WIDTH, &str[0], 10));
+ // print_string(" ");
+ // print_string(itoa(IMAGE_HEIGHT, &str[0], 10));
+ // print_string("\n255\n");
+ // for(int j= 0; j<IMAGE_HEIGHT; j++ )
+ // {
+ // for(int i = 0; i<IMAGE_WIDTH; i++ )
+ // {
+ // if (TEST_SET[i][j] < 16)
+ // {
+ // print_string("0");
+ // print_string(itoa(TEST_SET[i][j], &str[0], 16));
+ // }
+ // else
+ // print_string(itoa(TEST_SET[i][j], &str[0], 16));
+ // // print_string((char)TEST_SET[i][j]);
+ // //block of code to generate output to a .ppm file
+ // // if (TEST_SET[i][j]<50) color(0,0,0);
+ // // else if( TEST_SET[i][j]<100) color(5,5,5);
+ // // else if (TEST_SET[i][j]<150) color(0,0,255);
+ // // else if (TEST_SET[i][j]<255) color(255,255,255);
+ // // else color(180,0,0);
+ // }
+ // }
+ print_string("\n} End set\n");
+}
+
+//function to print on unsigned char rgb format to generate the
+//output to a .ppm file
+void color(uint8_t red, uint8_t green, uint8_t blue)
+{
+ BSP_output_char((unsigned char)red);
+ BSP_output_char((unsigned char)green);
+ BSP_output_char((unsigned char)blue);
+}
+
+// return the lentgh of a string
+size_t str_len (const char *str)
+{
+ const char *s = str;
+ while (*s) s++;
+ return s - str;
+}
+
+//print a string
+void print_string(const char *string)
+{
+ char *s;
+ size_t i=0;
+ s = (char *) string;
+
+ while (i<str_len(s))
+ {
+ BSP_output_char(s[i]);
+ ++i;
+ }
+}
+
+// swap two chars
+void swap (char *x, char *y)
+{
+ char temp = *x;
+ *x = *y;
+ *y = temp;
+}
+
+
+// function to reverse the order of an array/a string
+void reverse(char str[], int length)
+{
+ int start = 0;
+ int end = length - 1;
+ while (start < end)
+ {
+ swap(&str[start], &str[end]);
+ start++;
+ end--;
+ }
+}
+
+// Implementation of itoa()
+char* itoa(int num, char* str, int base)
+{
+ uint32_t i = 0;
+ bool isNegative = false;
+ uint32_t u32num = (uint32_t) num;
+ uint32_t u32base = (uint32_t) base;
+
+ /* Handle 0 explicitly, otherwise empty string is printed for 0 */
+ if (num == 0)
+ {
+ str[i++] = '0';
+ str[i] = '\0';
+ return str;
+ }
+
+ // In standard itoa(), negative numbers are handled only with
+ // base 10. Otherwise numbers are considered unsigned.
+ if (num < 0 && base == 10)
+ {
+ // -2^31 is a special case, and needs to be treated diferently
+ if (num == -2147483648)
+ {
+ memcpy(str,"-2147483648", str_len("-2147483648"));
+ return str;
+ }
+ isNegative = true;
+ u32num = (uint32_t) (-num);
+ }
+
+ // Process individual digits
+ while (u32num != 0)
+ {
+ uint32_t u32rem = u32num % u32base;
+ str[i++] = (u32rem > 9)? (u32rem-10) + 'a' : u32rem + '0';
+ u32num = u32num/u32base;
+ }
+
+ // If number is negative, append '-'
+ if (isNegative)
+ str[i++] = '-';
+
+ str[i] = '\0'; // Append string terminator
+
+ // Reverse the string
+ reverse(str, str_len(str));
+
+ return str;
+}
+
+// Function to calc mandelbrot set
+void mandelbrot_tile(uint8_t tile, uint8_t tiles)
+{
+ float zx, zy, x_zero, tempx, y_zero;
+ uint16_t iteration, y_min_tile, y_max_tile;
+
+ // setting first and last point of the tile
+ y_min_tile = ( IMAGE_HEIGHT/tiles ) * (tile - 1);
+ y_max_tile = tile < tiles ? (IMAGE_HEIGHT / tiles) * tile : IMAGE_HEIGHT;
+
+ // scanning every point in the tile
+ for (uint16_t x = 0; x < IMAGE_WIDTH; x++)
+ {
+ x_zero = (x * SCALE_X)+ LEFT;
+ for (uint16_t y = y_min_tile; y < y_max_tile; y++)
+ {
+ //scaling to lie in the mandelbrot scale
+ y_zero = (y * SCALE_Y) + TOP;
+
+ //iterations need to be reset before calculations for each point
+ zx = 0;
+ zy = 0;
+ iteration = 0;
+
+ // Calculate whether belongs to the Mandelbrot set or not
+ while ((zx * zx + zy * zy < 4) && (iteration < MAXITERATION))
+ {
+ // Calculate Mandelbrot function
+ // z = z*z + c where z is a complex number
+ tempx = zx * zx - zy * zy + x_zero;
+ zy = 2 * zx * zy + y_zero;
+ zx = tempx;
+
+ iteration = iteration + 1;
+ }
+ TEST_SET[x][y]=iteration;
+ }
+ }
+}
+
+// Dumb implementation of primality test
+bool is_prime(uint64_t p)
+{
+ if (2 == p)
+ return TRUE;
+ else if ((1 >= p) || (0 == (p % 2)))
+ return FALSE;
+ else
+ {
+ bool prime = TRUE;
+ const uint32_t to = p / 2;
+ for (uint32_t i = 3; i <= to; i += 2)
+ {
+ if (0 == (p % i)) {
+ prime = false;
+ break;
+ }
+ }
+ return prime;
+ }
+}
+
+bool is_mersenne_prime(uint64_t p)
+{
+ if (2 == p)
+ return TRUE;
+ else if (p >= 64)
+ {
+ // Using this to make sure we don't run into any undefined behaviour
+ // When left-shifting bits by greater than the set amount
+ // The object of this function isn't necessarily to get the correct value for any given integer
+ // Just to stress the the CPU while utilising lots of execution time to assert robustness
+ return false;
+ }
+ else
+ {
+ const uint64_t m_p = (1LLU << p) - 1;
+ uint64_t s = 4;
+ uint64_t i;
+ for (i = 3; i <= p; i++)
+ {
+ s = (s * s - 2) % m_p;
+ }
+ return 0 == s;
+ }
+}
+
+// Dumb implementation of power function for small numbers
+uint64_t power (uint16_t num, uint16_t exp) {
+ uint64_t total = 1;
+ for (uint16_t i = 0; i < exp; i++) {
+ total *= num;
+ }
+ return total;
+}
+
+uint32_t isqrt(uint32_t val) {
+ uint32_t temp, g = 0U, b = 0x8000U, bshft = 15U;
+ do {
+ if (val >= (temp = (((g << 1) + b)<<bshft--))) {
+ g += b;
+ val -= temp;
+ }
+ } while (b >>= 1);
+ return g;
+}
+
+
+//-----------------------------------------------------------------------------
+// Functions related with signal processing
+//-----------------------------------------------------------------------------
+
+static void swapf(float *x, float *y){
+ float temp = *x;
+ *x = *y;
+ *y = temp;
+}
+
+static uint32_t bits_reverse(uint32_t val, int width) {
+ uint32_t result = 0;
+ for (int i = 0; i < width; i++, val >>= 1)
+ result = (result << 1) | (val & 1U);
+ return result;
+}
+
+float cos_aprox(float arg) {
+ // arg must be between 0 and 2*PI
+ uint32_t idx = (uint32_t)(arg/(2*PI)*FFT_TABLE_SIZE);
+ float ro = (arg/(2*PI)*FFT_TABLE_SIZE)-(float)idx;
+ // using liner interpolation in the case that the given arg does not match exactly with a direct table entry
+ return cosTable[idx%FFT_TABLE_SIZE] + ro*(cosTable[(idx+1)%FFT_TABLE_SIZE]-cosTable[idx%FFT_TABLE_SIZE]);
+}
+
+float sin_aprox(float arg) {
+ // arg must be between 0 and 2*PI
+ uint32_t idx = (uint32_t)(arg/(2*PI)*FFT_TABLE_SIZE);
+ float ro = (arg/(2*PI)*FFT_TABLE_SIZE)-(float)idx;
+ // using liner interpolation in the case that the given arg does not match exactly with a direct table entry
+ return sinTable[idx%FFT_TABLE_SIZE] + ro*(sinTable[(idx+1)%FFT_TABLE_SIZE]-sinTable[idx%FFT_TABLE_SIZE]);
+}
+
+float blackman_harris(int n, int N){
+ float a0, a1, a2, a3, seg1, seg2, seg3, w_n;
+ a0 = 0.35875f;
+ a1 = 0.48829f;
+ a2 = 0.14128f;
+ a3 = 0.01168f;
+
+ seg1 = a1 * (float) cos_aprox((float)(2*PI*n)/(float) (N - 1));
+ seg2 = a2 * (float) cos_aprox((float)(4*PI*n)/(float) (N - 1));
+ seg3 = a3 * (float) cos_aprox((float)(6*PI*n)/(float) (N - 1));
+
+ w_n = a0 - seg1 + seg2 - seg3;
+
+ return w_n;
+}
+
+void fft( float *inReal, float *inImag, uint32_t log2_N ){
+ const uint32_t N = 1 << log2_N;
+
+ // Bits-reversed
+ for (uint32_t i = 0; i < N; i++) {
+ uint32_t j = bits_reverse(i, log2_N);
+ if (j > i) {
+ swapf(&inReal[i], &inReal[j]);
+ swapf(&inImag[i], &inImag[j]);
+ }
+ }
+
+ // Cooley-Tukey radix-2 FFT
+ for (uint32_t size = 2; size <= N; size *= 2) {
+ for (uint32_t i = 0; i < N; i += size) {
+ uint32_t k=0;
+ for (uint32_t j = i; j < i + size/2; j++) {
+ float a_real = inReal[j];
+ float a_imag = inImag[j];
+ float b_real = inReal[j+size/2];
+ float b_imag = inImag[j+size/2];
+ float twiddle_real = cos_aprox(2.0*PI*(float)k/(float)N);
+ float twiddle_imag = sin_aprox(2.0*PI*(float)k/(float)N);
+
+ float bias_real = b_real * twiddle_real + b_imag * twiddle_imag;
+ float bias_imag = -b_real * twiddle_imag + b_imag * twiddle_real;
+ inReal[j+size/2] = a_real - bias_real;
+ inImag[j+size/2] = a_imag - bias_imag;
+ inReal[j] = a_real + bias_real;
+ inImag[j] = a_imag + bias_imag;
+ k += N/size;
+ }
+ }
+ }
+}
+
+
+float noise_generator(uint32_t seed) {
+ static uint32_t lfsr = 0xE3F5828U;
+ if (seed != 0) { lfsr = seed; }
+ /* taps: 32,22,2,1; feedback polynomial : x^32 + x^22 + x^2 + x^1 + 1 */
+ uint32_t bit = ((lfsr >> 0) ^ (lfsr >> 10) ^ (lfsr >> 30) ^ (lfsr >> 31)) & 1u;
+ lfsr = (lfsr >> 1) | (bit << 31);
+ return (((float)lfsr / (float)UINT32_MAX) - 0.5f);
+}
+
diff --git a/testsuites/isvv/shared/utils.h b/testsuites/isvv/shared/utils.h
new file mode 100644
index 0000000000..3de91eb3a9
--- /dev/null
+++ b/testsuites/isvv/shared/utils.h
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/*
+ * Copyright (C) 2022 Critical Software SA
+ *
+ * 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.
+ */
+
+/*
+ * Calculates the mandebroot set
+*/
+#include <rtems.h>
+#include "trig_tables.h"
+
+#ifdef gr740
+ #define TEST_PROCESSORS 4
+#endif
+#ifdef gr712rc
+ #define TEST_PROCESSORS 2
+#endif
+
+#define MAXITERATION 255
+#define IMAGE_WIDTH 2250
+#define IMAGE_HEIGHT 2250
+
+#define LEFT -2.00 //x max value
+#define SIDE_X 2.47 //x range (xmax-xmin)
+#define TOP 1.12 //y max value
+#define SIDE_Y -2.24 //y range (ymax-ymin)
+#define SCALE_X (SIDE_X / IMAGE_WIDTH)
+#define SCALE_Y (SIDE_Y / IMAGE_HEIGHT)
+
+#define ASSERT_SUCCESS(sc) \
+ do { \
+ if ((sc) != RTEMS_SUCCESSFUL) \
+ { \
+ print_string(rtems_status_text(sc)); \
+ print_string("\n"); \
+ rtems_fatal(RTEMS_FATAL_SOURCE_EXIT, __LINE__); \
+ } \
+ } while (0)
+
+#define ASSERT_SUCCESS_WITHOUT_FAILING(sc) \
+ do { \
+ if ((sc) != RTEMS_SUCCESSFUL) \
+ { \
+ print_string(rtems_status_text(sc)); \
+ print_string("\n"); \
+ } \
+ } while (0)
+
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+
+void Loop(int16_t x);
+
+uint32_t crc32(const uint8_t *s,size_t n);
+
+void print_test_results(void);
+
+void color(uint8_t red, uint8_t green, uint8_t blue);
+
+size_t str_len (const char *str);
+
+void print_string(const char *string);
+
+void swap (char *x, char *y);
+
+void reverse(char str[], int length);
+
+char* itoa(int num, char* str, int base);
+
+void mandelbrot_tile(uint8_t tile, uint8_t tiles);
+
+bool is_prime(uint64_t p);
+
+bool is_mersenne_prime(uint64_t p);
+
+uint64_t power(uint16_t num, uint16_t exp);
+
+uint32_t isqrt(uint32_t val);
+
+float sin_aprox(float arg);
+
+float cos_aprox(float arg);
+
+float blackman_harris(int n, int N);
+
+void fft(float *inReal, float *inImag, uint32_t log2_N);
+
+float noise_generator(uint32_t seed);