From 6a018a4cfda937c0d8cbdee761187c5c5843e115 Mon Sep 17 00:00:00 2001 From: Scott Larson Date: Fri, 7 Aug 2020 17:47:29 -0700 Subject: [PATCH] add ARM11 --- .../arm11/ac5/example_build/build_threadx.bat | 238 ++ .../example_build/build_threadx_sample.bat | 4 + .../arm11/ac5/example_build/sample_threadx.c | 369 ++ .../example_build/tx_initialize_low_level.s | 444 +++ ports/arm11/ac5/inc/tx_port.h | 327 ++ ports/arm11/ac5/readme_threadx.txt | 534 +++ .../arm11/ac5/src/tx_thread_context_restore.s | 247 ++ ports/arm11/ac5/src/tx_thread_context_save.s | 207 + .../ac5/src/tx_thread_fiq_context_restore.s | 259 ++ .../ac5/src/tx_thread_fiq_context_save.s | 203 + .../arm11/ac5/src/tx_thread_fiq_nesting_end.s | 111 + .../ac5/src/tx_thread_fiq_nesting_start.s | 104 + .../ac5/src/tx_thread_interrupt_control.s | 102 + .../ac5/src/tx_thread_interrupt_disable.s | 98 + .../ac5/src/tx_thread_interrupt_restore.s | 87 + .../arm11/ac5/src/tx_thread_irq_nesting_end.s | 110 + .../ac5/src/tx_thread_irq_nesting_start.s | 104 + ports/arm11/ac5/src/tx_thread_schedule.s | 172 + ports/arm11/ac5/src/tx_thread_stack_build.s | 156 + ports/arm11/ac5/src/tx_thread_system_return.s | 150 + .../ac5/src/tx_thread_vectored_context_save.s | 209 + ports/arm11/ac5/src/tx_timer_interrupt.s | 258 ++ .../arm11/gnu/example_build/build_threadx.bat | 238 ++ .../example_build/build_threadx_sample.bat | 6 + ports/arm11/gnu/example_build/crt0.S | 90 + ports/arm11/gnu/example_build/libc.a | Bin 0 -> 1207876 bytes ports/arm11/gnu/example_build/libgcc.a | Bin 0 -> 261004 bytes ports/arm11/gnu/example_build/libnosys.a | Bin 0 -> 29354 bytes ports/arm11/gnu/example_build/reset.S | 76 + .../arm11/gnu/example_build/sample_threadx.c | 369 ++ .../arm11/gnu/example_build/sample_threadx.ld | 239 ++ .../example_build/tx_initialize_low_level.S | 347 ++ ports/arm11/gnu/inc/tx_port.h | 316 ++ ports/arm11/gnu/readme_threadx.txt | 496 +++ .../arm11/gnu/src/tx_thread_context_restore.S | 241 ++ ports/arm11/gnu/src/tx_thread_context_save.S | 210 + .../gnu/src/tx_thread_fiq_context_restore.S | 256 ++ .../gnu/src/tx_thread_fiq_context_save.S | 204 + .../arm11/gnu/src/tx_thread_fiq_nesting_end.S | 111 + .../gnu/src/tx_thread_fiq_nesting_start.S | 104 + .../gnu/src/tx_thread_interrupt_control.S | 115 + .../gnu/src/tx_thread_interrupt_disable.S | 116 + .../gnu/src/tx_thread_interrupt_restore.S | 104 + .../arm11/gnu/src/tx_thread_irq_nesting_end.S | 111 + .../gnu/src/tx_thread_irq_nesting_start.S | 104 + ports/arm11/gnu/src/tx_thread_schedule.S | 187 + ports/arm11/gnu/src/tx_thread_stack_build.S | 178 + ports/arm11/gnu/src/tx_thread_system_return.S | 167 + .../gnu/src/tx_thread_vectored_context_save.S | 199 + ports/arm11/gnu/src/tx_timer_interrupt.S | 279 ++ ports/arm11/iar/example_build/azure_rtos.eww | 13 + ports/arm11/iar/example_build/cstartup.s | 161 + .../arm11/iar/example_build/sample_threadx.c | 374 ++ .../iar/example_build/sample_threadx.ewd | 2974 ++++++++++++++ .../iar/example_build/sample_threadx.ewp | 2136 ++++++++++ .../iar/example_build/sample_threadx.ewt | 2797 ++++++++++++++ .../iar/example_build/sample_threadx.icf | 49 + .../example_build/settings/azure_rtos.wsdt | 535 +++ .../settings/sample_threadx.Debug.cspy.bat | 40 + .../settings/sample_threadx.Debug.cspy.ps1 | 31 + .../settings/sample_threadx.Debug.driver.xcl | 13 + .../settings/sample_threadx.Debug.general.xcl | 11 + .../settings/sample_threadx.crun | 13 + .../settings/sample_threadx.dbgdt | 1685 ++++++++ .../example_build/settings/sample_threadx.dnx | 99 + .../example_build/settings/tx.Debug.cspy.bat | 40 + .../example_build/settings/tx.Debug.cspy.ps1 | 31 + .../settings/tx.Debug.driver.xcl | 13 + .../settings/tx.Debug.general.xcl | 11 + .../arm11/iar/example_build/settings/tx.crun | 13 + .../arm11/iar/example_build/settings/tx.dbgdt | 4 + ports/arm11/iar/example_build/settings/tx.dnx | 58 + ports/arm11/iar/example_build/tx.ewd | 2974 ++++++++++++++ ports/arm11/iar/example_build/tx.ewp | 2766 +++++++++++++ ports/arm11/iar/example_build/tx.ewt | 3427 +++++++++++++++++ .../example_build/tx_initialize_low_level.s | 339 ++ ports/arm11/iar/inc/tx_port.h | 401 ++ ports/arm11/iar/readme_threadx.txt | 527 +++ ports/arm11/iar/src/tx_iar.c | 816 ++++ .../arm11/iar/src/tx_thread_context_restore.s | 258 ++ ports/arm11/iar/src/tx_thread_context_save.s | 222 ++ .../iar/src/tx_thread_fiq_context_restore.s | 269 ++ .../iar/src/tx_thread_fiq_context_save.s | 215 ++ .../arm11/iar/src/tx_thread_fiq_nesting_end.s | 121 + .../iar/src/tx_thread_fiq_nesting_start.s | 114 + .../iar/src/tx_thread_interrupt_control.s | 115 + .../iar/src/tx_thread_interrupt_disable.s | 113 + .../iar/src/tx_thread_interrupt_restore.s | 99 + .../arm11/iar/src/tx_thread_irq_nesting_end.s | 122 + .../iar/src/tx_thread_irq_nesting_start.s | 114 + ports/arm11/iar/src/tx_thread_schedule.s | 183 + ports/arm11/iar/src/tx_thread_stack_build.s | 170 + ports/arm11/iar/src/tx_thread_system_return.s | 161 + .../iar/src/tx_thread_vectored_context_save.s | 207 + ports/arm11/iar/src/tx_timer_interrupt.s | 272 ++ 95 files changed, 34462 insertions(+) create mode 100644 ports/arm11/ac5/example_build/build_threadx.bat create mode 100644 ports/arm11/ac5/example_build/build_threadx_sample.bat create mode 100644 ports/arm11/ac5/example_build/sample_threadx.c create mode 100644 ports/arm11/ac5/example_build/tx_initialize_low_level.s create mode 100644 ports/arm11/ac5/inc/tx_port.h create mode 100644 ports/arm11/ac5/readme_threadx.txt create mode 100644 ports/arm11/ac5/src/tx_thread_context_restore.s create mode 100644 ports/arm11/ac5/src/tx_thread_context_save.s create mode 100644 ports/arm11/ac5/src/tx_thread_fiq_context_restore.s create mode 100644 ports/arm11/ac5/src/tx_thread_fiq_context_save.s create mode 100644 ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s create mode 100644 ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s create mode 100644 ports/arm11/ac5/src/tx_thread_interrupt_control.s create mode 100644 ports/arm11/ac5/src/tx_thread_interrupt_disable.s create mode 100644 ports/arm11/ac5/src/tx_thread_interrupt_restore.s create mode 100644 ports/arm11/ac5/src/tx_thread_irq_nesting_end.s create mode 100644 ports/arm11/ac5/src/tx_thread_irq_nesting_start.s create mode 100644 ports/arm11/ac5/src/tx_thread_schedule.s create mode 100644 ports/arm11/ac5/src/tx_thread_stack_build.s create mode 100644 ports/arm11/ac5/src/tx_thread_system_return.s create mode 100644 ports/arm11/ac5/src/tx_thread_vectored_context_save.s create mode 100644 ports/arm11/ac5/src/tx_timer_interrupt.s create mode 100644 ports/arm11/gnu/example_build/build_threadx.bat create mode 100644 ports/arm11/gnu/example_build/build_threadx_sample.bat create mode 100644 ports/arm11/gnu/example_build/crt0.S create mode 100644 ports/arm11/gnu/example_build/libc.a create mode 100644 ports/arm11/gnu/example_build/libgcc.a create mode 100644 ports/arm11/gnu/example_build/libnosys.a create mode 100644 ports/arm11/gnu/example_build/reset.S create mode 100644 ports/arm11/gnu/example_build/sample_threadx.c create mode 100644 ports/arm11/gnu/example_build/sample_threadx.ld create mode 100644 ports/arm11/gnu/example_build/tx_initialize_low_level.S create mode 100644 ports/arm11/gnu/inc/tx_port.h create mode 100644 ports/arm11/gnu/readme_threadx.txt create mode 100644 ports/arm11/gnu/src/tx_thread_context_restore.S create mode 100644 ports/arm11/gnu/src/tx_thread_context_save.S create mode 100644 ports/arm11/gnu/src/tx_thread_fiq_context_restore.S create mode 100644 ports/arm11/gnu/src/tx_thread_fiq_context_save.S create mode 100644 ports/arm11/gnu/src/tx_thread_fiq_nesting_end.S create mode 100644 ports/arm11/gnu/src/tx_thread_fiq_nesting_start.S create mode 100644 ports/arm11/gnu/src/tx_thread_interrupt_control.S create mode 100644 ports/arm11/gnu/src/tx_thread_interrupt_disable.S create mode 100644 ports/arm11/gnu/src/tx_thread_interrupt_restore.S create mode 100644 ports/arm11/gnu/src/tx_thread_irq_nesting_end.S create mode 100644 ports/arm11/gnu/src/tx_thread_irq_nesting_start.S create mode 100644 ports/arm11/gnu/src/tx_thread_schedule.S create mode 100644 ports/arm11/gnu/src/tx_thread_stack_build.S create mode 100644 ports/arm11/gnu/src/tx_thread_system_return.S create mode 100644 ports/arm11/gnu/src/tx_thread_vectored_context_save.S create mode 100644 ports/arm11/gnu/src/tx_timer_interrupt.S create mode 100644 ports/arm11/iar/example_build/azure_rtos.eww create mode 100644 ports/arm11/iar/example_build/cstartup.s create mode 100644 ports/arm11/iar/example_build/sample_threadx.c create mode 100644 ports/arm11/iar/example_build/sample_threadx.ewd create mode 100644 ports/arm11/iar/example_build/sample_threadx.ewp create mode 100644 ports/arm11/iar/example_build/sample_threadx.ewt create mode 100644 ports/arm11/iar/example_build/sample_threadx.icf create mode 100644 ports/arm11/iar/example_build/settings/azure_rtos.wsdt create mode 100644 ports/arm11/iar/example_build/settings/sample_threadx.Debug.cspy.bat create mode 100644 ports/arm11/iar/example_build/settings/sample_threadx.Debug.cspy.ps1 create mode 100644 ports/arm11/iar/example_build/settings/sample_threadx.Debug.driver.xcl create mode 100644 ports/arm11/iar/example_build/settings/sample_threadx.Debug.general.xcl create mode 100644 ports/arm11/iar/example_build/settings/sample_threadx.crun create mode 100644 ports/arm11/iar/example_build/settings/sample_threadx.dbgdt create mode 100644 ports/arm11/iar/example_build/settings/sample_threadx.dnx create mode 100644 ports/arm11/iar/example_build/settings/tx.Debug.cspy.bat create mode 100644 ports/arm11/iar/example_build/settings/tx.Debug.cspy.ps1 create mode 100644 ports/arm11/iar/example_build/settings/tx.Debug.driver.xcl create mode 100644 ports/arm11/iar/example_build/settings/tx.Debug.general.xcl create mode 100644 ports/arm11/iar/example_build/settings/tx.crun create mode 100644 ports/arm11/iar/example_build/settings/tx.dbgdt create mode 100644 ports/arm11/iar/example_build/settings/tx.dnx create mode 100644 ports/arm11/iar/example_build/tx.ewd create mode 100644 ports/arm11/iar/example_build/tx.ewp create mode 100644 ports/arm11/iar/example_build/tx.ewt create mode 100644 ports/arm11/iar/example_build/tx_initialize_low_level.s create mode 100644 ports/arm11/iar/inc/tx_port.h create mode 100644 ports/arm11/iar/readme_threadx.txt create mode 100644 ports/arm11/iar/src/tx_iar.c create mode 100644 ports/arm11/iar/src/tx_thread_context_restore.s create mode 100644 ports/arm11/iar/src/tx_thread_context_save.s create mode 100644 ports/arm11/iar/src/tx_thread_fiq_context_restore.s create mode 100644 ports/arm11/iar/src/tx_thread_fiq_context_save.s create mode 100644 ports/arm11/iar/src/tx_thread_fiq_nesting_end.s create mode 100644 ports/arm11/iar/src/tx_thread_fiq_nesting_start.s create mode 100644 ports/arm11/iar/src/tx_thread_interrupt_control.s create mode 100644 ports/arm11/iar/src/tx_thread_interrupt_disable.s create mode 100644 ports/arm11/iar/src/tx_thread_interrupt_restore.s create mode 100644 ports/arm11/iar/src/tx_thread_irq_nesting_end.s create mode 100644 ports/arm11/iar/src/tx_thread_irq_nesting_start.s create mode 100644 ports/arm11/iar/src/tx_thread_schedule.s create mode 100644 ports/arm11/iar/src/tx_thread_stack_build.s create mode 100644 ports/arm11/iar/src/tx_thread_system_return.s create mode 100644 ports/arm11/iar/src/tx_thread_vectored_context_save.s create mode 100644 ports/arm11/iar/src/tx_timer_interrupt.s diff --git a/ports/arm11/ac5/example_build/build_threadx.bat b/ports/arm11/ac5/example_build/build_threadx.bat new file mode 100644 index 000000000..d2abc7829 --- /dev/null +++ b/ports/arm11/ac5/example_build/build_threadx.bat @@ -0,0 +1,238 @@ +del tx.a +armasm -g --cpu ARM1136J-S --apcs /interwork tx_initialize_low_level.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_stack_build.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_schedule.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_system_return.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_context_save.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_context_restore.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_interrupt_control.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_timer_interrupt.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_interrupt_disable.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_interrupt_restore.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_fiq_context_save.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_fiq_nesting_start.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_irq_nesting_start.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_irq_nesting_end.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_fiq_nesting_end.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_fiq_context_restore.s +armasm -g --cpu ARM1136J-S --apcs /interwork ../src/tx_thread_vectored_context_save.s +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_allocate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_cleanup.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_initialize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_system_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_block_release.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_allocate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_cleanup.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_initialize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_search.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_release.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_cleanup.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_initialize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_system_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_high_level.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_enter.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_setup.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_cleanup.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_initialize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_system_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_priority_change.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_put.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_cleanup.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_flush.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_front_send.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_initialize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_system_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_receive.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_ceiling_put.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_cleanup.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_initialize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_system_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_entry_exit_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_identify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_initialize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_system_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_preemption_change.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_priority_change.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_relinquish.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_reset.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_resume.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_shell_entry.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_sleep.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_analyze.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_handler.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_suspend.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_preempt_check.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_resume.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_suspend.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_terminate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice_change.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_timeout.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_wait_abort.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_time_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_time_set.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_activate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_change.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_deactivate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_expiration_process.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_initialize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_system_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_activate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_deactivate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_thread_entry.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_enable.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_disable.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_initialize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_interrupt_control.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_enter_insert.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_exit_insert.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_register.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_unregister.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_user_event_insert.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_buffer_full_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_filter.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_unfilter.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_allocate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_block_release.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_allocate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_release.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_put.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_flush.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_front_send.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_receive.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_ceiling_put.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_prioritize.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_entry_exit_notify.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_info_get.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_preemption_change.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_priority_change.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_relinquish.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_reset.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_resume.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_suspend.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_terminate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_time_slice_change.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_wait_abort.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_activate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_change.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_create.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_deactivate.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_delete.c +armcc -c -g -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_info_get.c +armar --create tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o +armar -r tx.a tx_thread_interrupt_disable.o tx_thread_interrupt_restore.o tx_thread_fiq_context_save.o tx_thread_fiq_nesting_start.o tx_thread_irq_nesting_start.o tx_thread_irq_nesting_end.o +armar -r tx.a tx_thread_fiq_nesting_end.o tx_thread_fiq_context_restore.o tx_thread_vectored_context_save.o tx_initialize_low_level.o +armar -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o +armar -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o +armar -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o +armar -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o +armar -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o +armar -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o +armar -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o +armar -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o +armar -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o +armar -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o +armar -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o +armar -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o +armar -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o +armar -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o +armar -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o +armar -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o +armar -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o +armar -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o +armar -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o +armar -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o +armar -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o +armar -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o +armar -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o +armar -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o +armar -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o +armar -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o +armar -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o +armar -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o +armar -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o +armar -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o +armar -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o +armar -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o +armar -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o diff --git a/ports/arm11/ac5/example_build/build_threadx_sample.bat b/ports/arm11/ac5/example_build/build_threadx_sample.bat new file mode 100644 index 000000000..f8fb754b3 --- /dev/null +++ b/ports/arm11/ac5/example_build/build_threadx_sample.bat @@ -0,0 +1,4 @@ +armasm -g --cpu ARM1136J-S --apcs /interwork tx_initialize_low_level.s +armcc -g -c -O2 --cpu ARM1136J-S --apcs /interwork -I../../../../common/inc -I../inc sample_threadx.c +armlink -d -o sample_threadx.axf --elf --ro 0 --first tx_initialize_low_level.o(Init) --remove --map --symbols --list sample_threadx.map tx_initialize_low_level.o sample_threadx.o tx.a + diff --git a/ports/arm11/ac5/example_build/sample_threadx.c b/ports/arm11/ac5/example_build/sample_threadx.c new file mode 100644 index 000000000..418ec634f --- /dev/null +++ b/ports/arm11/ac5/example_build/sample_threadx.c @@ -0,0 +1,369 @@ +/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight + threads of different priorities, using a message queue, semaphore, mutex, event flags group, + byte pool, and block pool. */ + +#include "tx_api.h" + +#define DEMO_STACK_SIZE 1024 +#define DEMO_BYTE_POOL_SIZE 9120 +#define DEMO_BLOCK_POOL_SIZE 100 +#define DEMO_QUEUE_SIZE 100 + + +/* Define the ThreadX object control blocks... */ + +TX_THREAD thread_0; +TX_THREAD thread_1; +TX_THREAD thread_2; +TX_THREAD thread_3; +TX_THREAD thread_4; +TX_THREAD thread_5; +TX_THREAD thread_6; +TX_THREAD thread_7; +TX_QUEUE queue_0; +TX_SEMAPHORE semaphore_0; +TX_MUTEX mutex_0; +TX_EVENT_FLAGS_GROUP event_flags_0; +TX_BYTE_POOL byte_pool_0; +TX_BLOCK_POOL block_pool_0; + + +/* Define the counters used in the demo application... */ + +ULONG thread_0_counter; +ULONG thread_1_counter; +ULONG thread_1_messages_sent; +ULONG thread_2_counter; +ULONG thread_2_messages_received; +ULONG thread_3_counter; +ULONG thread_4_counter; +ULONG thread_5_counter; +ULONG thread_6_counter; +ULONG thread_7_counter; + + +/* Define thread prototypes. */ + +void thread_0_entry(ULONG thread_input); +void thread_1_entry(ULONG thread_input); +void thread_2_entry(ULONG thread_input); +void thread_3_and_4_entry(ULONG thread_input); +void thread_5_entry(ULONG thread_input); +void thread_6_and_7_entry(ULONG thread_input); + + +/* Define main entry point. */ + +int main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ + +void tx_application_define(void *first_unused_memory) +{ + +CHAR *pointer = TX_NULL; + + + /* Create a byte memory pool from which to allocate the thread stacks. */ + tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE); + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + /* Allocate the stack for thread 0. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + + + /* Allocate the stack for thread 1. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 1 and 2. These threads pass information through a ThreadX + message queue. It is also interesting to note that these threads have a time + slice. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, DEMO_STACK_SIZE, + 16, 16, 4, TX_AUTO_START); + + /* Allocate the stack for thread 2. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, DEMO_STACK_SIZE, + 16, 16, 4, TX_AUTO_START); + + /* Allocate the stack for thread 3. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore. + An interesting thing here is that both threads share the same instruction area. */ + tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 4. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 5. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create thread 5. This thread simply pends on an event flag which will be set + by thread_0. */ + tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 6. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 6 and 7. These threads compete for a ThreadX mutex. */ + tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 7. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the message queue. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT); + + /* Create the message queue shared by threads 1 and 2. */ + tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG)); + + /* Create the semaphore used by threads 3 and 4. */ + tx_semaphore_create(&semaphore_0, "semaphore 0", 1); + + /* Create the event flags group used by threads 1 and 5. */ + tx_event_flags_create(&event_flags_0, "event flags 0"); + + /* Create the mutex used by thread 6 and 7 without priority inheritance. */ + tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Allocate the memory for a small block pool. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT); + + /* Create a block memory pool to allocate a message buffer from. */ + tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE); + + /* Allocate a block and release the block memory. */ + tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT); + + /* Release the block back to the pool. */ + tx_block_release(pointer); +} + + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* This thread simply sits in while-forever-sleep loop. */ + while(1) + { + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Sleep for 10 ticks. */ + tx_thread_sleep(10); + + /* Set event flag 0 to wakeup thread 5. */ + status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* This thread simply sends messages to a queue shared by thread 2. */ + while(1) + { + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Send message to queue 0. */ + status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER); + + /* Check completion status. */ + if (status != TX_SUCCESS) + break; + + /* Increment the message sent. */ + thread_1_messages_sent++; + } +} + + +void thread_2_entry(ULONG thread_input) +{ + +ULONG received_message; +UINT status; + + /* This thread retrieves messages placed on the queue by thread 1. */ + while(1) + { + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Retrieve a message from the queue. */ + status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER); + + /* Check completion status and make sure the message is what we + expected. */ + if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received)) + break; + + /* Otherwise, all is okay. Increment the received message count. */ + thread_2_messages_received++; + } +} + + +void thread_3_and_4_entry(ULONG thread_input) +{ + +UINT status; + + + /* This function is executed from thread 3 and thread 4. As the loop + below shows, these function compete for ownership of semaphore_0. */ + while(1) + { + + /* Increment the thread counter. */ + if (thread_input == 3) + thread_3_counter++; + else + thread_4_counter++; + + /* Get the semaphore with suspension. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Sleep for 2 ticks to hold the semaphore. */ + tx_thread_sleep(2); + + /* Release the semaphore. */ + status = tx_semaphore_put(&semaphore_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +void thread_5_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_flags; + + + /* This thread simply waits for an event in a forever loop. */ + while(1) + { + + /* Increment the thread counter. */ + thread_5_counter++; + + /* Wait for event flag 0. */ + status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR, + &actual_flags, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_flags != 0x1)) + break; + } +} + + +void thread_6_and_7_entry(ULONG thread_input) +{ + +UINT status; + + + /* This function is executed from thread 6 and thread 7. As the loop + below shows, these function compete for ownership of mutex_0. */ + while(1) + { + + /* Increment the thread counter. */ + if (thread_input == 6) + thread_6_counter++; + else + thread_7_counter++; + + /* Get the mutex with suspension. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Get the mutex again with suspension. This shows + that an owning thread may retrieve the mutex it + owns multiple times. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Sleep for 2 ticks to hold the mutex. */ + tx_thread_sleep(2); + + /* Release the mutex. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Release the mutex again. This will actually + release ownership since it was obtained twice. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} diff --git a/ports/arm11/ac5/example_build/tx_initialize_low_level.s b/ports/arm11/ac5/example_build/tx_initialize_low_level.s new file mode 100644 index 000000000..a7bd0a351 --- /dev/null +++ b/ports/arm11/ac5/example_build/tx_initialize_low_level.s @@ -0,0 +1,444 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Initialize */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_initialize.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +SVC_MODE EQU 0xD3 ; Disable IRQ/FIQ SVC mode +IRQ_MODE EQU 0xD2 ; Disable IRQ/FIQ IRQ mode +FIQ_MODE EQU 0xD1 ; Disable IRQ/FIQ FIQ mode +SYS_MODE EQU 0xDF ; Disable IRQ/FIQ SYS mode +HEAP_SIZE EQU 4096 ; Heap size +FIQ_STACK_SIZE EQU 512 ; FIQ stack size +SYS_STACK_SIZE EQU 1024 ; SYS stack size (used for nested interrupts) +IRQ_STACK_SIZE EQU 1024 ; IRQ stack size +; +; +;/* ARM11 ARMulator Timer and Interrupt controller information. This depends on +; the ARMulator's Interrupt Controller and Timer being enabled in the default.ami. +; In addition, the addresses must match those specified in the peripherals.ami file. +; Please refer to section 2.10 and 4.16 of the Debug Target Guide, version 1.2. */ +; +IRQStatus EQU 0x0a000000 ; IRQ Status Register +IRQRawStatus EQU 0x0a000004 ; IRQ Raw Status Register +IRQEnable EQU 0x0a000008 ; IRQ Enable Set Register +IRQEnableClear EQU 0x0a00000C ; IRQ Enable Clear Register +IRQSoft EQU 0x0a000010 ; IRQ Soft +FIQStatus EQU 0x0a000100 ; FIQ Status Register +FIQRawStatus EQU 0x0a000104 ; FIQ Raw Status Register +FIQEnable EQU 0x0a000108 ; FIQ Enable Set Register +FIQEnableClear EQU 0x0a00010C ; FIQ Enable Clear Register + +TIMER1_BIT EQU 0x00000010 ; IRQ/FIQ Timer1 bit +TIMER2_BIT EQU 0x00000020 ; IRQ/FIQ Timer2 bit + +Timer1Load EQU 0x0a800000 ; Timer1 Load Register +Timer1Value EQU 0x0a800004 ; Timer1 Value Register +Timer1Control EQU 0x0a800008 ; Timer1 Control Register +Timer1Clear EQU 0x0a80000C ; Timer1 Clear Register + +Timer1Mode EQU 0x000000C0 ; Timer1 Control Value, Timer enable, periodic, no prescaler +Timer1Period EQU 0x0000FFFF ; Timer1 count-down period, maximum value + +Timer2Load EQU 0x0a800020 ; Timer2 Load Register +Timer2Value EQU 0x0a800024 ; Timer2 Value Register +Timer2Control EQU 0x0a800028 ; Timer2 Control Register +Timer2Clear EQU 0x0a80002C ; Timer2 Clear Register +; +; + IMPORT _tx_thread_system_stack_ptr + IMPORT _tx_initialize_unused_memory + IMPORT _tx_thread_context_save + IMPORT _tx_thread_context_restore + IF :DEF:TX_ENABLE_FIQ_SUPPORT + IMPORT _tx_thread_fiq_context_save + IMPORT _tx_thread_fiq_context_restore + ENDIF + IF :DEF:TX_ENABLE_IRQ_NESTING + IMPORT _tx_thread_irq_nesting_start + IMPORT _tx_thread_irq_nesting_end + ENDIF + IF :DEF:TX_ENABLE_FIQ_NESTING + IMPORT _tx_thread_fiq_nesting_start + IMPORT _tx_thread_fiq_nesting_end + ENDIF + IMPORT _tx_timer_interrupt + IMPORT __main + IMPORT _tx_version_id + IMPORT _tx_build_options + IMPORT |Image$$ZI$$Limit| +; +; + AREA Init, CODE, READONLY +; +;/* Define the ARM11 vector area. This should be located or copied to 0. */ +; + EXPORT __vectors +__vectors + LDR pc,=__main ; Reset goes to startup function + LDR pc,=__tx_undefined ; Undefined handler + LDR pc,=__tx_swi_interrupt ; Software interrupt handler + LDR pc,=__tx_prefetch_handler ; Prefetch exception handler + LDR pc,=__tx_abort_handler ; Abort exception handler + LDR pc,=__tx_reserved_handler ; Reserved exception handler + LDR pc,=__tx_irq_handler ; IRQ interrupt handler + LDR pc,=__tx_fiq_handler ; FIQ interrupt handler +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_initialize_low_level ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for any low-level processor */ +;/* initialization, including setting up interrupt vectors, setting */ +;/* up a periodic timer interrupt source, saving the system stack */ +;/* pointer for use in ISR processing later, and finding the first */ +;/* available RAM memory address for tx_application_define. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* _tx_initialize_kernel_enter ThreadX entry function */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_initialize_low_level(VOID) +;{ + EXPORT _tx_initialize_low_level +_tx_initialize_low_level +; +; +; /****** NOTE ****** We must be in SVC MODE at this point. Some monitors +; enter this routine in USER mode and require a software interrupt to +; change into SVC mode. */ +; + LDR r1, =|Image$$ZI$$Limit| ; Get end of non-initialized RAM area + LDR r2, =HEAP_SIZE ; Pickup the heap size + ADD r1, r2, r1 ; Setup heap limit + ADD r1, r1, #4 ; Setup stack limit +; + IF :DEF:TX_ENABLE_IRQ_NESTING +; /* Setup the system mode stack for nested interrupt support */ + LDR r2, =SYS_STACK_SIZE ; Pickup stack size + MOV r3, #SYS_MODE ; Build SYS mode CPSR + MSR CPSR_cxsf, r3 ; Enter SYS mode + ADD r1, r1, r2 ; Calculate start of SYS stack + BIC r1, r1, #7 ; Ensure 8-byte alignment + MOV sp, r1 ; Setup SYS stack pointer + ENDIF +; + LDR r2, =FIQ_STACK_SIZE ; Pickup stack size + MOV r0, #FIQ_MODE ; Build FIQ mode CPSR + MSR CPSR_c, r0 ; Enter FIQ mode + ADD r1, r1, r2 ; Calculate start of FIQ stack + BIC r1, r1, #7 ; Ensure 8-byte alignment + MOV sp, r1 ; Setup FIQ stack pointer + MOV sl, #0 ; Clear sl + MOV fp, #0 ; Clear fp + LDR r2, =IRQ_STACK_SIZE ; Pickup IRQ (system stack size) + MOV r0, #IRQ_MODE ; Build IRQ mode CPSR + MSR CPSR_c, r0 ; Enter IRQ mode + ADD r1, r1, r2 ; Calculate start of IRQ stack + BIC r1, r1, #7 ; Ensure 8-byte alignment + MOV sp, r1 ; Setup IRQ stack pointer + MOV r0, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_c, r0 ; Enter SVC mode + LDR r3, =_tx_thread_system_stack_ptr ; Pickup stack pointer + STR r1, [r3, #0] ; Save the system stack +; +; /* Save the system stack pointer. */ +; _tx_thread_system_stack_ptr = (VOID_PTR) (sp); +; + LDR r1, =_tx_thread_system_stack_ptr ; Pickup address of system stack ptr + LDR r0, [r1, #0] ; Pickup system stack + ADD r0, r0, #4 ; Increment to next free word +; +; /* Save the first available memory address. */ +; _tx_initialize_unused_memory = (VOID_PTR) |Image$$ZI$$Limit| + HEAP + [SYS_STACK] + FIQ_STACK + IRQ_STACK; +; + LDR r2, =_tx_initialize_unused_memory ; Pickup unused memory ptr address + STR r0, [r2, #0] ; Save first free memory address +; +; /* Setup Timer for periodic interrupts. */ +; +; /* Setup ARMulator Timer1 for periodic interrupts. */ +; + LDR r0,=IRQEnable ; Build address of IRQ enable register + LDR r1,=TIMER1_BIT ; Build value of Timer1 IRQ enable + STR r1,[r0] ; Enable IRQ interrupts for Timer1 + + LDR r0,=Timer1Load ; Build address of Timer1 load register + LDR r1,=Timer1Period ; Build Timer1 periodic value + STR r1,[r0] ; Set Timer1 load value + + LDR r0,=Timer1Control ; Build address of Timer1 control register + LDR r1,=Timer1Mode ; Build Timer1 control value + STR r1,[r0] ; Enable Timer1 +; +; /* Done, return to caller. */ +; + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +;} +; +; +;/* Define initial heap/stack routine for the ARM RealView (and ADS) startup code. This +; routine will set the initial stack to use the ThreadX IRQ & FIQ & +; (optionally SYS) stack areas. */ +; + EXPORT __user_initial_stackheap +__user_initial_stackheap + LDR r0, =|Image$$ZI$$Limit| ; Get end of non-initialized RAM area + LDR r2, =HEAP_SIZE ; Pickup the heap size + ADD r2, r2, r0 ; Setup heap limit + ADD r3, r2, #4 ; Setup stack limit + MOV r1, r3 ; Setup start of stack + IF :DEF:TX_ENABLE_IRQ_NESTING + LDR r12, =SYS_STACK_SIZE ; Pickup IRQ system stack + ADD r1, r1, r12 ; Setup the return system stack + BIC r1, r1, #7 ; Ensure 8-byte alignment + ENDIF + LDR r12, =FIQ_STACK_SIZE ; Pickup FIQ stack size + ADD r1, r1, r12 ; Setup the return system stack + BIC r1, r1, #7 ; Ensure 8-byte alignment + LDR r12, =IRQ_STACK_SIZE ; Pickup IRQ system stack + ADD r1, r1, r12 ; Setup the return system stack + BIC r1, r1, #7 ; Ensure 8-byte alignment + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +; +;/* Define shells for each of the interrupt vectors. */ +; + EXPORT __tx_undefined +__tx_undefined + B __tx_undefined ; Undefined handler +; + EXPORT __tx_swi_interrupt +__tx_swi_interrupt + B __tx_swi_interrupt ; Software interrupt handler +; + EXPORT __tx_prefetch_handler +__tx_prefetch_handler + B __tx_prefetch_handler ; Prefetch exception handler +; + EXPORT __tx_abort_handler +__tx_abort_handler + B __tx_abort_handler ; Abort exception handler +; + EXPORT __tx_reserved_handler +__tx_reserved_handler + B __tx_reserved_handler ; Reserved exception handler +; +; + EXPORT __tx_irq_handler + EXPORT __tx_irq_processing_return +__tx_irq_handler +; +; /* Jump to context save to save system context. */ + B _tx_thread_context_save +__tx_irq_processing_return +; +; /* At this point execution is still in the IRQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. In +; addition, IRQ interrupts may be re-enabled - with certain restrictions - +; if nested IRQ interrupts are desired. Interrupts may be re-enabled over +; small code sequences where lr is saved before enabling interrupts and +; restored after interrupts are again disabled. */ +; +; +; /* Check for Timer1 interrupts on the ARMulator. */ + + LDR r1,=IRQStatus ; Pickup address of IRQStatus register + LDR r2, [r1] ; Read IRQStatus + LDR r0,=TIMER1_BIT ; Pickup Timer1 interrupt present bit + AND r2, r2, r0 ; Is this a timer interrupt? + CMP r2, r0 ; + BNE _tx_not_timer_interrupt ; If 0, not a timer interrupt + + LDR r1,=Timer1Clear ; Build address of Timer1 clear register + MOV r0,#0 ; + STR r0, [r1] ; Clear timer 0 interrupt + + BL _tx_timer_interrupt ; Timer interrupt handler +_tx_not_timer_interrupt +; +; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start +; from IRQ mode with interrupts disabled. This routine switches to the +; system mode and returns with IRQ interrupts enabled. +; +; NOTE: It is very important to ensure all IRQ interrupts are cleared +; prior to enabling nested IRQ interrupts. */ + IF :DEF:TX_ENABLE_IRQ_NESTING + BL _tx_thread_irq_nesting_start + ENDIF +; +; +; /* Application IRQ handlers can be called here! */ +; +; /* If interrupt nesting was started earlier, the end of interrupt nesting +; service must be called before returning to _tx_thread_context_restore. +; This routine returns in processing in IRQ mode with interrupts disabled. */ + IF :DEF:TX_ENABLE_IRQ_NESTING + BL _tx_thread_irq_nesting_end + ENDIF +; +; /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore +; +; +; /* This is an example of a vectored IRQ handler. */ +; + EXPORT __tx_example_vectored_irq_handler +__tx_example_vectored_irq_handler +; +; +; /* Save initial context and call context save to prepare for +; vectored ISR execution. */ +; +; STMDB sp!, {r0-r3} ; Save some scratch registers +; MRS r0, SPSR ; Pickup saved SPSR +; SUB lr, lr, #4 ; Adjust point of interrupt +; STMDB sp!, {r0, r10, r12, lr} ; Store other scratch registers +; BL _tx_thread_vectored_context_save ; Vectored context save +; +; /* At this point execution is still in the IRQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. In +; addition, IRQ interrupts may be re-enabled - with certain restrictions - +; if nested IRQ interrupts are desired. Interrupts may be re-enabled over +; small code sequences where lr is saved before enabling interrupts and +; restored after interrupts are again disabled. */ +; +; +; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start +; from IRQ mode with interrupts disabled. This routine switches to the +; system mode and returns with IRQ interrupts enabled. +; +; NOTE: It is very important to ensure all IRQ interrupts are cleared +; prior to enabling nested IRQ interrupts. */ +; IF :DEF:TX_ENABLE_IRQ_NESTING +; BL _tx_thread_irq_nesting_start +; ENDIF +; +; /* Application IRQ handlers can be called here! */ +; +; /* If interrupt nesting was started earlier, the end of interrupt nesting +; service must be called before returning to _tx_thread_context_restore. +; This routine returns in processing in IRQ mode with interrupts disabled. */ +; IF :DEF:TX_ENABLE_IRQ_NESTING +; BL _tx_thread_irq_nesting_end +; ENDIF +; +; /* Jump to context restore to restore system context. */ +; B _tx_thread_context_restore +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT + EXPORT __tx_fiq_handler + EXPORT __tx_fiq_processing_return +__tx_fiq_handler +; +; /* Jump to fiq context save to save system context. */ + B _tx_thread_fiq_context_save +__tx_fiq_processing_return +; +; /* At this point execution is still in the FIQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. */ +; +; /* Interrupt nesting is allowed after calling _tx_thread_fiq_nesting_start +; from FIQ mode with interrupts disabled. This routine switches to the +; system mode and returns with FIQ interrupts enabled. +; +; NOTE: It is very important to ensure all FIQ interrupts are cleared +; prior to enabling nested FIQ interrupts. */ + IF :DEF:TX_ENABLE_FIQ_NESTING + BL _tx_thread_fiq_nesting_start + ENDIF +; +; /* Application FIQ handlers can be called here! */ +; +; /* If interrupt nesting was started earlier, the end of interrupt nesting +; service must be called before returning to _tx_thread_fiq_context_restore. */ + IF :DEF:TX_ENABLE_FIQ_NESTING + BL _tx_thread_fiq_nesting_end + ENDIF +; +; /* Jump to fiq context restore to restore system context. */ + B _tx_thread_fiq_context_restore +; +; + ELSE + EXPORT __tx_fiq_handler +__tx_fiq_handler + B __tx_fiq_handler ; FIQ interrupt handler + ENDIF +; +; /* Reference build options and version ID to ensure they come in. */ +; + LDR r2, =_tx_build_options ; Pickup build options variable address + LDR r0, [r2, #0] ; Pickup build options content + LDR r2, =_tx_version_id ; Pickup version ID variable address + LDR r0, [r2, #0] ; Pickup version ID content +; +; + END + diff --git a/ports/arm11/ac5/inc/tx_port.h b/ports/arm11/ac5/inc/tx_port.h new file mode 100644 index 000000000..90145158a --- /dev/null +++ b/ports/arm11/ac5/inc/tx_port.h @@ -0,0 +1,327 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Port Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_port.h ARM11/AC5 */ +/* 6.0.1 */ +/* */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data type definitions that make the ThreadX */ +/* real-time kernel function identically on a variety of different */ +/* processor architectures. For example, the size or number of bits */ +/* in an "int" data type vary between microprocessor architectures and */ +/* even C compilers for the same microprocessor. ThreadX does not */ +/* directly use native C data types. Instead, ThreadX creates its */ +/* own special types that can be mapped to actual data types by this */ +/* file to guarantee consistency in the interface and functionality. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +/* */ +/**************************************************************************/ + +#ifndef TX_PORT_H +#define TX_PORT_H + + +/* Determine if the optional ThreadX user define file should be used. */ + +#ifdef TX_INCLUDE_USER_DEFINE_FILE + + +/* Yes, include the user defines in tx_user.h. The defines in this file may + alternately be defined on the command line. */ + +#include "tx_user.h" +#endif + + +/* Define compiler library include files. */ + +#include +#include + + +/* Define ThreadX basic types for this port. */ + +#define VOID void +typedef char CHAR; +typedef unsigned char UCHAR; +typedef int INT; +typedef unsigned int UINT; +typedef long LONG; +typedef unsigned long ULONG; +typedef short SHORT; +typedef unsigned short USHORT; + + +/* Define the priority levels for ThreadX. Legal values range + from 32 to 1024 and MUST be evenly divisible by 32. */ + +#ifndef TX_MAX_PRIORITIES +#define TX_MAX_PRIORITIES 32 +#endif + + +/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during + thread creation is less than this value, the thread create call will return an error. */ + +#ifndef TX_MINIMUM_STACK +#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */ +#endif + + +/* Define the system timer thread's default stack size and priority. These are only applicable + if TX_TIMER_PROCESS_IN_ISR is not defined. */ + +#ifndef TX_TIMER_THREAD_STACK_SIZE +#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ +#endif + +#ifndef TX_TIMER_THREAD_PRIORITY +#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ +#endif + + +/* Define various constants for the ThreadX ARM port. */ + +#ifdef TX_ENABLE_FIQ_SUPPORT +#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */ +#else +#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */ +#endif +#define TX_INT_ENABLE 0x00 /* Enable IRQ interrupts */ + + +/* Define the clock source for trace event entry time stamp. The following two item are port specific. + For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock + source constants would be: + +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) +#define TX_TRACE_TIME_MASK 0x0000FFFFUL + +*/ + +#ifndef TX_TRACE_TIME_SOURCE +#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time +#endif +#ifndef TX_TRACE_TIME_MASK +#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL +#endif + + +/* Define the port specific options for the _tx_build_options variable. This variable indicates + how the ThreadX library was built. */ + +#ifdef TX_ENABLE_FIQ_SUPPORT +#define TX_FIQ_ENABLED 1 +#else +#define TX_FIQ_ENABLED 0 +#endif + +#ifdef TX_ENABLE_IRQ_NESTING +#define TX_IRQ_NESTING_ENABLED 2 +#else +#define TX_IRQ_NESTING_ENABLED 0 +#endif + +#ifdef TX_ENABLE_FIQ_NESTING +#define TX_FIQ_NESTING_ENABLED 4 +#else +#define TX_FIQ_NESTING_ENABLED 0 +#endif + +#define TX_PORT_SPECIFIC_BUILD_OPTIONS TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED + + +/* Define the in-line initialization constant so that modules with in-line + initialization capabilities can prevent their initialization from being + a function call. */ + +#define TX_INLINE_INITIALIZATION + + +/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is + disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack + checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING + define is negated, thereby forcing the stack fill which is necessary for the stack checking + logic. */ + +#ifdef TX_ENABLE_STACK_CHECKING +#undef TX_DISABLE_STACK_FILLING +#endif + + +/* Define the TX_THREAD control block extensions for this port. The main reason + for the multiple macros is so that backward compatibility can be maintained with + existing ThreadX kernel awareness modules. */ + +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#define TX_THREAD_EXTENSION_2 +#define TX_THREAD_EXTENSION_3 + + +/* Define the port extensions of the remaining ThreadX objects. */ + +#define TX_BLOCK_POOL_EXTENSION +#define TX_BYTE_POOL_EXTENSION +#define TX_EVENT_FLAGS_GROUP_EXTENSION +#define TX_MUTEX_EXTENSION +#define TX_QUEUE_EXTENSION +#define TX_SEMAPHORE_EXTENSION +#define TX_TIMER_EXTENSION + + +/* Define the user extension field of the thread control block. Nothing + additional is needed for this port so it is defined as white space. */ + +#ifndef TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION +#endif + + +/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, + tx_thread_shell_entry, and tx_thread_terminate. */ + + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) + + +/* Define the ThreadX object creation extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr) +#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr) +#define TX_QUEUE_CREATE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr) +#define TX_TIMER_CREATE_EXTENSION(timer_ptr) + + +/* Define the ThreadX object deletion extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr) +#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr) +#define TX_QUEUE_DELETE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) +#define TX_TIMER_DELETE_EXTENSION(timer_ptr) + + +/* Determine if the ARM architecture has the CLZ instruction. This is available on + architectures v5 and above. If available, redefine the macro for calculating the + lowest bit set. */ + +#ifndef __thumb + +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \ + b = (ULONG) __clz((unsigned int) m); \ + b = 31 - b; +#endif + + +/* Define ThreadX interrupt lockout and restore macros for protection on + access of critical kernel information. The restore interrupt macro must + restore the interrupt posture of the running thread prior to the value + present prior to the disable macro. In most cases, the save area macro + is used to define a local function save area for the disable and restore + macros. */ + +#ifndef __thumb + +#define TX_INTERRUPT_SAVE_AREA register unsigned int interrupt_save_disabled; + +#ifdef TX_ENABLE_FIQ_SUPPORT + +/* IRQ and FIQ support. */ + +#define TX_DISABLE __memory_changed(), interrupt_save_disabled = __disable_irq(); \ + __disable_fiq(); + +#define TX_RESTORE if (!interrupt_save_disabled) \ + { \ + __enable_irq(); \ + __enable_fiq(); \ + } + +#else + +#define TX_DISABLE __memory_changed(), interrupt_save_disabled = __disable_irq(); + +#define TX_RESTORE if (!interrupt_save_disabled) \ + { \ + __enable_irq(); \ + } +#endif + +#else + +unsigned int _tx_thread_interrupt_disable(void); +unsigned int _tx_thread_interrupt_restore(UINT old_posture); + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif + + +/* Define the interrupt lockout macros for each ThreadX object. */ + +#define TX_BLOCK_POOL_DISABLE TX_DISABLE +#define TX_BYTE_POOL_DISABLE TX_DISABLE +#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE +#define TX_MUTEX_DISABLE TX_DISABLE +#define TX_QUEUE_DISABLE TX_DISABLE +#define TX_SEMAPHORE_DISABLE TX_DISABLE + + +/* Define the version ID of ThreadX. This may be utilized by the application. */ + +#ifdef TX_THREAD_INIT +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX ARM11/AC5 Version 6.0.1 *"; +#else +extern CHAR _tx_version_id[]; +#endif + + +#endif + diff --git a/ports/arm11/ac5/readme_threadx.txt b/ports/arm11/ac5/readme_threadx.txt new file mode 100644 index 000000000..836a2e01d --- /dev/null +++ b/ports/arm11/ac5/readme_threadx.txt @@ -0,0 +1,534 @@ + Microsoft's Azure RTOS ThreadX for ARM11 + + Thumb & 32-bit Mode + + Using ARM Compiler 5 (AC5) + +1. Building the ThreadX run-time Library + +First make sure you are in the "example_build" directory. Also, make sure that +you have setup your path and other environment variables necessary for the ARM +AC5 development environment. At this point you may run the build_threadx.bat +batch file. This will build the ThreadX run-time environment in the +"example_build" directory. + +You should observe assembly and compilation of a series of ThreadX source +files. At the end of the batch file, they are all combined into the +run-time library file: tx.a. This file must be linked with your +application in order to use ThreadX. + + +2. Demonstration System + +Since there is no ARM11 FVP, there are no instructions here for running +the demonstration; users are expected to run the demonstration on their +platform of choice. + +Building the demonstration is easy; simply execute the build_threadx_sample.bat +batch file while inside the "example_build" directory. + +You should observe the compilation of sample_threadx.c (which is the demonstration +application) and linking with tx.a. The resulting file sample_threadx.axf +is a binary file that can be downloaded and executed on the user's platform of choice. + + +3. System Initialization + +The entry point in ThreadX for the Cortex-A5 using AC5 tools is at label +__main. This is defined within the AC5 compiler's startup code. In addition, +this is where all static and global pre-set C variable initialization processing +takes place. + +The ThreadX tx_initialize_low_level.s file is responsible for setting up +various system data structures, the vector area, and a periodic timer interrupt +source. By default, the vector area is defined to be located in the Init area, +which is defined at the top of tx_initialize_low_level.s. This area is typically +located at 0. In situations where this is impossible, the vectors at the beginning +of the Init area should be copied to address 0. + +This is also where initialization of a periodic timer interrupt source +should take place. + +In addition, _tx_initialize_low_level determines the first available +address for use by the application, which is supplied as the sole input +parameter to your application definition function, tx_application_define. + + +4. Assembler / Compiler Switches + +The following are compiler switches used in building the demonstration +system: + +Compiler Switch Meaning + + -g Specifies debug information + -c Specifies object code generation + --cpu Cortex-A5 Specifies Cortex-A5 instruction set + --apcs /interwork Specifies Thumb/32-bit compatibility + +Linker Switch Meaning + + -d Specifies to retain debug information in output file + -o demo.axf Specifies demo output file name + --elf Specifies elf output file format + --ro Specifies that Read-Only memory starts at address 0 + --first tx_initialize_low_level.o(Init) + Specifies that the first area loaded is Init + --remove Remove unused areas + --list Specifies map file name + --symbols Specifies symbols for map file + --map Creates a map file + +Application Defines + + --PD "TX_ENABLE_FIQ_SUPPORT SETL {TRUE}" This assembler define enables FIQ + interrupt handling support in the + ThreadX assembly files. If used, + it should be used on all assembly + files and the generic C source of + ThreadX should be compiled with + TX_ENABLE_FIQ_SUPPORT defined as well. + --PD "TX_ENABLE_IRQ_NESTING SETL {TRUE}" This assembler define enables IRQ + nested support. If IRQ nested + interrupt support is needed, this + define should be applied to + tx_initialize_low_level.s. + --PD "TX_ENABLE_FIQ_NESTING SETL {TRUE}" This assembler define enables FIQ + nested support. If FIQ nested + interrupt support is needed, this + define should be applied to + tx_initialize_low_level.s. In addition, + IRQ nesting should also be enabled. + -DTX_ENABLE_FIQ_SUPPORT This compiler define enables FIQ + interrupt handling in the ThreadX + generic C source. This define + should also be used in conjunction + with the corresponding assembler + define. + -DTX_DISABLE_ERROR_CHECKING If defined before tx_api.h is included, + this define causes basic ThreadX error + checking to be disabled. Please see + Chapter 2 in the "ThreadX User Guide" + for more details. + + -DTX_MAX_PRIORITIES Defines the priority levels for ThreadX. + Legal values range from 32 through + 1024 (inclusive) and MUST be evenly divisible + by 32. Increasing the number of priority levels + supported increases the RAM usage by 128 bytes + for every group of 32 priorities. However, there + is only a negligible effect on performance. By + default, this value is set to 32 priority levels. + + -DTX_MINIMUM_STACK Defines the minimum stack size (in bytes). It is + used for error checking when threads are created. + The default value is port-specific and is found + in tx_port.h. + + -DTX_TIMER_THREAD_STACK_SIZE Defines the stack size (in bytes) of the internal + ThreadX timer thread. This thread processes all + thread sleep requests as well as all service call + timeouts. In addition, all application timer callback + routines are invoked from this context. The default + value is port-specific and is found in tx_port.h. + + -DTX_TIMER_THREAD_PRIORITY Defines the priority of the internal ThreadX timer + thread. The default value is priority 0 - the highest + priority in ThreadX. The default value is defined + in tx_port.h. + + -DTX_TIMER_PROCESS_IN_ISR Defined, this option eliminates the internal system + timer thread for ThreadX. This results in improved + performance on timer events and smaller RAM requirements + because the timer stack and control block are no + longer needed. However, using this option moves all + the timer expiration processing to the timer ISR level. + By default, this option is not defined. + + -DTX_REACTIVATE_INLINE Defined, this option performs reactivation of ThreadX + timers in-line instead of using a function call. This + improves performance but slightly increases code size. + By default, this option is not defined. + + -DTX_DISABLE_STACK_FILLING Defined, placing the 0xEF value in each byte of each + thread's stack is disabled. By default, this option is + not defined. + + -DTX_ENABLE_STACK_CHECKING Defined, this option enables ThreadX run-time stack checking, + which includes analysis of how much stack has been used and + examination of data pattern "fences" before and after the + stack area. If a stack error is detected, the registered + application stack error handler is called. This option does + result in slightly increased overhead and code size. Please + review the tx_thread_stack_error_notify API for more information. + By default, this option is not defined. + + -DTX_DISABLE_PREEMPTION_THRESHOLD Defined, this option disables the preemption-threshold feature + and slightly reduces code size and improves performance. Of course, + the preemption-threshold capabilities are no longer available. + By default, this option is not defined. + + -DTX_DISABLE_REDUNDANT_CLEARING Defined, this option removes the logic for initializing ThreadX + global C data structures to zero. This should only be used if + the compiler's initialization code sets all un-initialized + C global data to zero. Using this option slightly reduces + code size and improves performance during initialization. + By default, this option is not defined. + + -DTX_DISABLE_NOTIFY_CALLBACKS Defined, this option disables the notify callbacks for various + ThreadX objects. Using this option slightly reduces code size + and improves performance. + + -DTX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on block pools. By default, this option is + not defined. + + -DTX_BYTE_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on byte pools. By default, this option is + not defined. + + -DTX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on event flags groups. By default, this option + is not defined. + + -DTX_MUTEX_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on mutexes. By default, this option is + not defined. + + -DTX_QUEUE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on queues. By default, this option is + not defined. + + -DTX_SEMAPHORE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on semaphores. By default, this option is + not defined. + + -DTX_THREAD_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on threads. By default, this option is + not defined. + + -DTX_TIMER_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on timers. By default, this option is + not defined. + + -DTX_ENABLE_EVENT_TRACE Defined, this option enables the internal ThreadX trace + feature. The trace buffer is supplied at a later time + via an application call to tx_trace_enable. + + -DTX_TRACE_TIME_SOURCE This defines the time-stamp source for event tracing. + This define is only pertinent if the ThreadX library is + built with TX_ENABLE_EVENT_TRACE defined. + + -DTX_TRACE_TIME_MASK This defines the number of valid bits in the event trace + time-stamp source defined previously. If the time-stamp + source is 16-bits, this value should be 0xFFFF. Alternatively, + if the time-stamp source is 32-bits, this value should be + 0xFFFFFFFF. This define is only pertinent if the ThreadX + library is built with TX_ENABLE_EVENT_TRACE defined. + + + +5. Register Usage and Stack Frames + +The AC5 compiler assumes that registers r0-r3 (a1-a4) and r12 (ip) are scratch +registers for each function. All other registers used by a C function must +be preserved by the function. ThreadX takes advantage of this in situations +where a context switch happens as a result of making a ThreadX service call +(which is itself a C function). In such cases, the saved context of a thread +is only the non-scratch registers. + +The following defines the saved context stack frames for context switches +that occur as a result of interrupt handling or from thread-level API calls. +All suspended threads have one of these two types of stack frames. The top +of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the +associated thread control block TX_THREAD. + + + + Offset Interrupted Stack Frame Non-Interrupt Stack Frame + + 0x00 1 0 + 0x04 CPSR CPSR + 0x08 r0 (a1) r4 (v1) + 0x0C r1 (a2) r5 (v2) + 0x10 r2 (a3) r6 (v3) + 0x14 r3 (a4) r7 (v4) + 0x18 r4 (v1) r8 (v5) + 0x1C r5 (v2) r9 (v6) + 0x20 r6 (v3) r10 (v7) + 0x24 r7 (v4) r11 (fp) + 0x28 r8 (v5) r14 (lr) + 0x2C r9 (v6) + 0x30 r10 (v7) + 0x34 r11 (fp) + 0x38 r12 (ip) + 0x3C r14 (lr) + 0x40 PC + + +6. Improving Performance + +The distribution version of ThreadX is built without any compiler +optimizations. This makes it easy to debug because you can trace or set +breakpoints inside of ThreadX itself. Of course, this costs some +performance. To make it run faster, you can change the build_threadx.bat file to +remove the -g option and enable all compiler optimizations. + +In addition, you can eliminate the ThreadX basic API error checking by +compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING +defined. + + +7. Interrupt Handling + +ThreadX provides complete and high-performance interrupt handling for Cortex-A5 +targets. There are a certain set of requirements that are defined in the +following sub-sections: + + +7.1 Vector Area + +The Cortex-A5 vectors start at address zero. The demonstration system startup +Init area contains the vectors and is loaded at address zero. On actual +hardware platforms, this area might have to be copied to address 0. + + +7.2 IRQ ISRs + +ThreadX fully manages standard and vectored IRQ interrupts. ThreadX also supports nested +IRQ interrupts. The following sub-sections define the IRQ capabilities. + + +7.2.1 Standard IRQ ISRs + +The standard ARM IRQ mechanism has a single interrupt vector at address 0x18. This IRQ +interrupt is managed by the __tx_irq_handler code in tx_initialize_low_level. The following +is the default IRQ handler defined in tx_initialize_low_level.s: + + EXPORT __tx_irq_handler + EXPORT __tx_irq_processing_return +__tx_irq_handler +; +; /* Jump to context save to save system context. */ + B _tx_thread_context_save ; Jump to the context save +__tx_irq_processing_return +; +; /* At this point execution is still in the IRQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. Note +; that IRQ interrupts are still disabled upon return from the context +; save function. */ +; +; /* Application ISR call(s) go here! */ +; +; /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore + + +7.2.2 Vectored IRQ ISRs + +The vectored ARM IRQ mechanism has multiple interrupt vectors at addresses specified +by the particular implementation. The following is an example IRQ handler defined in +tx_initialize_low_level.s: + + EXPORT __tx_irq_example_handler +__tx_irq_example_handler +; +; /* Call context save to save system context. */ + + STMDB sp!, {r0-r3} ; Save some scratch registers + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} ; Store other scratch registers + BL _tx_thread_vectored_context_save ; Call the vectored IRQ context save +; +; /* At this point execution is still in the IRQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. Note +; that IRQ interrupts are still disabled upon return from the context +; save function. */ +; +; /* Application ISR call goes here! */ +; +; /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore + + +7.2.3 Nested IRQ Support + +By default, nested IRQ interrupt support is not enabled. To enable nested +IRQ support, the entire library should be built with TX_ENABLE_IRQ_NESTING +defined. With this defined, two new IRQ interrupt management services are +available, namely _tx_thread_irq_nesting_start and _tx_thread_irq_nesting_end. +These function should be called between the IRQ context save and restore +calls. + +Execution between the calls to _tx_thread_irq_nesting_start and +_tx_thread_irq_nesting_end is enabled for IRQ nesting. This is achieved +by switching from IRQ mode to SYS mode and enabling IRQ interrupts. +The SYS mode stack is used during the SYS mode operation, which was +setup in tx_initialize_low_level.s. When nested IRQ interrupts are no longer required, +calling the _tx_thread_irq_nesting_end service disables nesting by disabling +IRQ interrupts and switching back to IRQ mode in preparation for the IRQ +context restore service. + +The following is an example of enabling IRQ nested interrupts in a standard +IRQ handler: + + EXPORT __tx_irq_handler + EXPORT __tx_irq_processing_return +__tx_irq_handler +; +; /* Jump to context save to save system context. */ + B _tx_thread_context_save +__tx_irq_processing_return +; +; /* Enable nested IRQ interrupts. NOTE: Since this service returns +; with IRQ interrupts enabled, all IRQ interrupt sources must be +; cleared prior to calling this service. */ + BL _tx_thread_irq_nesting_start +; +; /* Application ISR call(s) go here! */ +; +; /* Disable nested IRQ interrupts. The mode is switched back to +; IRQ mode and IRQ interrupts are disable upon return. */ + BL _tx_thread_irq_nesting_end +; +; /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore + + +7.3 FIQ Interrupts + +By default, Cortex-A5 FIQ interrupts are left alone by ThreadX. Of course, this +means that the application is fully responsible for enabling the FIQ interrupt +and saving/restoring any registers used in the FIQ ISR processing. To globally +enable FIQ interrupts, the application should enable FIQ interrupts at the +beginning of each thread or before any threads are created in tx_application_define. +In addition, the application must ensure that no ThreadX service calls are made +from default FIQ ISRs, which is located in tx_initialize_low_level.s. + + +7.3.1 Managed FIQ Interrupts + +Full ThreadX management of FIQ interrupts is provided if the ThreadX sources +are built with the TX_ENABLE_FIQ_SUPPORT defined. If the library is built +this way, the FIQ interrupt handlers are very similar to the IRQ interrupt +handlers defined previously. The following is default FIQ handler +defined in tx_initialize_low_level.s: + + + EXPORT __tx_fiq_handler + EXPORT __tx_fiq_processing_return +__tx_fiq_handler +; +; /* Jump to fiq context save to save system context. */ + B _tx_thread_fiq_context_save +__tx_fiq_processing_return: +; +; /* At this point execution is still in the FIQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. */ +; +; /* Application FIQ handlers can be called here! */ +; +; /* Jump to fiq context restore to restore system context. */ + B _tx_thread_fiq_context_restore + + +7.3.1.1 Nested FIQ Support + +By default, nested FIQ interrupt support is not enabled. To enable nested +FIQ support, the entire library should be built with TX_ENABLE_FIQ_NESTING +defined. With this defined, two new FIQ interrupt management services are +available, namely _tx_thread_fiq_nesting_start and _tx_thread_fiq_nesting_end. +These function should be called between the FIQ context save and restore +calls. + +Execution between the calls to _tx_thread_fiq_nesting_start and +_tx_thread_fiq_nesting_end is enabled for FIQ nesting. This is achieved +by switching from FIQ mode to SYS mode and enabling FIQ interrupts. +The SYS mode stack is used during the SYS mode operation, which was +setup in tx_initialize_low_level.s. When nested FIQ interrupts are no longer required, +calling the _tx_thread_fiq_nesting_end service disables nesting by disabling +FIQ interrupts and switching back to FIQ mode in preparation for the FIQ +context restore service. + +The following is an example of enabling FIQ nested interrupts in the +typical FIQ handler: + + + EXPORT __tx_fiq_handler + EXPORT __tx_fiq_processing_return +__tx_fiq_handler +; +; /* Jump to fiq context save to save system context. */ + B _tx_thread_fiq_context_save +__tx_fiq_processing_return +; +; /* At this point execution is still in the FIQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. */ +; +; /* Enable nested FIQ interrupts. NOTE: Since this service returns +; with FIQ interrupts enabled, all FIQ interrupt sources must be +; cleared prior to calling this service. */ + BL _tx_thread_fiq_nesting_start +; +; /* Application FIQ handlers can be called here! */ +; +; /* Disable nested FIQ interrupts. The mode is switched back to +; FIQ mode and FIQ interrupts are disable upon return. */ + BL _tx_thread_fiq_nesting_end +; +; /* Jump to fiq context restore to restore system context. */ + B _tx_thread_fiq_context_restore + + +8. ThreadX Timer Interrupt + +ThreadX requires a periodic interrupt source to manage all time-slicing, +thread sleeps, timeouts, and application timers. Without such a timer +interrupt source, these services are not functional. However, all other +ThreadX services are operational without a periodic timer source. + +To add the timer interrupt processing, simply make a call to +_tx_timer_interrupt in the IRQ processing. An example of this can be +found in the file tx_initialize_low_level.s in the Integrator sub-directories. + + +9. Thumb/Cortex-A5 Mixed Mode + +By default, ThreadX is setup for running in Cortex-A5 32-bit mode. This is +also true for the demonstration system. It is possible to build any +ThreadX file and/or the application in Thumb mode. If any Thumb code +is used the entire ThreadX source- both C and assembly - should be built +with the "-apcs /interwork" option. + +11. VFP Support + +By default, VFP support is disabled for each thread. If saving the context of the VFP registers +is needed, the following API call must be made from the context of the application thread - before +the VFP usage: + +void tx_thread_vfp_enable(void); + +After this API is called in the application, VFP registers will be saved/restored for this thread if it +is preempted via an interrupt. All other suspension of the this thread will not require the VFP registers +to be saved/restored. + +To disable VFP register context saving, simply call the following API: + +void tx_thread_vfp_disable(void); + + +12. Revision History + +For generic code revision information, please refer to the readme_threadx_generic.txt +file, which is included in your distribution. The following details the revision +information associated with this specific port of ThreadX: + +06/30/2020 Initial ThreadX 6.0.1 version for Cortex-A5 using AC5 tools. + + +Copyright(c) 1996-2020 Microsoft Corporation + + +https://azure.com/rtos + diff --git a/ports/arm11/ac5/src/tx_thread_context_restore.s b/ports/arm11/ac5/src/tx_thread_context_restore.s new file mode 100644 index 000000000..1d6cd60f8 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_context_restore.s @@ -0,0 +1,247 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +IRQ_MODE EQU 0xD2 ; IRQ mode +SVC_MODE EQU 0xD3 ; SVC mode + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts + ELSE +DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts + ENDIF +MODE_MASK EQU 0x1F ; Mode mask +THUMB_MASK EQU 0x20 ; Thumb bit mask +SVC_MODE_BITS EQU 0x13 ; SVC mode value +; +; + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT _tx_thread_execute_ptr + IMPORT _tx_timer_time_slice + IMPORT _tx_thread_schedule + IMPORT _tx_thread_preempt_disable + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_exit + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_restore ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function restores the interrupt context if it is processing a */ +;/* nested interrupt. If not, it returns to the interrupt thread if no */ +;/* preemption is necessary. Otherwise, if preemption is necessary or */ +;/* if no thread was running, the function returns to the scheduler. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling routine */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs Interrupt Service Routines */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_restore(VOID) +;{ + EXPORT _tx_thread_context_restore +_tx_thread_context_restore +; +; /* Lockout interrupts. */ +; + MRS r3, CPSR ; Pickup current CPSR + ORR r0, r3, #DISABLE_INTS ; Build interrupt disable value + MSR CPSR_cxsf, r0 ; Lockout interrupts + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR exit function to indicate an ISR is complete. */ +; + BL _tx_execution_isr_exit ; Call the ISR exit function + ENDIF +; +; /* Determine if interrupts are nested. */ +; if (--_tx_thread_system_state) +; { +; + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3, #0] ; Pickup system state + SUB r2, r2, #1 ; Decrement the counter + STR r2, [r3, #0] ; Store the counter + CMP r2, #0 ; Was this the first interrupt? + BEQ __tx_thread_not_nested_restore ; If so, not a nested restore +; +; /* Interrupts are nested. */ +; +; /* Just recover the saved registers and return to the point of +; interrupt. */ +; + LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +__tx_thread_not_nested_restore +; +; /* Determine if a thread was interrupted and no preemption is required. */ +; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +; || (_tx_thread_preempt_disable)) +; { +; + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup actual current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_idle_system_restore ; Yes, idle system was interrupted +; + LDR r3, =_tx_thread_preempt_disable ; Pickup preempt disable address + LDR r2, [r3, #0] ; Pickup actual preempt disable flag + CMP r2, #0 ; Is it set? + BNE __tx_thread_no_preempt_restore ; Yes, don't preempt this thread + LDR r3, =_tx_thread_execute_ptr ; Pickup address of execute thread ptr + LDR r2, [r3, #0] ; Pickup actual execute thread pointer + CMP r0, r2 ; Is the same thread highest priority? + BNE __tx_thread_preempt_restore ; No, preemption needs to happen +; +; +__tx_thread_no_preempt_restore +; +; /* Restore interrupted thread or ISR. */ +; +; /* Pickup the saved stack pointer. */ +; tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; +; +; /* Recover the saved context and return to the point of interrupt. */ +; + LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +; else +; { +__tx_thread_preempt_restore +; + LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers + MOV r1, lr ; Save lr (point of interrupt) + MOV r2, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_c, r2 ; Enter SVC mode + STR r1, [sp, #-4]! ; Save point of interrupt + STMDB sp!, {r4-r12, lr} ; Save upper half of registers + MOV r4, r3 ; Save SPSR in r4 + MOV r2, #IRQ_MODE ; Build IRQ mode CPSR + MSR CPSR_c, r2 ; Enter IRQ mode + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOV r5, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_c, r5 ; Enter SVC mode + STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack + MOV r3, #1 ; Build interrupt stack type + STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup current thread pointer + STR sp, [r0, #8] ; Save stack pointer in thread control + ; block + BIC r4, r4, #THUMB_MASK ; Clear the Thumb bit of CPSR + ORR r3, r4, #DISABLE_INTS ; Or-in interrupt lockout bit(s) + MSR CPSR_cxsf, r3 ; Lockout interrupts +; +; /* Save the remaining time-slice and disable it. */ +; if (_tx_timer_time_slice) +; { +; + LDR r3, =_tx_timer_time_slice ; Pickup time-slice variable address + LDR r2, [r3, #0] ; Pickup time-slice + CMP r2, #0 ; Is it active? + BEQ __tx_thread_dont_save_ts ; No, don't save it +; +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + STR r2, [r0, #24] ; Save thread's time-slice + MOV r2, #0 ; Clear value + STR r2, [r3, #0] ; Disable global time-slice flag +; +; } +__tx_thread_dont_save_ts +; +; +; /* Clear the current task pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + MOV r0, #0 ; NULL value + STR r0, [r1, #0] ; Clear current thread pointer +; +; /* Return to the scheduler. */ +; _tx_thread_schedule(); +; + B _tx_thread_schedule ; Return to scheduler +; } +; +__tx_thread_idle_system_restore +; +; /* Just return back to the scheduler! */ +; + MRS r3, CPSR ; Pickup current CPSR + BIC r3, r3, #MODE_MASK ; Clear the mode portion of the CPSR + ORR r3, r3, #SVC_MODE_BITS ; Or-in new interrupt lockout bit + MSR CPSR_cxsf, r3 ; Lockout interrupts + B _tx_thread_schedule ; Return to scheduler +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_context_save.s b/ports/arm11/ac5/src/tx_thread_context_save.s new file mode 100644 index 000000000..6ce74590a --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_context_save.s @@ -0,0 +1,207 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled + ELSE +DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled + ENDIF + + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT __tx_irq_processing_return + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_enter + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_save ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function saves the context of an executing thread in the */ +;/* beginning of interrupt processing. The function also ensures that */ +;/* the system stack is used upon return to the calling ISR. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_save(VOID) +;{ + EXPORT _tx_thread_context_save +_tx_thread_context_save +; +; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +; out, we are in IRQ mode, and all registers are intact. */ +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; + STMDB sp!, {r0-r3} ; Save some working registers + IF :DEF:TX_ENABLE_FIQ_SUPPORT + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt CPSR + MSR CPSR_cxsf, r0 ; Disable interrupts + ENDIF + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3, #0] ; Pickup system state + CMP r2, #0 ; Is this the first interrupt? + BEQ __tx_thread_not_nested_save ; Yes, not a nested context save +; +; /* Nested interrupt condition. */ +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3, #0] ; Store it back in the variable +; +; /* Save the rest of the scratch registers on the stack and return to the +; calling ISR. */ +; + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} ; Store other registers +; +; /* Return to the ISR. */ +; + MOV r10, #0 ; Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr + ENDIF + + B __tx_irq_processing_return ; Continue IRQ processing +; +__tx_thread_not_nested_save +; } +; +; /* Otherwise, not nested, check to see if a thread was running. */ +; else if (_tx_thread_current_ptr) +; { +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3, #0] ; Store it back in the variable + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in + ; scheduling loop - nothing needs saving! +; +; /* Save minimal context of interrupted thread. */ +; + MRS r2, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r2, r10, r12, lr} ; Store other registers +; +; /* Save the current stack pointer in the thread's control block. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +; +; /* Switch to the system stack. */ +; sp = _tx_thread_system_stack_ptr; +; + MOV r10, #0 ; Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr + ENDIF + + B __tx_irq_processing_return ; Continue IRQ processing +; +; } +; else +; { +; +__tx_thread_idle_system_save +; +; /* Interrupt occurred in the scheduling loop. */ +; +; /* Not much to do here, just adjust the stack pointer, and return to IRQ +; processing. */ +; + MOV r10, #0 ; Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr + ENDIF + + ADD sp, sp, #16 ; Recover saved registers + B __tx_irq_processing_return ; Continue IRQ processing +; +; } +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_fiq_context_restore.s b/ports/arm11/ac5/src/tx_thread_fiq_context_restore.s new file mode 100644 index 000000000..a183032b3 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_fiq_context_restore.s @@ -0,0 +1,259 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +SVC_MODE EQU 0xD3 ; SVC mode +FIQ_MODE EQU 0xD1 ; FIQ mode + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts + ELSE +DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts + ENDIF +MODE_MASK EQU 0x1F ; Mode mask +THUMB_MASK EQU 0x20 ; Thumb bit mask +IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits +SVC_MODE_BITS EQU 0x13 ; SVC mode value +; +; + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT _tx_thread_system_stack_ptr + IMPORT _tx_thread_execute_ptr + IMPORT _tx_timer_time_slice + IMPORT _tx_thread_schedule + IMPORT _tx_thread_preempt_disable + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_exit + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_context_restore ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function restores the fiq interrupt context when processing a */ +;/* nested interrupt. If not, it returns to the interrupt thread if no */ +;/* preemption is necessary. Otherwise, if preemption is necessary or */ +;/* if no thread was running, the function returns to the scheduler. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling routine */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* FIQ ISR Interrupt Service Routines */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_fiq_context_restore(VOID) +;{ + EXPORT _tx_thread_fiq_context_restore +_tx_thread_fiq_context_restore +; +; /* Lockout interrupts. */ +; + MRS r3, CPSR ; Pickup current CPSR + ORR r0, r3, #DISABLE_INTS ; Build interrupt disable value + MSR CPSR_cxsf, r0 ; Lockout interrupts + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR exit function to indicate an ISR is complete. */ +; + BL _tx_execution_isr_exit ; Call the ISR exit function + ENDIF +; +; /* Determine if interrupts are nested. */ +; if (--_tx_thread_system_state) +; { +; + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3] ; Pickup system state + SUB r2, r2, #1 ; Decrement the counter + STR r2, [r3] ; Store the counter + CMP r2, #0 ; Was this the first interrupt? + BEQ __tx_thread_fiq_not_nested_restore ; If so, not a nested restore +; +; /* Interrupts are nested. */ +; +; /* Just recover the saved registers and return to the point of +; interrupt. */ +; + LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +__tx_thread_fiq_not_nested_restore +; +; /* Determine if a thread was interrupted and no preemption is required. */ +; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +; || (_tx_thread_preempt_disable)) +; { +; + LDR r1, [sp] ; Pickup the saved SPSR + MOV r2, #MODE_MASK ; Build mask to isolate the interrupted mode + AND r1, r1, r2 ; Isolate mode bits + CMP r1, #IRQ_MODE_BITS ; Was an interrupt taken in IRQ mode before we + ; got to context save? */ + BEQ __tx_thread_fiq_no_preempt_restore ; Yes, just go back to point of interrupt + + + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1] ; Pickup actual current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_fiq_idle_system_restore ; Yes, idle system was interrupted + + LDR r3, =_tx_thread_preempt_disable ; Pickup preempt disable address + LDR r2, [r3] ; Pickup actual preempt disable flag + CMP r2, #0 ; Is it set? + BNE __tx_thread_fiq_no_preempt_restore ; Yes, don't preempt this thread + LDR r3, =_tx_thread_execute_ptr ; Pickup address of execute thread ptr + LDR r2, [r3] ; Pickup actual execute thread pointer + CMP r0, r2 ; Is the same thread highest priority? + BNE __tx_thread_fiq_preempt_restore ; No, preemption needs to happen + + +__tx_thread_fiq_no_preempt_restore +; +; /* Restore interrupted thread or ISR. */ +; +; /* Pickup the saved stack pointer. */ +; tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; +; +; /* Recover the saved context and return to the point of interrupt. */ +; + LDMIA sp!, {r0, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +; else +; { +__tx_thread_fiq_preempt_restore +; + LDMIA sp!, {r3, lr} ; Recover temporarily saved registers + MOV r1, lr ; Save lr (point of interrupt) + MOV r2, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_cxsf, r2 ; Enter SVC mode + STR r1, [sp, #-4]! ; Save point of interrupt + STMDB sp!, {r4-r12, lr} ; Save upper half of registers + MOV r4, r3 ; Save SPSR in r4 + MOV r2, #FIQ_MODE ; Build FIQ mode CPSR + MSR CPSR_cxsf, r2 ; Re-enter FIQ mode + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOV r5, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_cxsf, r5 ; Enter SVC mode + STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack + MOV r3, #1 ; Build interrupt stack type + STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1] ; Pickup current thread pointer + STR sp, [r0, #8] ; Save stack pointer in thread control + ; block */ + BIC r4, r4, #THUMB_MASK ; Clear the Thumb bit of CPSR + ORR r3, r4, #DISABLE_INTS ; Or-in interrupt lockout bit(s) + MSR CPSR_cxsf, r3 ; Lockout interrupts +; +; /* Save the remaining time-slice and disable it. */ +; if (_tx_timer_time_slice) +; { +; + LDR r3, =_tx_timer_time_slice ; Pickup time-slice variable address + LDR r2, [r3] ; Pickup time-slice + CMP r2, #0 ; Is it active? + BEQ __tx_thread_fiq_dont_save_ts ; No, don't save it +; +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + STR r2, [r0, #24] ; Save thread's time-slice + MOV r2, #0 ; Clear value + STR r2, [r3] ; Disable global time-slice flag +; +; } +__tx_thread_fiq_dont_save_ts +; +; +; /* Clear the current task pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + MOV r0, #0 ; NULL value + STR r0, [r1] ; Clear current thread pointer +; +; /* Return to the scheduler. */ +; _tx_thread_schedule(); +; + B _tx_thread_schedule ; Return to scheduler +; } +; +__tx_thread_fiq_idle_system_restore +; +; /* Just return back to the scheduler! */ +; + ADD sp, sp, #24 ; Recover FIQ stack space + MRS r3, CPSR ; Pickup current CPSR + BIC r3, r3, #MODE_MASK ; Clear the mode portion of the CPSR + ORR r3, r3, #SVC_MODE_BITS ; Or-in new interrupt lockout bit + MSR CPSR_cxsf, r3 ; Lockout interrupts + B _tx_thread_schedule ; Return to scheduler +; +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_fiq_context_save.s b/ports/arm11/ac5/src/tx_thread_fiq_context_save.s new file mode 100644 index 000000000..370e09468 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_fiq_context_save.s @@ -0,0 +1,203 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT __tx_fiq_processing_return + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_enter + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_context_save ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function saves the context of an executing thread in the */ +;/* beginning of interrupt processing. The function also ensures that */ +;/* the system stack is used upon return to the calling ISR. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +; VOID _tx_thread_fiq_context_save(VOID) +;{ + EXPORT _tx_thread_fiq_context_save +_tx_thread_fiq_context_save +; +; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +; out, we are in IRQ mode, and all registers are intact. */ +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; + STMDB sp!, {r0-r3} ; Save some working registers + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3] ; Pickup system state + CMP r2, #0 ; Is this the first interrupt? + BEQ __tx_thread_fiq_not_nested_save ; Yes, not a nested context save +; +; /* Nested interrupt condition. */ +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3] ; Store it back in the variable +; +; /* Save the rest of the scratch registers on the stack and return to the +; calling ISR. */ +; + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} ; Store other registers +; +; /* Return to the ISR. */ +; + MOV r10, #0 ; Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr + ENDIF + + B __tx_fiq_processing_return ; Continue FIQ processing +; +__tx_thread_fiq_not_nested_save +; } +; +; /* Otherwise, not nested, check to see if a thread was running. */ +; else if (_tx_thread_current_ptr) +; { +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3] ; Store it back in the variable + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1] ; Pickup current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_fiq_idle_system_save ; If so, interrupt occurred in +; ; scheduling loop - nothing needs saving! +; +; /* Save minimal context of interrupted thread. */ +; + MRS r2, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r2, lr} ; Store other registers, Note that we don't +; ; need to save sl and ip since FIQ has +; ; copies of these registers. Nested +; ; interrupt processing does need to save +; ; these registers. +; +; /* Save the current stack pointer in the thread's control block. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +; +; /* Switch to the system stack. */ +; sp = _tx_thread_system_stack_ptr; +; + MOV r10, #0 ; Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr + ENDIF + + B __tx_fiq_processing_return ; Continue FIQ processing +; +; } +; else +; { +; +__tx_thread_fiq_idle_system_save +; +; /* Interrupt occurred in the scheduling loop. */ +; + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr + ENDIF +; +; /* Not much to do here, save the current SPSR and LR for possible +; use in IRQ interrupted in idle system conditions, and return to +; FIQ interrupt processing. */ +; + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r0, lr} ; Store other registers that will get used +; ; or stripped off the stack in context +; ; restore + B __tx_fiq_processing_return ; Continue FIQ processing +; +; } +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s b/ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s new file mode 100644 index 000000000..5d81879d6 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_fiq_nesting_end.s @@ -0,0 +1,111 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts + ELSE +DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts + ENDIF +MODE_MASK EQU 0x1F ; Mode mask +FIQ_MODE_BITS EQU 0x11 ; FIQ mode bits +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_nesting_end ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from FIQ mode after */ +;/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */ +;/* processing from system mode back to FIQ mode prior to the ISR */ +;/* calling _tx_thread_fiq_context_restore. Note that this function */ +;/* assumes the system stack pointer is in the same position after */ +;/* nesting start function was called. */ +;/* */ +;/* This function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s). */ +;/* */ +;/* This function returns with FIQ interrupts disabled. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_fiq_nesting_end(VOID) +;{ + EXPORT _tx_thread_fiq_nesting_end +_tx_thread_fiq_nesting_end + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt value + MSR CPSR_cxsf, r0 ; Disable interrupts + LDMIA sp!, {r1, lr} ; Pickup saved lr (and r1 throw-away for + ; 8-byte alignment logic) + BIC r0, r0, #MODE_MASK ; Clear mode bits + ORR r0, r0, #FIQ_MODE_BITS ; Build IRQ mode CPSR + MSR CPSR_cxsf, r0 ; Re-enter IRQ mode + IF {INTER} = {TRUE} + BX r3 ; Return to caller + ELSE + MOV pc, r3 ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s b/ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s new file mode 100644 index 000000000..32c1b2587 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_fiq_nesting_start.s @@ -0,0 +1,104 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +FIQ_DISABLE EQU 0x40 ; FIQ disable bit +MODE_MASK EQU 0x1F ; Mode mask +SYS_MODE_BITS EQU 0x1F ; System mode bits +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_nesting_start ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from FIQ mode after */ +;/* _tx_thread_fiq_context_save has been called and switches the FIQ */ +;/* processing to the system mode so nested FIQ interrupt processing */ +;/* is possible (system mode has its own "lr" register). Note that */ +;/* this function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s). */ +;/* */ +;/* This function returns with FIQ interrupts enabled. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_fiq_nesting_start(VOID) +;{ + EXPORT _tx_thread_fiq_nesting_start +_tx_thread_fiq_nesting_start + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + BIC r0, r0, #MODE_MASK ; Clear the mode bits + ORR r0, r0, #SYS_MODE_BITS ; Build system mode CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + STMDB sp!, {r1, lr} ; Push the system mode lr on the system mode stack + ; and push r1 just to keep 8-byte alignment + BIC r0, r0, #FIQ_DISABLE ; Build enable FIQ CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + IF {INTER} = {TRUE} + BX r3 ; Return to caller + ELSE + MOV pc, r3 ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_interrupt_control.s b/ports/arm11/ac5/src/tx_thread_interrupt_control.s new file mode 100644 index 000000000..f11c820e7 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_interrupt_control.s @@ -0,0 +1,102 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +INT_MASK EQU 0xC0 ; Interrupt bit mask + ELSE +INT_MASK EQU 0x80 ; Interrupt bit mask + ENDIF +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_control ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for changing the interrupt lockout */ +;/* posture of the system. */ +;/* */ +;/* INPUT */ +;/* */ +;/* new_posture New interrupt lockout posture */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* old_posture Old interrupt lockout posture */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* Application Code */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;UINT _tx_thread_interrupt_control(UINT new_posture) +;{ + EXPORT _tx_thread_interrupt_control +_tx_thread_interrupt_control +; +; /* Pickup current interrupt lockout posture. */ +; + MRS r3, CPSR ; Pickup current CPSR + BIC r1, r3, #INT_MASK ; Clear interrupt lockout bits + ORR r1, r1, r0 ; Or-in new interrupt lockout bits +; +; /* Apply the new interrupt posture. */ +; + MSR CPSR_cxsf, r1 ; Setup new CPSR + AND r0, r3, #INT_MASK ; Return previous interrupt mask + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_interrupt_disable.s b/ports/arm11/ac5/src/tx_thread_interrupt_disable.s new file mode 100644 index 000000000..a3145dab7 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_interrupt_disable.s @@ -0,0 +1,98 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled + ELSE +DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled + ENDIF +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_disable ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for disabling interrupts */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* old_posture Old interrupt lockout posture */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* Application Code */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;UINT _tx_thread_interrupt_disable(void) +;{ + EXPORT _tx_thread_interrupt_disable +_tx_thread_interrupt_disable +; +; /* Pickup current interrupt lockout posture. */ +; + MRS r0, CPSR ; Pickup current CPSR +; +; /* Mask interrupts. */ +; + ORR r1, r0, #DISABLE_INTS ; Mask interrupts + MSR CPSR_cxsf, r1 ; Setup new CPSR + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_interrupt_restore.s b/ports/arm11/ac5/src/tx_thread_interrupt_restore.s new file mode 100644 index 000000000..aad4e743e --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_interrupt_restore.s @@ -0,0 +1,87 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_restore ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for restoring interrupts to the state */ +;/* returned by a previous _tx_thread_interrupt_disable call. */ +;/* */ +;/* INPUT */ +;/* */ +;/* old_posture Old interrupt lockout posture */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* Application Code */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;UINT _tx_thread_interrupt_restore(UINT old_posture) +;{ + EXPORT _tx_thread_interrupt_restore +_tx_thread_interrupt_restore +; +; /* Apply the new interrupt posture. */ +; + MSR CPSR_cxsf, r0 ; Setup new CPSR + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_irq_nesting_end.s b/ports/arm11/ac5/src/tx_thread_irq_nesting_end.s new file mode 100644 index 000000000..415d6152c --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_irq_nesting_end.s @@ -0,0 +1,110 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts + ELSE +DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts + ENDIF +MODE_MASK EQU 0x1F ; Mode mask +IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_irq_nesting_end ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from IRQ mode after */ +;/* _tx_thread_irq_nesting_start has been called and switches the IRQ */ +;/* processing from system mode back to IRQ mode prior to the ISR */ +;/* calling _tx_thread_context_restore. Note that this function */ +;/* assumes the system stack pointer is in the same position after */ +;/* nesting start function was called. */ +;/* */ +;/* This function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s). */ +;/* */ +;/* This function returns with IRQ interrupts disabled. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_irq_nesting_end(VOID) +;{ + EXPORT _tx_thread_irq_nesting_end +_tx_thread_irq_nesting_end + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt value + MSR CPSR_cxsf, r0 ; Disable interrupts + LDMIA sp!, {r1, lr} ; Pickup saved lr (and r1 throw-away for + ; 8-byte alignment logic) + BIC r0, r0, #MODE_MASK ; Clear mode bits + ORR r0, r0, #IRQ_MODE_BITS ; Build IRQ mode CPSR + MSR CPSR_cxsf, r0 ; Re-enter IRQ mode + IF {INTER} = {TRUE} + BX r3 ; Return to caller + ELSE + MOV pc, r3 ; Return to caller + ENDIF +;} + END + diff --git a/ports/arm11/ac5/src/tx_thread_irq_nesting_start.s b/ports/arm11/ac5/src/tx_thread_irq_nesting_start.s new file mode 100644 index 000000000..417235dd6 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_irq_nesting_start.s @@ -0,0 +1,104 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +IRQ_DISABLE EQU 0x80 ; IRQ disable bit +MODE_MASK EQU 0x1F ; Mode mask +SYS_MODE_BITS EQU 0x1F ; System mode bits +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_irq_nesting_start ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from IRQ mode after */ +;/* _tx_thread_context_save has been called and switches the IRQ */ +;/* processing to the system mode so nested IRQ interrupt processing */ +;/* is possible (system mode has its own "lr" register). Note that */ +;/* this function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s). */ +;/* */ +;/* This function returns with IRQ interrupts enabled. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_irq_nesting_start(VOID) +;{ + EXPORT _tx_thread_irq_nesting_start +_tx_thread_irq_nesting_start + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + BIC r0, r0, #MODE_MASK ; Clear the mode bits + ORR r0, r0, #SYS_MODE_BITS ; Build system mode CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + STMDB sp!, {r1, lr} ; Push the system mode lr on the system mode stack + ; and push r1 just to keep 8-byte alignment + BIC r0, r0, #IRQ_DISABLE ; Build enable IRQ CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + IF {INTER} = {TRUE} + BX r3 ; Return to caller + ELSE + MOV pc, r3 ; Return to caller + ENDIF +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_schedule.s b/ports/arm11/ac5/src/tx_thread_schedule.s new file mode 100644 index 000000000..0347394e9 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_schedule.s @@ -0,0 +1,172 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +ENABLE_INTS EQU 0xC0 ; IRQ & FIQ Interrupts enabled mask + ELSE +ENABLE_INTS EQU 0x80 ; IRQ Interrupts enabled mask + ENDIF +; +; + IMPORT _tx_thread_execute_ptr + IMPORT _tx_thread_current_ptr + IMPORT _tx_timer_time_slice + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_thread_enter + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_schedule ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function waits for a thread control block pointer to appear in */ +;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */ +;/* in the variable, the corresponding thread is resumed. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* _tx_initialize_kernel_enter ThreadX entry function */ +;/* _tx_thread_system_return Return to system from thread */ +;/* _tx_thread_context_restore Restore thread's context */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_schedule(VOID) +;{ + EXPORT _tx_thread_schedule +_tx_thread_schedule +; +; /* Enable interrupts. */ +; + MRS r2, CPSR ; Pickup CPSR + BIC r0, r2, #ENABLE_INTS ; Clear the disable bit(s) + MSR CPSR_cxsf, r0 ; Enable interrupts +; +; /* Wait for a thread to execute. */ +; do +; { + LDR r1, =_tx_thread_execute_ptr ; Address of thread execute ptr +; +__tx_thread_schedule_loop +; + LDR r0, [r1, #0] ; Pickup next thread to execute + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_schedule_loop ; If so, keep looking for a thread +; +; } +; while(_tx_thread_execute_ptr == TX_NULL); +; +; /* Yes! We have a thread to execute. Lockout interrupts and +; transfer control to it. */ +; + MSR CPSR_cxsf, r2 ; Disable interrupts +; +; /* Setup the current thread pointer. */ +; _tx_thread_current_ptr = _tx_thread_execute_ptr; +; + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread + STR r0, [r1, #0] ; Setup current thread pointer +; +; /* Increment the run count for this thread. */ +; _tx_thread_current_ptr -> tx_thread_run_count++; +; + LDR r2, [r0, #4] ; Pickup run counter + LDR r3, [r0, #24] ; Pickup time-slice for this thread + ADD r2, r2, #1 ; Increment thread run-counter + STR r2, [r0, #4] ; Store the new run counter +; +; /* Setup time-slice, if present. */ +; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; +; + LDR r2, =_tx_timer_time_slice ; Pickup address of time slice + ; variable + LDR sp, [r0, #8] ; Switch stack pointers + STR r3, [r2, #0] ; Setup time-slice +; +; /* Switch to the thread's stack. */ +; sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr; +; + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the thread entry function to indicate the thread is executing. */ +; + BL _tx_execution_thread_enter ; Call the thread execution enter function + ENDIF +; +; /* Determine if an interrupt frame or a synchronous task suspension frame +; is present. */ +; + LDMIA sp!, {r0, r1} ; Pickup the stack type and saved CPSR + CMP r0, #0 ; Check for synchronous context switch + MSRNE SPSR_cxsf, r1 ; Setup SPSR for return + LDMNEIA sp!, {r0-r12, lr, pc}^ ; Return to point of thread interrupt + LDMIA sp!, {r4-r11, lr} ; Return to thread synchronously + MSR CPSR_cxsf, r1 ; Recover CPSR + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_thread_stack_build.s b/ports/arm11/ac5/src/tx_thread_stack_build.s new file mode 100644 index 000000000..d9b68fa98 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_stack_build.s @@ -0,0 +1,156 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +SVC_MODE EQU 0x13 ; SVC mode + IF :DEF:TX_ENABLE_FIQ_SUPPORT +CPSR_MASK EQU 0xDF ; Mask initial CPSR, IRQ & FIQ ints enabled + ELSE +CPSR_MASK EQU 0x9F ; Mask initial CPSR, IRQ ints enabled + ENDIF +; +; + AREA ||.text||, CODE, READONLY +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_stack_build ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function builds a stack frame on the supplied thread's stack. */ +;/* The stack frame results in a fake interrupt return to the supplied */ +;/* function pointer. */ +;/* */ +;/* INPUT */ +;/* */ +;/* thread_ptr Pointer to thread control blk */ +;/* function_ptr Pointer to return function */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* _tx_thread_create Create thread service */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +;{ + EXPORT _tx_thread_stack_build +_tx_thread_stack_build +; +; +; /* Build a fake interrupt frame. The form of the fake interrupt stack +; on the ARM11 should look like the following after it is built: +; +; Stack Top: 1 Interrupt stack frame type +; CPSR Initial value for CPSR +; a1 (r0) Initial value for a1 +; a2 (r1) Initial value for a2 +; a3 (r2) Initial value for a3 +; a4 (r3) Initial value for a4 +; v1 (r4) Initial value for v1 +; v2 (r5) Initial value for v2 +; v3 (r6) Initial value for v3 +; v4 (r7) Initial value for v4 +; v5 (r8) Initial value for v5 +; sb (r9) Initial value for sb +; sl (r10) Initial value for sl +; fp (r11) Initial value for fp +; ip (r12) Initial value for ip +; lr (r14) Initial value for lr +; pc (r15) Initial value for pc +; 0 For stack backtracing +; +; Stack Bottom: (higher memory address) */ +; + LDR r2, [r0, #16] ; Pickup end of stack area + BIC r2, r2, #7 ; Ensure 8-byte alignment + SUB r2, r2, #76 ; Allocate space for the stack frame +; +; /* Actually build the stack frame. */ +; + MOV r3, #1 ; Build interrupt stack type + STR r3, [r2, #0] ; Store stack type + MOV r3, #0 ; Build initial register value + STR r3, [r2, #8] ; Store initial r0 + STR r3, [r2, #12] ; Store initial r1 + STR r3, [r2, #16] ; Store initial r2 + STR r3, [r2, #20] ; Store initial r3 + STR r3, [r2, #24] ; Store initial r4 + STR r3, [r2, #28] ; Store initial r5 + STR r3, [r2, #32] ; Store initial r6 + STR r3, [r2, #36] ; Store initial r7 + STR r3, [r2, #40] ; Store initial r8 + STR r3, [r2, #44] ; Store initial r9 + LDR r3, [r0, #12] ; Pickup stack starting address + STR r3, [r2, #48] ; Store initial r10 (sl) + MOV r3, #0 ; Build initial register value + STR r3, [r2, #52] ; Store initial r11 + STR r3, [r2, #56] ; Store initial r12 + STR r3, [r2, #60] ; Store initial lr + STR r1, [r2, #64] ; Store initial pc + STR r3, [r2, #68] ; 0 for back-trace + MRS r1, CPSR ; Pickup CPSR + BIC r1, r1, #CPSR_MASK ; Mask mode bits of CPSR + ORR r3, r1, #SVC_MODE ; Build CPSR, SVC mode, interrupts enabled + STR r3, [r2, #4] ; Store initial CPSR +; +; /* Setup stack pointer. */ +; thread_ptr -> tx_thread_stack_ptr = r2; +; + STR r2, [r0, #8] ; Save stack pointer in thread's + ; control block + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +;} + END + diff --git a/ports/arm11/ac5/src/tx_thread_system_return.s b/ports/arm11/ac5/src/tx_thread_system_return.s new file mode 100644 index 000000000..9bfd95d94 --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_system_return.s @@ -0,0 +1,150 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled + ELSE +DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled + ENDIF +; +; + IMPORT _tx_thread_current_ptr + IMPORT _tx_timer_time_slice + IMPORT _tx_thread_schedule + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_thread_exit + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_system_return ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is target processor specific. It is used to transfer */ +;/* control from a thread back to the ThreadX system. Only a */ +;/* minimal context is saved since the compiler assumes temp registers */ +;/* are going to get slicked by a function call anyway. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling loop */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ThreadX components */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_system_return(VOID) +;{ + EXPORT _tx_thread_system_return +_tx_thread_system_return +; +; /* Save minimal context on the stack. */ +; + MOV r0, #0 ; Build a solicited stack type + MRS r1, CPSR ; Pickup the CPSR + STMDB sp!, {r0-r1, r4-r11, lr} ; Save minimal context +; +; /* Lockout interrupts. */ +; + ORR r2, r1, #DISABLE_INTS ; Build disable interrupt CPSR + MSR CPSR_cxsf, r2 ; Disable interrupts + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the thread exit function to indicate the thread is no longer executing. */ +; + BL _tx_execution_thread_exit ; Call the thread exit function + ENDIF + + LDR r3, =_tx_thread_current_ptr ; Pickup address of current ptr + LDR r0, [r3, #0] ; Pickup current thread pointer + LDR r2, =_tx_timer_time_slice ; Pickup address of time slice + LDR r1, [r2, #0] ; Pickup current time slice +; +; /* Save current stack and switch to system stack. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +; sp = _tx_thread_system_stack_ptr; +; + STR sp, [r0, #8] ; Save thread stack pointer +; +; /* Determine if the time-slice is active. */ +; if (_tx_timer_time_slice) +; { +; + MOV r4, #0 ; Build clear value + CMP r1, #0 ; Is a time-slice active? + BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice +; +; /* Save time-slice for the thread and clear the current time-slice. */ +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + STR r4, [r2, #0] ; Clear time-slice + STR r1, [r0, #24] ; Save current time-slice +; +; } +__tx_thread_dont_save_ts +; +; /* Clear the current thread pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + STR r4, [r3, #0] ; Clear current thread pointer + B _tx_thread_schedule ; Jump to scheduler! +; +;} + END + diff --git a/ports/arm11/ac5/src/tx_thread_vectored_context_save.s b/ports/arm11/ac5/src/tx_thread_vectored_context_save.s new file mode 100644 index 000000000..f318ff3dd --- /dev/null +++ b/ports/arm11/ac5/src/tx_thread_vectored_context_save.s @@ -0,0 +1,209 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 ; IRQ & FIQ interrupts disabled + ELSE +DISABLE_INTS EQU 0x80 ; IRQ interrupts disabled + ENDIF +; +; + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_enter + ENDIF +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_vectored_context_save ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function saves the context of an executing thread in the */ +;/* beginning of interrupt processing. The function also ensures that */ +;/* the system stack is used upon return to the calling ISR. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_vectored_context_save(VOID) +;{ + EXPORT _tx_thread_vectored_context_save +_tx_thread_vectored_context_save +; +; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +; out, we are in IRQ mode, and all registers are intact. */ +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; + IF :DEF:TX_ENABLE_FIQ_SUPPORT + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt CPSR + MSR CPSR_cxsf, r0 ; Disable interrupts + ENDIF + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3, #0] ; Pickup system state + CMP r2, #0 ; Is this the first interrupt? + BEQ __tx_thread_not_nested_save ; Yes, not a nested context save +; +; /* Nested interrupt condition. */ +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3, #0] ; Store it back in the variable +; +; /* Note: Minimal context of interrupted thread is already saved. */ +; +; /* Return to the ISR. */ +; + MOV r10, #0 ; Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr + ENDIF + + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +__tx_thread_not_nested_save +; } +; +; /* Otherwise, not nested, check to see if a thread was running. */ +; else if (_tx_thread_current_ptr) +; { +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3, #0] ; Store it back in the variable + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in + ; scheduling loop - nothing needs saving! +; +; /* Note: Minimal context of interrupted thread is already saved. */ +; +; /* Save the current stack pointer in the thread's control block. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +; +; /* Switch to the system stack. */ +; sp = _tx_thread_system_stack_ptr; +; + MOV r10, #0 ; Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr + ENDIF + + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +; } +; else +; { +; +__tx_thread_idle_system_save +; +; /* Interrupt occurred in the scheduling loop. */ +; +; /* Not much to do here, just adjust the stack pointer, and return to IRQ +; processing. */ +; + MOV r10, #0 ; Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr + ENDIF + + ADD sp, sp, #32 ; Recover saved registers + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +; } +;} +; + END + diff --git a/ports/arm11/ac5/src/tx_timer_interrupt.s b/ports/arm11/ac5/src/tx_timer_interrupt.s new file mode 100644 index 000000000..158f69300 --- /dev/null +++ b/ports/arm11/ac5/src/tx_timer_interrupt.s @@ -0,0 +1,258 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) Microsoft Corporation. All rights reserved. */ +;/* */ +;/* This software is licensed under the Microsoft Software License */ +;/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +;/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +;/* and in the root directory of this software. */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Timer */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_timer.h" +;#include "tx_thread.h" +; +; +;Define Assembly language external references... +; + IMPORT _tx_timer_time_slice + IMPORT _tx_timer_system_clock + IMPORT _tx_timer_current_ptr + IMPORT _tx_timer_list_start + IMPORT _tx_timer_list_end + IMPORT _tx_timer_expired_time_slice + IMPORT _tx_timer_expired + IMPORT _tx_thread_time_slice + IMPORT _tx_timer_expiration_process +; +; + AREA ||.text||, CODE, READONLY + PRESERVE8 +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_timer_interrupt ARM11/AC5 */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Microsoft Corporation */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function processes the hardware timer interrupt. This */ +;/* processing includes incrementing the system clock and checking for */ +;/* time slice and/or timer expiration. If either is found, the */ +;/* interrupt context save/restore functions are called along with the */ +;/* expiration functions. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_timer_expiration_process Timer expiration processing */ +;/* _tx_thread_time_slice Time slice interrupted thread */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* interrupt vector */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_timer_interrupt(VOID) +;{ + EXPORT _tx_timer_interrupt +_tx_timer_interrupt +; +; /* Upon entry to this routine, it is assumed that context save has already +; been called, and therefore the compiler scratch registers are available +; for use. */ +; +; /* Increment the system clock. */ +; _tx_timer_system_clock++; +; + LDR r1, =_tx_timer_system_clock ; Pickup address of system clock + LDR r0, [r1, #0] ; Pickup system clock + ADD r0, r0, #1 ; Increment system clock + STR r0, [r1, #0] ; Store new system clock +; +; /* Test for time-slice expiration. */ +; if (_tx_timer_time_slice) +; { +; + LDR r3, =_tx_timer_time_slice ; Pickup address of time-slice + LDR r2, [r3, #0] ; Pickup time-slice + CMP r2, #0 ; Is it non-active? + BEQ __tx_timer_no_time_slice ; Yes, skip time-slice processing +; +; /* Decrement the time_slice. */ +; _tx_timer_time_slice--; +; + SUB r2, r2, #1 ; Decrement the time-slice + STR r2, [r3, #0] ; Store new time-slice value +; +; /* Check for expiration. */ +; if (__tx_timer_time_slice == 0) +; + CMP r2, #0 ; Has it expired? + BNE __tx_timer_no_time_slice ; No, skip expiration processing +; +; /* Set the time-slice expired flag. */ +; _tx_timer_expired_time_slice = TX_TRUE; +; + LDR r3, =_tx_timer_expired_time_slice ; Pickup address of expired flag + MOV r0, #1 ; Build expired value + STR r0, [r3, #0] ; Set time-slice expiration flag +; +; } +; +__tx_timer_no_time_slice +; +; /* Test for timer expiration. */ +; if (*_tx_timer_current_ptr) +; { +; + LDR r1, =_tx_timer_current_ptr ; Pickup current timer pointer addr + LDR r0, [r1, #0] ; Pickup current timer + LDR r2, [r0, #0] ; Pickup timer list entry + CMP r2, #0 ; Is there anything in the list? + BEQ __tx_timer_no_timer ; No, just increment the timer +; +; /* Set expiration flag. */ +; _tx_timer_expired = TX_TRUE; +; + LDR r3, =_tx_timer_expired ; Pickup expiration flag address + MOV r2, #1 ; Build expired value + STR r2, [r3, #0] ; Set expired flag + B __tx_timer_done ; Finished timer processing +; +; } +; else +; { +__tx_timer_no_timer +; +; /* No timer expired, increment the timer pointer. */ +; _tx_timer_current_ptr++; +; + ADD r0, r0, #4 ; Move to next timer +; +; /* Check for wrap-around. */ +; if (_tx_timer_current_ptr == _tx_timer_list_end) +; + LDR r3, =_tx_timer_list_end ; Pickup addr of timer list end + LDR r2, [r3, #0] ; Pickup list end + CMP r0, r2 ; Are we at list end? + BNE __tx_timer_skip_wrap ; No, skip wrap-around logic +; +; /* Wrap to beginning of list. */ +; _tx_timer_current_ptr = _tx_timer_list_start; +; + LDR r3, =_tx_timer_list_start ; Pickup addr of timer list start + LDR r0, [r3, #0] ; Set current pointer to list start +; +__tx_timer_skip_wrap +; + STR r0, [r1, #0] ; Store new current timer pointer +; } +; +__tx_timer_done +; +; +; /* See if anything has expired. */ +; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) +; { +; + LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of expired flag + LDR r2, [r3, #0] ; Pickup time-slice expired flag + CMP r2, #0 ; Did a time-slice expire? + BNE __tx_something_expired ; If non-zero, time-slice expired + LDR r1, =_tx_timer_expired ; Pickup addr of other expired flag + LDR r0, [r1, #0] ; Pickup timer expired flag + CMP r0, #0 ; Did a timer expire? + BEQ __tx_timer_nothing_expired ; No, nothing expired +; +__tx_something_expired +; +; + STMDB sp!, {r0, lr} ; Save the lr register on the stack + ; and save r0 just to keep 8-byte alignment +; +; /* Did a timer expire? */ +; if (_tx_timer_expired) +; { +; + LDR r1, =_tx_timer_expired ; Pickup addr of expired flag + LDR r0, [r1, #0] ; Pickup timer expired flag + CMP r0, #0 ; Check for timer expiration + BEQ __tx_timer_dont_activate ; If not set, skip timer activation +; +; /* Process timer expiration. */ +; _tx_timer_expiration_process(); +; + BL _tx_timer_expiration_process ; Call the timer expiration handling routine +; +; } +__tx_timer_dont_activate +; +; /* Did time slice expire? */ +; if (_tx_timer_expired_time_slice) +; { +; + LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of time-slice expired + LDR r2, [r3, #0] ; Pickup the actual flag + CMP r2, #0 ; See if the flag is set + BEQ __tx_timer_not_ts_expiration ; No, skip time-slice processing +; +; /* Time slice interrupted thread. */ +; _tx_thread_time_slice(); + + BL _tx_thread_time_slice ; Call time-slice processing +; +; } +; +__tx_timer_not_ts_expiration +; + LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for + ; the 8-byte stack alignment +; +; } +; +__tx_timer_nothing_expired +; + IF {INTER} = {TRUE} + BX lr ; Return to caller + ELSE + MOV pc, lr ; Return to caller + ENDIF +; +;} + END + diff --git a/ports/arm11/gnu/example_build/build_threadx.bat b/ports/arm11/gnu/example_build/build_threadx.bat new file mode 100644 index 000000000..812a730ec --- /dev/null +++ b/ports/arm11/gnu/example_build/build_threadx.bat @@ -0,0 +1,238 @@ +del tx.a +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s tx_initialize_low_level.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_stack_build.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_schedule.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_system_return.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_context_save.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_context_restore.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_interrupt_control.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_timer_interrupt.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_interrupt_disable.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_interrupt_restore.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_context_save.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_nesting_start.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_irq_nesting_start.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_irq_nesting_end.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_nesting_end.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_fiq_context_restore.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s ../src/tx_thread_vectored_context_save.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_allocate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_cleanup.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_initialize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_system_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_block_release.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_allocate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_cleanup.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_initialize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_search.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_release.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_cleanup.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_initialize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_system_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_high_level.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_enter.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_setup.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_cleanup.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_initialize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_system_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_priority_change.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_put.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_cleanup.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_flush.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_front_send.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_initialize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_system_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_receive.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_ceiling_put.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_cleanup.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_initialize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_system_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_entry_exit_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_identify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_initialize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_system_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_preemption_change.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_priority_change.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_relinquish.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_reset.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_resume.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_shell_entry.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_sleep.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_analyze.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_handler.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_error_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_suspend.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_preempt_check.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_resume.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_suspend.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_terminate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice_change.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_timeout.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_wait_abort.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_time_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_time_set.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_activate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_change.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_deactivate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_expiration_process.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_initialize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_system_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_activate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_deactivate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_thread_entry.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_enable.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_disable.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_initialize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_interrupt_control.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_enter_insert.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_exit_insert.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_register.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_unregister.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_user_event_insert.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_buffer_full_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_filter.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_unfilter.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_allocate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_block_release.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_allocate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_release.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_put.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_flush.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_front_send.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_receive.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_ceiling_put.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_prioritize.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_entry_exit_notify.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_info_get.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_preemption_change.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_priority_change.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_relinquish.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_reset.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_resume.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_suspend.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_terminate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_time_slice_change.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_wait_abort.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_activate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_change.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_create.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_deactivate.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_delete.c +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_info_get.c +arm-none-eabi-ar -r tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o +arm-none-eabi-ar -r tx.a tx_thread_interrupt_disable.o tx_thread_interrupt_restore.o tx_thread_fiq_context_save.o tx_thread_fiq_nesting_start.o tx_thread_irq_nesting_start.o tx_thread_irq_nesting_end.o +arm-none-eabi-ar -r tx.a tx_thread_fiq_nesting_end.o tx_thread_fiq_context_restore.o tx_thread_vectored_context_save.o tx_initialize_low_level.o +arm-none-eabi-ar -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o +arm-none-eabi-ar -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o +arm-none-eabi-ar -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o +arm-none-eabi-ar -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o +arm-none-eabi-ar -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o +arm-none-eabi-ar -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o +arm-none-eabi-ar -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o +arm-none-eabi-ar -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o +arm-none-eabi-ar -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o +arm-none-eabi-ar -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o +arm-none-eabi-ar -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o +arm-none-eabi-ar -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o +arm-none-eabi-ar -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o +arm-none-eabi-ar -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o +arm-none-eabi-ar -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o +arm-none-eabi-ar -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o +arm-none-eabi-ar -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o +arm-none-eabi-ar -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o +arm-none-eabi-ar -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o +arm-none-eabi-ar -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o +arm-none-eabi-ar -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o +arm-none-eabi-ar -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o +arm-none-eabi-ar -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o +arm-none-eabi-ar -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o +arm-none-eabi-ar -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o +arm-none-eabi-ar -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o +arm-none-eabi-ar -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o +arm-none-eabi-ar -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o +arm-none-eabi-ar -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o +arm-none-eabi-ar -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o +arm-none-eabi-ar -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o +arm-none-eabi-ar -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o +arm-none-eabi-ar -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o diff --git a/ports/arm11/gnu/example_build/build_threadx_sample.bat b/ports/arm11/gnu/example_build/build_threadx_sample.bat new file mode 100644 index 000000000..e67e3c20b --- /dev/null +++ b/ports/arm11/gnu/example_build/build_threadx_sample.bat @@ -0,0 +1,6 @@ +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s reset.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s crt0.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s tx_initialize_low_level.S +arm-none-eabi-gcc -c -g -mcpu=arm1136j-s -I../../../../common/inc -I../inc sample_threadx.c +arm-none-eabi-ld -A arm1136j-s -T sample_threadx.ld reset.o crt0.o tx_initialize_low_level.o sample_threadx.o tx.a libc.a libnosys.a libgcc.a -o sample_threadx.out -M > sample_threadx.map + diff --git a/ports/arm11/gnu/example_build/crt0.S b/ports/arm11/gnu/example_build/crt0.S new file mode 100644 index 000000000..aa0f32396 --- /dev/null +++ b/ports/arm11/gnu/example_build/crt0.S @@ -0,0 +1,90 @@ + +/* .text is used instead of .section .text so it works with arm-aout too. */ + .text + .code 32 + .align 0 + + .global _mainCRTStartup + .global _start + .global start +start: +_start: +_mainCRTStartup: + +/* Start by setting up a stack */ + /* Set up the stack pointer to a fixed value */ + ldr r3, .LC0 + mov sp, r3 + /* Setup a default stack-limit in case the code has been + compiled with "-mapcs-stack-check". Hard-wiring this value + is not ideal, since there is currently no support for + checking that the heap and stack have not collided, or that + this default 64k is enough for the program being executed. + However, it ensures that this simple crt0 world will not + immediately cause an overflow event: */ + sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */ + mov a2, #0 /* Second arg: fill value */ + mov fp, a2 /* Null frame pointer */ + mov r7, a2 /* Null frame pointer for Thumb */ + + ldr a1, .LC1 /* First arg: start of memory block */ + ldr a3, .LC2 + sub a3, a3, a1 /* Third arg: length of block */ + + + + bl memset + mov r0, #0 /* no arguments */ + mov r1, #0 /* no argv either */ +#ifdef __USES_INITFINI__ + /* Some arm/elf targets use the .init and .fini sections + to create constructors and destructors, and for these + targets we need to call the _init function and arrange + for _fini to be called at program exit. */ + mov r4, r0 + mov r5, r1 +/* ldr r0, .Lfini */ + bl atexit +/* bl init */ + mov r0, r4 + mov r1, r5 +#endif + bl main + + bl exit /* Should not return. */ + + + /* For Thumb, constants must be after the code since only + positive offsets are supported for PC relative addresses. */ + + .align 0 +.LC0: +.LC1: + .word __bss_start__ +.LC2: + .word __bss_end__ +/* +#ifdef __USES_INITFINI__ +.Lfini: + .word _fini +#endif */ + /* Return ... */ +#ifdef __APCS_26__ + movs pc, lr +#else +#ifdef __THUMB_INTERWORK + bx lr +#else + mov pc, lr +#endif +#endif + + +/* Workspace for Angel calls. */ + .data +/* Data returned by monitor SWI. */ +.global __stack_base__ +HeapBase: .word 0 +HeapLimit: .word 0 +__stack_base__: .word 0 +StackLimit: .word 0 diff --git a/ports/arm11/gnu/example_build/libc.a b/ports/arm11/gnu/example_build/libc.a new file mode 100644 index 0000000000000000000000000000000000000000..b03b1626469d3977b9515263f1a5da2221d7d407 GIT binary patch literal 1207876 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½S9!kk(}Y7v*I6VTXu|mJ zF7{3;k3G-3A9%YYX+p8{0^^|xl2&NK6-M8%pK&-qW_V*wFF|?Tzzahc%E|`3Z@j&O zX2h@`H*FZiOT}ozjV?S`%AAijv?A7|HTwWhaMz>_E0OL((+2bGD%*m_&o4ZRh+^jn zdwbS)bY0Wazol#5mTR#L7;6pCG{4E+LL8em?9*!a9&MTCxo|FWv_u7)NE!rk_ZHxqqRKG%rndpoLk1~C~H|qb9D1g zxoXtcJjX0}$98DPb5l*_AkQ!}ofy*Ei6#@^c+4A_g>(q@4-4aEHkA0n*brtEw5>91 z1M(!oqcD(TRb&v%X(lm94FmPP){YLkt&Wauv|w8BG`J0Tx#%ea0Z7|;SJ7PB@H@02 zdl=W=!Z8+iXXZuDpSl*t6_Qrr|?>D;^Wx zpc@BE8G+}&Kjke0o=K-z7Qz#=7Y_Eh7=gDO0cQE$!Amy6SU#3Z%13#FN%xZQm%i{I2yAC`4Cx*V-N{V8dClaP^JWlyGHWT3}|lHgH+sL!r9BhXeJ2k7%NaB%aaW zv^Q-1_N*5HN2s9J=r4S~*x4sbS9{&~khFE>t@FD2`?vP2-PYgTXO>|s_xrVOATF6> zkT~~Aqp;Ghw9QuQgr5)bLvW{+!MkyyhFsY9?lg@$2t%< z&o|#vzh#L#-NoAK74yF)}x%@7@QxB(qoF+;E4qGKhM)zPylwry*7N34IV zrpXPM=-C&vS?(Z&8}tXU=q#AO;ddDR-skUp!SZvs8&8>*_SeM z*pKEMIS07NQ6cl0%#pIz5P0oK!*|69yjBF5@EpM7xF9^CPlV4qe}%TdY2Aw_N{4F% z-YWP_cu~N!5k`1~BjsBUw@E*bz+cK7{sz*qAl0z=5FX3RJOR%$1QX( z*Iy)^rk}mnHJ7?}Sty@)9GiYVsSE1S&kq9Ymw`rxQ`dk_KAejtAJ4s#+L5Vo66s$> zc4TdtAOm!)s!smuwLtPXu9;n#o;^#!LbI;OGM@0Q$nl(pk6Ha% zr)mCz=7rZ?-?FH6$@Uqx%L$+SFOJ7^S9q|=NG!xu3O)|;qHw+ zfBvQ3O`EsGzPz=sf7?A@+5Xk9u~h80^U?S_5Z6`{#)`_6k!pT+nHxUQXgtSt-h|ay zC%$RJ5t=u})>_1kTlzZFkFVO2ghq%gtsPxtNwW!rL&xI7=N zaOdN$pJi5SH8t#ILRfiSb4TmSm92ML3@(@fIv9e90*3Dffn2L;qrj|>CvV22RxlU9 z?=YSXH=cWFy|tVwNq!cPa?IPhWqntF*Svg@%eK6mNb>^wQH+ePxd<@n?pvU15rh%f zn1&CVn{sF3mW;A}aI^2k2t3kG6J8iJi|-SjIWOD_Kj9%eWnRTE$E6s7w+;bJC&q>+ zDjwL9t^;l}-)iJ*BaHbnT)t|<`3%6I(WdYsP-W|wi96ko@bJ%P?P7& zm)$>q%*9LbBI(@uqibznX|k`D>*U1D*z?EtQGOV2{-8b!=LpN{92x7*YqsM=r=P5x zm}2|eLJwIN(le`<&8+AZU7G*I#3nRnTr@_Bh7_2Ko_5Sd`*5fTu9K%^n~CArry;KE zA*H+uFKz8qzmo2H_)Of4;w9n^=>o)b9&Rp!y8t)gF9|o1E`f)62(A~yP2w-Z#Yoxx zxY>>flU7PP7dO}S_V;Y+E@f@($Z^-Pansg>(8EpcV^^y6@58x!!OKym%yP3IOdiPW zms-S4G#nM2W7*l$T&L#yKt_m)MBmGZ6Mz1WOxBG!%lT9c;an{q*a~j1+daaD^ln+# zr8>;=TwJ1>>ru8L<;Q$K2oLijkMW-9K%Up|GAj1|YaEV5t8&BBq# za#njHU5Rxc-qG_E1ydT zt@d=tc`5ammi2>I8uR{ulXx0y%kSCFU=DjiKWL8}%%N@199sK$?$DKw=bo64vV81g zsSRsc-p{i<4_lpyfnS0yPIc=;UM9_Tr<2MO4!YqC?Kyz85ipKoPw&Ctu~g@=$8!OD zXX@C(b*a#m>r%lh*QP?LL^?RXHTCe^7gNWtKpx3`sTYrRr7Y_}u6kx~s?t7?3p6cF zg(C-YAt#!uv6rN(Bdw_$P`^qWc_E*0WH5J&W&JV$dcD|LnxUWJH*ihNaIB#h<9mry ztifM@2z!fHAgsruVDgi8iNm4U{)wMK3pc#8PGgoub&Bj!krBSa;6p7&D$B?fsJP3a(RZ1t)9wD0k6<;cXxmP*LpT@*kawi ziM*eZarb|%1F61bb@YF&ue-lv+h+Q@AqYnRSdMiay*-YANPa90ro3tS#ufr&7K%oa+yB}>x`N?+L zAe?39T~O2VaW4~zcj4F*BO}(&yPU4je2JfTxd|@ITo4|P zH-^Efcn$JGlzjt443;)1P$|5NgLGWekZ<9`dI)@@dR8auF{mM{Un#qvcUg==tt*mF z);(J`-(BLKVCgdLlNiS^9`Eu2P|IQGrS$L(N$dr_lpcXS3VRgxGq9h5eHiv(*w4a# z7WNU?M_^Niu^4NnVf$p7Jjw7UkEciA9)UdydldFFu%Cf_81`Y<&%%Bd_7T`eU=s!l z0bu_M5EClC5GY1$Q#N=3gau(x~$Dhf&pU~p7k*eWyKsjG;9mf@CN16 z_%ajl8(lvwj!Dp1J$z(c*5L+#!nm%2MH$Ny1l?2g41-(NVuZ^*!a1~AtntW!m5j#7 zSdlg@xY4C6AF+GCXdP)7@tgF8hI1$TNKDvuw8A#ik@#>Ni;;AGT^)YogEWiuhNFb( z=qC*$JTZsiaKr;!;C&8mlO{$1&qf&Gu{#A`C)_4Yd>#H$Xkr}-@g~x8d=p0rkK>Pd znl!Nz`I_aEvioUbC(_06t{6!tG*NxB8d{2D>Pak+Bh6#Wf{q|h7>_1$pU-m76t=Ef z`sq)@C*@#5*3;xKP1?l1nP{|$eVsQlGIR)OQz3upr$tkI@l!N?!Ru_cfH(35-c(=u zb7`4QDe0$M_^hciY&+7nPa6Ii9HqU5Un<|c4P0F}m^=4lvs=2>lQrz>Mc7g=Q27-k z(k<4Sx`~Rup?ihCy$5>c<&e)-HnjTsw>Hgdw&tnbEw`A8=(!tS{^DKyyk0T-$9@ze zqwOXH5QpZw5u}kqGa1BmjK9sbg?6;TuhA0@7=gC|Zl;&GWpEeEcP+wA`bS+w(kJ4q zN&j}jPk3V5;jqO6Tk`!2xJ`J~D1g9YIMcBlkhc`jQ_{3j=xGA!Y!rkzNw|bZo3N!# z;IxuRa|0c&k+S>gDRmzomqf57ol8&G_uNz3zE{)lC|l=usrXGQ%D?!%@e0U9f}Qe> zs@t-lI?qycf{PdT&EM_?z6ZxA}<`~V7 zDqZ?wYj=}xyX4~4anMvRo*PdoU1tTmDdwxkoWAkF~kO4M$u_kbh)Q4J}dOR15#50sT)4BC+de}Z17)~BVbylRWg8yG2H&uF3aSBiY!%k$wgyDQS9h^2R%Xc6vp2f65!b}ci zcg_JEClBXJ`2QV7*TL-jP+FUyKznlI=j?3sB7PaJdUSA)@|u`0Gn}aPgQTgeh2k-P!Hy@ znEN}J!vZL;*=8R>-XpV5rB5O))BO?h=lu2ow6DnI8_16!#D`Tu zjF*qt`!SC8XD~L@I022XAF+N4cRR+qRbP#?)bCr2{&rA4&WqCSr_Y|P3RtNu;?J%u;aV4vfI zz=^|w6Y2kU_UsEEY_EWh<84`{ud@d;L2FRq`f%i@=|J-U`fv%_1A33m303yW_8T+c z7CF|dq&))dw`J7$K)txv@xuMREF1Q>DzM)}cpvOM4tN`g@89FT+*G8Sx;=69W;~#^FIezH zZ?Ecb)2TGeg|lp#sj&goUxCigXTZPI2dvw(fmq_Isg;SejfZ8O3fRBJz7We+=bXyb zqnsg>4Y1Q!TLDQ>}7bjF1ZVRhxbw5Y8y1v=s(gV=|8?(33z-D^tp;jMbq z_-0<{-xrux;xW!ue=9s)J}U#hrYh{x^m@>AmYed-s~UHr>_<}}w3C_#K)=~eqt4IL zQ=_RYafSI|Ppv8tZBzL@X!U1bgP&<6o_HsG=$kiR^Xta=W4RF8G0@4eqxo5uwU_&{ z?Kh@|fU{`(;~4udlco>{h{rM2&bMX106ej6>A?#Tm%8{m%Zqz$_GtH5` ziZ-$BsXt7*)B+fPhxnDik0{)S;Qlh~QNXPNy?k>fXwRYq_D1*Ss`1oD_T~;ZJ)hob z?@c}1bPVO#i#%`3g63ntGx0LZ2{)Q|MYazxDp7{f^egFsWFmdUK9K%P#MfBC6vo2~ z)6rI-uP+QZgQ>b9;AJY2B|Z7xH|UIpb@ zf-=87Tj@t>VY`?9_ z4x$bWV>yW%BaSW~$B2Z#boT5ogCEA&MEoD2eMTauLHACBj;vH;faMihC+z@ufuk-? z1TdFzEFMNVP5J{m<<3Kgazl~!4Elf8PNX5NnvFVFqwf#TM&E-TKJ6U9+%_wH5as<2 z(o98rJR0HLuiJy|BV&u>Yy;BZd~P=IA|4z2+!%M&czW?pHQ*gS`h1${*B~9=T}@bv z&u!b)syw%6zk<4OPZ_i$%ROPqce*d%Wk~Zsfk2p>qGzXCVa(Za{9A8+?wVgWV4ha^ z2|OJc0-qDt^W{kN=l?%@?*k`Qb>5BN`Lpb>tjhpPy4kGBMb}6aarmRIieZ3NS4ABV z6B0>S{;Wb=U;=A`DNPo3ffZT1Ds8AQgh|Ad_O*F8gj&jvq@!YES~aASgj%t8W|&H- zO-X9|qi?9Z-|xBSxpU?+u!GW{#NT^9pL3sk&Ux;0&)?@f=Q;l}=npc3EZ1F`yv3Q= zw>CQ%@w@}P&%!^fcr#>;Lc0rFpU!*&^(qj%Ia{CV$=1et^I^2nD$t4IJ=ouq4ae4H zBdHYXZ!g;3)_fG@ywj3CH<7srdCWB$>~rhV8?yD*I>jG%+DRoNhU}>h=FFXoQ0Iq$ zr?b!Kx6|ww>jRxB^oeeK_cs1i#XT77$?To@f-2Km{EPf6WX;Ne|JO4OVWfv?3`QZ} zC3^Fg?XE{@puG6|7*BVmx_)u;Vu2t#&c9fkaup{yOewrj-BanEM@VvyCG znVBeL+>rHo$XRQK2csK@*V=1_W2{o8(rC>?eR2DA%Gg2t+m+A%4efMh4&zs}-Mf@5 zI^5zK3CaTOQxd99?;Q7&%#+tRnJ!rVlQf9KbP$j70{I`;=0#(x)&2&`BUbw4*I3rp zKE!eL{!BZ{JmS2bLBE_q-QEyO~1cqI*0u{vl;w7fc`Ml8E|&4{@JkIs!R)VSekUl{VWrT9n5?T?o3VF5g!^?*)a$Uy8XSwGW$dLv(M-F0c$wix*FRD zS$&o&3;CbKo3x%myA7fq*4pbKbN?JX{4napr#;jiOhu-`rF`i@HWV>RWV!U@jo(B&E{$1$5oDszB zpYXD3pOSXSQYvrJ*OZmFZeFfKUj9tyr5it?XXbqh(Y9IU(~(A1_feW6*Y9AS)?S5vdW{o^uEF>q?u@ESVSJFt1fl`e=d!;`q1{C=rul;JA9ujL zbJWi>oe1ZcXFl9F0>2}=4eNahbsh42m9z_tXR9FN9<4?Gs5r%1v*ejOCmhN=2!E^< z0xvDJeUW`Q_QZOpd^2#Ex9+z$IT8KsGWaW=V8Lj<5PbNGf7zMAxb=l?`BmTzHEHmM z1k&E>@&?7bQ5K38>dr~L?;Q2B%-a*)^fVyeZ`E$gR~TuTqSEry%>G8K$%9-QjD{Sx zb-`geSr2ap9@gBUP8IWktKlxyo>uKg`+NBNZ;>~fdH06brV9075O@H`IOaEQ{{CGC zvb-91Hlo~_F4BtY_nqNGnP+CY?H+ol`sP?~c6NVpyZ<-%L)JTOyEp&2AAHh`D`XCg z=}MR14)9KvpZPuW=T&@T()cmbD|yMXlCZFSX1>V&hkb;fFPi_W1K%NSmd|MLo=M<6 zwP?f3kY~~K)_mOBns172%-#{*sM_~LYh&J&1LC^g?HPY4!+eWg7x`tVX#v&%_9AUt z^PlbP&0gKtm7SjK%6_S}H`@^J&F`9sJV(BVBAvj)xB+b|HFeus)Qb(#`nq4Ly4RA* zG{VlYd$TOJu&!^-aJQn2OgUn%s!y&Q!8N7iLml{LXAE*gdIoh(_|G)w^XcB~#Tf5Y zgNFy~AoMEf%)cXlSmrz9zd*Zp$Kot&HC~2nHyFHn_f;=vAcNL7#JA>&%YKM_D+0V= zbhW|_Kn`bmAwymq0KXv57>{+5pG16jTA*uX(Vw|=Yr#wFfEz{LGHxet=u*5ijItmv zWu8vPw@e4~qQ4Qm6!~lNQsVSaba|;+p2AO|EA{y4uHlC={m66H7xrK5KczpFKJ;{T zWd(SM%X876#D1!I?%k)fHSpRe0;%R~)s9r=GT2Fo-yqi2D9Qu*_;CmMV1E(ik#H#2 zRcpDfhJ01Yb?s+D!$VQM|r@^vsw`}KoLlKW%_RE=SJK#iPUAb!Tt=+MgGr`fR%xJW^ zi@wmG849?I{ZM*8bgla{LoZ*K4M!d5?RvA%;M+Y8^r-2VGe5w0jB5q*m|=Xk_xEP0 z1K5TCM`O?DhF+e^kv_j8Ev`e_6Mb3XljdId3mu`sF)(DH*C;OxLi*U=C0#k>$53ln zE`s_+9SYM`fp^Nte22VLuhu<5UgFp`it$55%x#k<-{??%*V??q_nFuslo9H@HO+a( zdO7nW{HIobYkoKUH1u|k`)OvEeaMslD6j2=E_9E@(w0tWi%pxyAo@d$!M^96BTS`V_X|-u$tPU(O_+ z?aj~1^g>3qs+#RSH9i|Lp1fu?bb-3xM>~ke*5(tatI}U5bh+&xr^dzE0CdG6))lKe ze`QeV26DBrR0wsk;_eXg`QwK&&g5;Ur6?5`@p9v zQHBYW;X?dp)-cEv(4|tYLs_Xd{DVsLeW<&^!O`5t$=gPvt%f?Gcc%=|iT|YV9zy*h zKi`t*&GvxS4=P{glnC@-KT%`C3Qddu{v6UD$9LrE*W!SO6W6eBy(`xovi@}9&}|t1 z>h=ZP&j7b3Xzlrd#`!$bcj8jw&&=%&S$iUPf=+)bGjeHfw%tabjCfF1mcD?vf&SZ2 zXJ+OwCj8Sh;>P~x2dUod!FX>L`kzcY{5p|#f4Zxq$Zw>Z=_!?#>SS+z<0I&wzf$+h zp3iT~_k3epzT-P+&q#MI^fa}74`nM6pDN2OTfQUjR9ZPM#Q^0swnxU7WuU^-44;Fx z!#>>F!|)!Yi#SXh{Z)JJf7q%1QGduG_B9-BO0^%OK5b_1_fm@y2n!j9&bc>g}{p&(B_lK&u<~$mZDr5I=ANS{@#3JAN4z^%ZXHuWzF{1 zo$Sr-i1%g#eaPR|RA!xp{00A^4Cc)xMpx^(#9?YKaW!Nl$Y7Y0Ob;6ZenFXuc}tmr zW$5ZrGM?N-IfCu2Dvf`G_TKAJcCl5Z={sFHm;OtEe&;2W-7Js3eE)8~WgIH;|9tRH-vI!WqhV^QvbI2Ft zu!kvV-bKfE&-yYbJ_5ATT~zo45s+Jw6BM!?|iF&*rK=3KiiUl(=zAoeS*-&K8IQ9sn}>z6v=t{rtK ze-M3FAoj50+ZJ?J)Mc;_L#J{yVE>y+2jq*Yu}BYfEtdVN@&is4bWM4lAHuYfH{lKh ze)~kgUXi~MesB+i{|54Q%YHszJMK_^Fyeg$(q&tBp>M@JO6=EpaRaxCymxRMZJ+;- z{VGo#8D(X*sX*+x!_-f*e};?<_pJO>#Dg;Y5Xf%e!`~cYrM??O7}h4$4~{h}9bT2% z7u1}!($N2cF6UY*P-Y>}w$jfd4J-14qs>kXapv3&>9gOrLHhvS2dBHRmkI3}<@P)1 zGn%7adFTv~PNm1pbs^7ctuD+<7=Zrg@}J8v&rNyymH#?<^dM+8U&A?yHTgdT4&yQo=~8@X zl*@;)yy+(JCDh3*`4@T9&)+$Dl)Q;;hHm!rif{O2oHW{Dv_A67 zDE_hkrfvECS8r4OW@8fLt$y%6^o83yA=jjk{$vVk`(Mu3eZ8umWuHr(m&hE~rF-%J zREBbc^e-a+{NV7R%p;Lh1~OCTw@IZ}3NRSU*_54sk|2Fg~Jg@7JjB2{rG%S;vDs zpaFSaDs7dJNm8I+i}@Yu)c=_I1pH?{awtRjtucxE0A3jQ@RY3Gw>AF==CLXFP$#+D z!noxlT=!8ddk!dr-3WQ>v#H#%6#r=*t-^nwN~AJRv;83+EEkc#_zvEz+APcJNz6^K zt~39Sp)OKpiZDLFld@#lDp|_#t3W!jcHk&wq+QT+$sEI`UEA_$)VCY&>>bWJ7>aif z-~G0`2KYBilLK<94*?ozW9Y4hy2)qg__*yx~x0H1%UB7mN|=qg7hZf%t7k zKAP@La7V)1@~@*@mm6YjTLR|tqD+500(%W<8q0AWYj?rkNp}sqy_r=)4f&O~(%b@$2 z+)k9;qt=5ttPR;izQq5ka_YnUD$=%lGW0^=tI)YsG4ASn#Q$yl^9{#s>wdisbviYM zPKSLj`DEPUIITB78u8)3j^kh9R<|#vJWDtK-K6;x_m{qk@+5!af7vHcmLi{e4*qP9 z2W&0Z7;W(5_?~hY>kN5W=kRSKVJoEW%-*>zKaOM;ir)7s&16?E^hDSE!!)!(pOpScco%}s73(bIjLX=5ciIObgXb_Vo9*iJFs{7Z`rX{_tuJTx;d{10 z%5x3Lt$Fqr%#V9dKo4d2W*y|)f26g%s@4-FG8f}NoTH=cVAgBs<*H6skNyy45bAfw zySITh^-k0`1<@dBj=2CY^mR=mz|c!AD+TyS91oaqz=cSgTHk5|o}6r1sHaa18w-8_ zS;6B6s{LjQ{2&T`@MG`;rU_|#+d{cS(awFmyIg+2cEq+{i8k^dphY+N(EoPID{l+! zxEkNG4YO@wTwVVTcnsw~tSj0>T0!hFr*4sBF_ilVj>ov}k>ja=wFc{ho(-^^x}b;a z$9R!End>Mp=Td(HdCoA>K{g%T8RPmgSu5zy_3ioBmovWx9^(*jy0Yl6kM74jH0OlJ zKo58U>UTBj#xdy9R67}k{!q{VpkzjbRb9}04s8_j(Fn+mp)vcxk1((6mh(F&Pn`z+nSSPIGD0Ih4Tb+oT6|+zL`1x;MygGNq8{1y_yBEWUzJ0K2;hMkw zyQ9B8F#M8R4qtKg#5?c$&MWs{GWp*(|HrHM&klTh{rA(Ke(k9>-~QI0k01Buf$*<$ z<6j;B#fHDT_#ejq@|M2OUi-;!Meh2|J9iIz^nYLb;jb*XWZJm&)038D-}r~m?f;MO zt$I3jc<;hhH|;-k_b2Vk8s~rS=AUoAc=A)fxb~?_kA7{(Ws~n2^6OhyKlLwlZ``+M z)3rDL*+;+o<4u#l_*dWilZPH$^nL?VLPv`j4LYy1gMdvvuDk4~+l9%vYWm|H|mw|M>9dZg}By*FXG?$3ELW z^OeNIzZ!kR1#Q1m{lMyV4}9rIEw|sh<@oHx-dS_nUi#}tYrg%R)Q59V-t^J6e{uAk z%^&Iee-8D&@t<3N^Uq)X(;3sQ3SJZV?$zxRmi_fVZu~{(k8a-c_>L*Z6Ti9S{vUqv z{=b^^({KOyz^kt-|=TJY+da6sj%>0{pcf)Of2?;8glOsKJ53i z;#;au@v~m6IMpu|Jk`%Sbw3u?gn0&h2>Suta|*!|J=2Ug+jHU63A|6OsqL;<8(tS$ zk5d7fYnp=bnp*Rl(ZDfjPlUU<#5uS0zeD?DF5WZy@YY-t?GCREt>anrW4sWg0le&{ zn(FS*TJ`UiV7#iPdg_ox>e-^6MgL|z}PWd1_5#_u#dWb(QM}^;A3*-Vk~iSW|1_!HrcljZ=pd z#d9y{-m3GTWg(^x%%UWnn`-(3!LKSpUsBIcsb_GN;kZM+TN{NKU`xem=uNE|Q;`@_ zF{A3HnjL{)qN--h)Io_sGZ;}&E;#VBf@6;9z@ZR@kl4vYuKK z3r?@9iB267#9sm8f(TeQeBik64~3S7i~i>B=5pEjpqbbH8>5F+EQDP|=o)2C8eU){U4tBq<@_i4j zi(x{@&EoH?y*MgLDOcK5O$~) ze;>7O*5Tw+LA8Ue@IeSWmx}R+TNt-1L;i(57zJd!g}_mY@oTLG8iV{SSj2IN{~;g# zhphWGK6zXa;Y?2--d!WL$#sRmF^m6KXRXkf`Yl`|#`4xy$^7d5&o+^}k)3 z2E-)qjV~eW>MH)wsnRnPBy{ zVL~_&ruh4hS&!>*^06So`906ta?Qu&MZu6YN`)6ZM-^W27DDSOrhk#bUj@O|HE#Gz zhFd}iLsp~j`$qMBp+9Lf(SiSQUwl4peN$tw9S0C@nviv=5C2l@k2OLVX$~OVG$C+$ z=10Mdw!WhstnY!Mo`CWHgb)7{*7r2NOaBuEQg{ntCZm}CW!7J6443|8KK#pl?klXn zGJKe=FKajZn&BvqpZUTM`P_M*8~QxYklx$cl>i)$^1*IHZU<8v5!+TQTDWwag+uD` z_CRu+wPf7YORToVE0)e%IyO0PdB@n8)wZ|iWix%J8 z;klMBTfU_ID?ne!H{dRBTQYC)QuY0^v5QwMpGU$=9%#4PxKFX|stFy-+QfhUl6foc zM`%ae(iK)4_m8)^uU~0fz6^WG-My0!aPy=!S0#q04o$sxd0U&cBDs9=(vExKoY#(x z<`%YjFGxN}v;~XWa3m27<-7*uEoCvn4h?M$n+ehEm|uijv_G3P@hQvjJfbnEZw=^P zc5C-&?N;4I4=Z=^#HO>?Q=gPR0ZDQ-tiqz+>qjB?R5kgf++??cPF& z|6(3o#rL>|QDjVTb|IcB-+-s`6?FO-55P1b=(8O$9#IY334z~FNIXKuU&GltzjhFQ z4&j7|*Dn4a@jpO__(v-MneQ4-0%W{Yd7&IO^Z&p*KnVBiguvg$|BTf6J6GrL6n(xF z;_-VT5ub21An45@ z1f6z5(Cs8dd^T#h5R*mBmji^zSBDV!6-Qq4`*sbt5W;^4A^sb|;vmvV5F)O#HGEpb zx~Pla4H%q>^lG?~@NU!(4L1|siS|Z_a!V0T!+&&mKjCzgmv-;g;d?bqYq(FtI+oiM z_na4|yB6-?J#M=TqHc`Q?ie9Dy-C^~Cq$mKYWG4y&`fGK>va%Jzel?_5@MlvO1rlc zqTAoA-D$#)p**zv7~#ckJ79b$s|C@`v7ORQJ`zMX6W8u$LPU0tk>N z>Zx|K9R;BP<@pJuXQBQDuSYo(!rezW8GK8-$&Z3J0$;ny2ZFcYyR$w&NcSdV)ww~s zLvbCdThabSolD`IA=S+oPN1Q~F+5b)W4PG~8P1~a$nY=fm<)g2MHxQ2vod_7+tM*d z47|?Ez+yLMIK7ScZZ;HkZF2gEbX#NP7!q&azJwSQz0OO%b~{LM>5kHKvcvQos^j!r zssmL~UD!7Nf&1p(yL{dfApdsW6@}_;fn_Q)5zp!Rod7IV8L&Udcm=#pyf?#&5xkq= zVdCwBdy^mm3f>GK-fVmXmgyP6TkON@1RmokM)2C;0oG&1b-=-^!4L307M75Bgezgq z__5C_MXv*RCOyZX$C0Sed&o!c27m z@I?y8>#t&VHNADosO?t@+)V~t+4gk-jH`<`b^ho|4_0ijlip}w_7)kFx!Na82 z1bU<4$M}5+R_L9;yBWV$6h7rYF+%S+JWP7620iwlLT?DZHR<(1wqRa~5qcN-@TQ}Z za9k`#UOx&v^S?d#FUy?i_z0~07n`Gt{<{!`!Ev$}p?8IkUaZNL_ec+-iAOK)qxbYk z)O+}e5qgt+^j-u#$!B!s9zDv0{CvD7ko=uf`2oX|8c+DuX5evrCr19;4m>koj^V%i z;m34b1S|Q{<)hdC33t5Wr}s4Op;G+db&V(SnMJ%3?dTxz%zWODd|~@wJ|hZV zKK}xK_&h1}7F}81`7WD*7e`?OSfA7M$Vd23BRbYW$kG1=KQZ{7GF;4T;!!yLPYFbr zyz28^7B9VjxjGzb!1G;VSI2B+20q`V*)5cci7G~;p_v?__8A1y*wdH5Ts7v(tvD>_ zLowfI*=yCB!hn^`VZDEyoND7g79b^mmDmjVaL91t(2>6!nH z!%vKq8rVb;KVY9A?UgvR{NGeqi7Q@}j)UKd5qh75hsj?K81xtyp?4?VP5zRC`wCbw z@-IT+kqq0fExL7X$WZhozLIzFwo>@;V!mi2^!)tgFaqWZ5}@E|{-SOJ;)UY_@s}pK z^3)!fzmWICc>INTEQ_hWSkc0xxhV`$T`0Z-{ z(pua^aZXy=KYds)B)v?l<_9cN#SdfxgvUv$!z1|uJe%L4aw!?$-SP=f2547QKM1@c zhJ0cBkX$G4VZMqH9zdSLwi(v}X?(=?FYQ%$0K=ud5p^Rh{~<=`k@uMNUc^Vz=1m#k zcHo&jWiQ<2@RYZJ*AL77U*ahAh0h|$+JgVGPZT3@_wy8vi8xjfBY0PiziQky?w~$7e)m5U(zET zq1S_VlP`9|T@GK|1-xUhtbc54q(}Pvr^y$$BeFNZPmILf&lhVEzs-UKD0twD6RtiR zzBsX|Y~4%Jji|>L&3g_`8gY3yugsSZGQXrAoQCBTP|~|{st5HlW*uh@7XHX~Q0k6^ zVtg<(!<4!kyg`SvE|cG4YE~JxL-&pZ-igpLZ~24Xom#kmplwOA1M5_H3ziByh4B{r z4aR#WzRP&?J{ZM+5pBhP0U1B~+Zr}%I9fyU8HUF+B%h(XNkc^s$}C0i-SYE7Y6{)U z*!e3~jCJ#2tX#{WofJzA)?WBp<;6K;?P~6U^~U6}aC%1C{wVnHUHA#}$TWg?DLh#Z z2EscV-fq%kosxg?|KxQvvtZ5m5l{F$!v*g?jVEDoxQQ!9@D{+suY@0Y396K$ z$9S!SHRH1iZW~sN&|3o!lOER~u)dNW{fS36h-QWIS-_P=b?1yiAP zjnW>_Tna&W<2+U|ex<@Mv6b$!P6^9r8Oso)M zR~%ma_mEH82tjgW8Pc$fd3Wc9%H=*7)~MZlACB}lX*bK7JEx{_VT{3^} zf(Mq*T{3T_<)IbbEIN1YeeKKU&uiBoSaTEeIu=dW*Y(Yvw_?HK#dE*BpkvvR`P_w} zoJ;0+Ec@~TOJB67+6C9{#}GBbW(`?qsQa6vVXKBLp&$yJX}J)YrevN5%W~+Cg;s|N zZM}ASl&ja_TI{#!4|>NnJfR^w3;KsOjA+QUi1d$YSSyg{M2CQCY;}&fZy1aRoq7qXBSv6H#s?Z9d9z}1Vuh8WX+AKDAXgsfD-dKO( zp0h#o`>hWZ`D`MJ$86DTQz&LN=SwJKde+H>uwsZuLwU@UlNO=AupV$e7OzUKi2yEu zHRqq<+!H@A{xe$;4 z`!THXxfMs`THq%}=>07`OnP-FKq(K7~Ac+e4CGvTas1m(-E+^YrS$*t5AAH&&1 zuKc)7$&tqtO5vS6*OX=G7Q^x}-F)}Er;LH;c_hPNh-?_CJ+2pJnBwpXr4M2{U4u$$ z7|Jlk_?15VQ)L+AbJUx{nF{;|bp{t}1m+`Uh;haTtZ!3_!a?8dz;W%ip72)_as|)1 z?N|e-I%T48MWC24yVuyi*4T~WuS z;%4rPDUNfYFEe6$&bp-YUXObtvX=Zo`XtI3W;>Hw%(`LnK=MkKC2?7EiAOi*$4z=I zaF?RTHA5!77K5JICoR|X0F;@9XWV^NPl?}BxJ-Hp(2K#3|E9mh?`wEBdGsc@%i+=c zfG2uf;rVPcq;2x(w~_ei@Dszlpz-tQPQ>r`-5~W8JWsc9e|dN8j=%O=J@q%RZebG( z$l%en=yAxOOIe)5q}DzN6ddN~>3BBt*k9J?(k=CkiJnW$E3C;y?m^y}A#ONsP%H|MSiME=!PfuM zZpM2!(ob2C#&r*|e&sqbbGGkn>x{K2`W``QRQ0|ktC+vb&sv-U6gQe_Ji49gcxTt08< z!evY5E_nd51>&tk7A~B-Xx@rNe(#R2_d{0Y!#l6Wh1hULe30AThbS6cz8Qh~$hdtR0ZY7(6MKseN?iNBcNcPcm&n83@ zUZ~xR2+?_VX!lA&bd25F-9v~$5c_0)znO3(_8)5Z4ni&(mBv?xf`NYYr}qDketWZ-xh0 zt0yP3?n@YP<-Hy6CLZN!2{Z9n*G;_mY4E<|!)rbb-b+5bmeb(9?ZcZ6cLY|9#Pvgn zoEbm1=~8%8eRy+#Cp1V?-dlZmtwxxMw^8HKk7glkzj|{YLazsSluqJ0j5?1L-YI8O zN+2HN`$xbt<$dZ~%aQk+f#;y_q|S(XMbaxJ?>8c#5qM(onKFKPAD6UQel% zHOKh4y4#>1ceHVSac2o!{(w@PIVPy3r#6j%rOvzL*i8J-HyK@IN;e5C`GVoPz2fje zs=kf!Q2a8v*=kr9t5h8&I`f7yYlHW#TgNWdZsyT&{O?L%xYe$!i`s=jrHuAaDwu`K z+)%+Pnpja~)qp;kWkkq$vrnd*dX_pu3_FxR+>8VJ{IlwF(N*X^q!2Mf&!XdZ&bp8H zOYhITVLO%*pNMyssTip_%uAD3O+>q7tzbPO4lUg`!kYAE!_9w)5qeYLVbYrfdQte1 z9^)ePWIYJHlcs}n#FCP7e)!a&)xugtBxnN4|LuVbJVLHhNA@X~M zVYcUT>xO}a`?;v;O&QHy`<%TCB7z~*^d8y z9ARQ4?tVV=76MuY2~hA{KC@)r{W!Yn-g0ENYh-)Iz&hH^Zf1FWhB6!P)C|NSuSI{7 znT<2`dB0+i`&?Ujw}-Xo0`MGJ|Aln#3G*y|+-*7Zx==QF-L!0QNGdmC^0Lg6xO35p zt;5}ZYxA>lzCO>w*c&~-yJ2#j)-c>ZunzK`RTa0v$H>17yukIiF9i29df(wLUdD@e z2}F3`C*p@PteO_XeeL+3cUST5^;&y%KBE7{`#>32t5wH0ihB!?jzRdBihnebg(y;W z!ak4*r?=)iV{39fSj%SN-W{yi$W6jMO?zYeum-I=k9&hbyE_m3`ifXrhW_%O6R`uC zVD*TcgF6gDxaV`4-JQj~+_?bmZ&2UkyC`feX#5=O*xo@NcyYiQy1n*+VW1HR+0Tu@ z-BBZgO{rniV0rfqs{{KmQ{FY}`X+=KJo~1aMGMv0-80qmrW)4A(Xe7p;Kevwy}70i z$BpBx@8#-w{;kuZOi(axWfk}7WMkF;Dpbs54DnmU0Z6wc&DQHg=C1hiqIn%?$?Qn(UC{w;8)q_CXhb?hK?hNK#k`J= z2kEx}YQ&`vK)2?~e3Yf*Am4z>ksw6HBtL4vPnmvi&Jzu^j&8`<&4h3>j_*OnHWN^g zvWrr1&bqAkZ9X%GJR<*<8pLvE9T6ink!{iJV|XSj`zY31;?UB4GptGPMYvg~#0b4< z@G$AU4th5HNRM$5dR#w8dSdp$(Jl@^q4!z5oAgc?^cXLpcR$_{lmt+QYmv+816zS- zT>T4{Sh$epiqH1yB0G_Qm%tEoTk%xY+oz_hQ>f1B}-PQr50M z&H7`e)8xf;i(xyPG6s+HX#Nk)-7v1qT>9&@*{a0^gauqaE&Yc*hpt?T2L@rR9Gm zzM$tBuDKiMxe9Uj^Nuv|T1()Wyo0C34LDAp*i`m7{g@lkBHj^!ygUu}gAR$U$$kj; zSMjWvCx4t;U738o%Sxvnk0w)(2XTKf?yejaus2TN{aMwq)CkI{kWWWgvCff5Z+#SW zAm@&X##0j@f8vho)sB)|6N&66kYyr6^6qBd8OpFo=Z#s)>$tt4DiCeX2BK>nE4C1K zEeD(k?tzThQ=D*YB;?qcxo~v#ez^BjW({=W?3&m#CxH8$L$MwwZ1q4ke>`6S+5xLG z7q+_c{Eq*`U6zz@GvQc;I`=M;=*fm-n{l7w^SMgU7>YDQ-1r-bALGXJZi1kNI3BHx z_Ba8^$6?6p{4Rn!!$`9-*`?&-aI#0y{Uvb8Urm0?ept+Ol=rPQb=`y3R;&xJ5B1=N zpWvDrYu^ih{lgbufn;k2oNs)Y{dvJii*tQS@nLf%0^7*P^vBEt^5x45#8ex)%I8LX z^bEhh&2zbJ4st554OlKy^{NY-tF9X0Q9DK4yC9y5q{``O2(!3{fZSbtA6TmV)!KLJ zN5~f_udXBnqk4-Fa%?ryz;o>z0ND?4E<|+3lvBy;D8If-ov?HSh}s8JE@d4MBQ+Q$_Jd%ilhCC_^*k)Ksz`|*4=?|8PK z!x^J@kq7f`MThqSN75U!)z;_L{p<~pQ!U_uFdQhOBQK30WJDNWa2+da1u5Jv8AWo?MV8-Max~ zPnapAOvg8dp5nZdlfiZj6IOFrjCc2ql-drFGK=?d)7uWT~ z2qSo$&H9_dT%Z>%UxE#tg^{Ln*EO71It$h>F;a_}za}r|eK#y4wgKYMGTX_^!InK8 z$X>j&{)rKKcf!M@*93Yt{7BF28y3S&dSW7QG>ZdJ=(XY9q&M53$9PHnc=jKHk^suE zA1tS@Sp__XuNiME zGqB$NMZ^up8+Wj;iLftF{YhcJbSXck+mxy47Q;5`cb{*vGi8K=adjFjKi5bta$V%r z#rT6%nHTT}=GB7BydkgVl0Y#G8zl}vx}^@f_=CLtXhc)AT!!nNoZ&i))V>A%h`QWM zL~FNfE(C8S9r8|=)rF{#;^sfeJB61vYWHYDHlBCIOLYtjoKwZ>9J0*wif1wp#Yk-$ z0}qoY)uH_{&;2}e3jDxYJf7Kt_fqt3fWJv^v_a40nF&n~K$$ss#`HUZ#BVy@O?o`D z)`lPBXYx$S4JOar2)EQ%yn6hZX>eH#ecd}RY`8r=9&rR&vo{=6aF60FCw}HABl+gyt$k9Y9 z7sURQI?h|J-v&Jg^dperBR1wbty!6CDX+&i<*TEclnx{m>vkx=N79=hlds8DM>i_H zNhA$@2jp_4r-^rGDN|QtuJYLLfB#5j;(6#yX7Id=$1!i%_2lG7GZ#V!MBJ|qy*oD{ zU|sjr#Qx0p_%G;JMh2`6mrO|E-(A_JbXT@>SSoXP9nQ>vZY3Ol6grhDpg#k8A*&us znvYV)^b5=S)9Uypj1^{NPLtaRR*lTfi#h;b$aqq zSft@kgVi%~KeDXL@J;@k&tgo1F--vf{O0gfX5*;MZ;trl`pm|0Jx(MxEn6MyMqYR4 zsTbNfrRUA+_?mni=_US%z^5}K@cu>6iXblGKK#4yN65?1WGp*%G3JIRRK#vk@jzL; z%6#}Ah-3PaZTa*_^p~;6@>cTEe85_ft4ywS0$*7_d}wn0@RMKt;fQE*eQ;>m!5-mx$q!yPi{f*w=f z4C%i$8i+m|wNh(v;Az*$O1nP$Qgd zp9-M8R8?7VXGpRW-{D`$^_Xvd*kN2EsUFAy(AOn5KAw zwoq5?Te6iHTY?ViaA&3>jrn`zP0&W&wUF28HK@O9@)saY;p7wfs(321d7?Yk3|KRf zzOJh_`rM)94^ieftGq_uKaaeBwE}w1U=n)H8nytv)gCQx^2<7i8Ger_F9xdSFR#K-q7vx1JDa&jYBDZ zAUuRT<*j#49<4%q`R2q_W(wGAE!t8Kc+(uT`;BNj_r$ug)pn0lo!z|727 zR9d&Fv<6grwVsHisb83xp$?(i-h%qE8T9~dD-DY_RUO}$AC0(@KKi>SW&u8c|6Fo) zDzglHW~uNQ#3z8X;m+e6brC7h1Ft+9imgZ59?w^@EL5KEQv8oRkL`zikUWs-{RL<| z6`)RJZT3${FOB@Mb^ahe#Fsp0eut6ofmpZB^X}~5xAEkO$vK+~**k_vm=; z0Zt@3KO0DGa02!7p0V_#VAKY>eKb|CgV^x{4F)zSV8>i-C|gHVWk-A;7{?BHYMKL_49 zS%ouJP`BOs%=a+zll7Ur_7?nONL4Ch!}5%!e|-n>0B@^IKIE{Shm+m;k1!tOcgan8 z8}BU3Y2&~Xqp94m73;x^d-Chy&oV@RyCUG8--BV_I9=(SWp+t!SIHjRVrQXqy0}ovm#vAnhV;lYq1< zwe19??a{Umkan}SDL~pC+V%s|?$$O9Nc*C;`vGYWYU=>f9?|v~AnkE&l|UCj+O_35 zFtl~rQl_IFtu4pJv`yN^0cl&bO#sr)*0vRpc9FJ8K-!hsb^_A&Xxj%!yII>5Anguq z`vGZpYnuk7eNo%}fV2m-bpUCPXnPEh_PDl6h=r^f(KZT5OZlDF)|T=&E!REJQhuh5 zYuf@yo6vSPAZ@F*ivVep+O7no?bNmhkhV|T&49EiZFd0D_G`NvkT$LDi-5HIwLJ(( z>u7rfkoK6i#{p?AFd5p2wmdh3woY3ckd`_i+L*RYfV6RKTL5Vj+Rg@~ZPj)WAZ=3H zm4LLJ+V%j__G!BrkT#|54nW#|ZFd9GrnP+$kaoYe2LWjvZI1xb9@F+XAT9MA9LaFp zV(L7ogA{WRb4)kYGs*Mn;LQi#ic=KCv)bmGD!~0?~vNpgz0!`-mBAabI_FI7g-h z!#yd*;Si4v!}H9F!&!O-!+qPu;T(|`OsRd_9DmZVtf|An7|%0NynVuRx%~sibe>`O z6wl>`-=f{40eP3e0_|o_4@3Sy{!+$uS6b-!4R^KmRFQkI^-Pib0_zp+j)1^04j)_< zjGmvRKHv2iP#ZsY#r)-J&ANYf_EZhOkiSMu>A_v6-CV!Ga9hJh4M%G@M#Gqf6E$qoaFT{` z4Y>}2^jb9J{07|#4QFXMTf;dTwraRg!$lglYnarqL&KFCuF|km!)^_GG~B3RpN5+> z+^pdi4O1F!*Kmi1Pixq(;Vun#Yq(d#w1)dMd{M)fG~BP@0Symo__~IUhKDsgqTyQ_ z9@Fq`4UcPhLPLlPDxY~j2lG3kVYP-)4S7EX!|OC`(9qV9`*ayTT0`u0Umo2} z8ggG9-Ej?@HEhvvx`qi2XK6TF!#NtZYPe9tMH;qinAEUC!<8DY(y&v*ZVh`h+^Aun zhMP3ptl<_7QyOm9aEFFZYuK;hE)92UxL3ophWj*pQNx!s+^^vQ4G(Jgx`vL1hc!H+ z;aeIW)9`H#k85~BLkKXc9Ksq#G_2Mzs$s2$bs9EkXlvN0;b;xVXc*IQqJ~WxPSP;0 zA=m7%KD1~!UBiTivoxHo;T#QHHC(9SA`RO$OlsJnA^TPShiiHWJ2mXqut&p<8un?p zNyE(=ZqYEM;dTvoX!x{-{TlAlaJPngHB4)`Ps0~Ad`ZLo8XnN_poXt&=xBIY!y_8L zrQtCR-`4QBh9@+Hc<7eDhPCV$a5ickA!LhpH-{$D6;`3Cvr5H%iX2uP?321q4J=4% z#bF|YxwCZcL8w|hqtxYIG~zA(Ca^wQy+Ax2)m0}nI3 zv!n1pT9{sr(1^$Mz5r{|tF11i5kX#h-|*qpod%D@NKcIHX%e@@kMdbj{Lmm7MaGZg zL5UycEST0Lyp(Cjf3FY+p!|yvEZ;L*fER}ch6JjulOE~wpOSZYwO+^1{(&#r2tCHb z#9M^;VSdOn@_Oa?tH(M8azi)h{8v$>Q)7v*reQpB!Ul{Ajp_k4D zezooEi00Ahh-E7*Gi@U59O!DPyR{PTd}RPSSg!vQeeTGi%QC5;yCzWl1c&E&oatM% zB1H?oQ3lywq?1(WGFhw`ib4 z8`jOs!~sb6bw2k@pZhd=grvI(QTGoem-TsFg|9~_`0GKxiU-&EF(24pk{1$=(J-cA z9FXh26B;hmko=GS8#QEpajnZ1LL^f4$6!dTC-1dCRtZ0cof`E@Z0EA7s8IIsgb^Mv zO1}%gI33=lz$4Ec2#f3Tx%g?)p4$+*}9Or}-j z&)67Yi4!y2Gtp~x{ zf{D?>y)L}JdbHuLfSdD@b?{Sr-s9gt0@_CzS25&EO|UE@Q_tQg2!P$N1~11|)=6wV zf90=V*jIDj>(h;7pdO!kwl?+eg~|{~qTaeKYk``*RL<%^eg+*_|?Fze51&Eqn4EtrhX zboP|EzQUJ(AAmlD{GI%8JS+|Sq#5eXeS`rRey4`g$MwL?dMt)`G`GQ;eM1v?FY7It z99szS*w-wEC0#Mqa5RYnQ0TSc-K0l71geFi$6^+G{&nHapjS>`(*Zp8H*Cvi>TB3% zJ_Z~y_(U0hUz0-o)(H}z;ORAv^V{3hR`vnq|0X$tuZ+7BsVjx?`WpAM#%m= zq%Hjp+26wY6wILVtZhHvrdv!SUZ${eoJafGSq}S9}8%sSfYtCuhYs)ExjWrE|y%-nVtpEN)gMY2)Mt%sVlXy0FLHqS+owFwVevJpqZNHO|r&70>$){_-*CUK=DGp21 zijPXQ-{}bZ?{2^5{u_zAzx^f=Fh|AIeF&bk-{rdV9Z2_f?bYSCU&sB4*M6yc3#56j z0`zEDw~X^1GT>4DeCu!3z*HirxU1(tc}p+h`f+^_#Cm0z7PeXT ztzuYj(Eq9;&>b+}>80+}BkqOx;d|l{yy9@{mXX+_5vq=+u(Ujtxf(LL+GB$C z;~U_Qvk@z-ST|_6=P0_wAt-@%JNEEf=^0ro@eSx_ZqJ7BJ^o%boBpw0thaV~(Bal^ zV7`L4Sn!kLNhAI+ zUjHL{AFQ|^86CQ8SSpwr27S+fx*nF(ZyVoLDc28^uQDxqyy#}R7B-awVTv!kM}3b= z>)bJw^J%=u{1YQ>@ssdytC|}!9l&;9)l={|4{f&DS@?);itW_oDbx|0ZMGfma@y<` z;H6;s58(l&+Uz9!7fZK1BXRe)*@Xxo-x4Eum>0ZCMu41d8)&@9aN^lzv{|k{gYnud z&+s_Ledx&<*;>ePlTtW`x(~8jEB3)crn>|(T@%jQ=3eTt6qhll7wW`**nY0lNac_Z zM=kpg5&r31Ah8yELf1Iq{)dMnJWyfH&Q!;n9m`&qM?PU6th>i}FyuNb&mU1d$g=? zV4p1Lq}_OO&wT7OXHl6l&M{=})YAKUnu4>`PM%N6ex3$Z6z(IgzN_vItyOz~>ONId zectiJV%bqzog4pB`+Hd5DQ~$(dT`fO>U=8lMjGZJdFVyTaY$&hx06+#vO2 zIAqHeOO?d6!aL^#+BNZ`gsDYJycYb6j)q+cGMpcb5u&qK@**mx;@ha5IbICvF#H^)H4p{2V8mb_AG zR3jX5xWx#)W_XzNT0oEWg!K5W(EA+TNly&<@*;5n3O(xPO?tCI&xRlAF_bYQ z`DMe3ky_;Eu`Ot?tRa3Ldo%n@db8kWeGnt`roqGHi3!kS9rE*7%DJQ`W+Pr&!~rPu zc%PR^uNCxc`1yJ4BKVm+_5j@F@YpaT0XqyEo;QWmeWaApOfgtJXH;*6a+SVM<1xnn;$9FBD!rVQ_% z!vcBNN~t^1{XCRzF)Z)%jW?R{E7Te{#--+Qsav6Oc^Ps85*JnRT0#`pxfz!$!skw6 zd%t+e7~~hLn8`~@wSE6QZacoQVZ|V~mAM{IvrSV+Mjk=F15w(Oo2KL4Y||UzE~icJ z1zrl4|Dff6NuTea=NYd5sPkNfw(4)w-N2hu0`JQ4*Tk-o1`Rk+n;tiQLfPYT?hl0V z+BD~J)wn!0BTJbmhOw)abjPV5Q{&{jav_XcKZ^HNeVB7;P2~>v|B*hoE0w9D4Alww zDaNy_Qkm;9hr+Qoy3#!;SAfsvs^i^Gpmkjqb1PMW#NF9&YD4y4aHbIVQOFr_R;z>a z*it$ASvX@z{4r+c-BU+Http-feUy=}hBf6e_DN#;@p77RaqKH(L(QO7Q5o<-S;*Rs!R$63nr=VEy)mW=YM z_TqUH(&X9qj3>_$U>tbH0P8--uJ3-Vsu-M%RL{lrCg;_>Hp@ti@UAiNFnL!y+9}IP z_zdyL$8LfJ+wja`yfu5SLQgdnekQ$D20ijyp?4SFOZV`36HMWeoX76^Wj9 z;QKj|Z4{w%HcEQ`=P?J8ZMgnK>N+#H9oFWHHc~Rz!fm!^S*PNcZEgjg*`7DTT~2#G z8`(zs8b(p#?r+bX2>2`!v=KbWHsjAuwwYM=eMLMg0mf_3+=~>|I-kQ1^gC(j*`2M2 z8&vxx>I`+?W;oi5FL6F7PHS^zmb)N_pzX*04sy+E>@NbeW~#Q&H7ahqcXBw>@RYS~ zrrg(nKPdgrO|Pi#-3%j7#GUQ4t7@#N9CMy;@(8+f!-Un`aUuRvD_s=IBgObq>m{5D zm4e|OAz7!)JfgfpD2DyW80}y_Q8xs6g{+}iT5)|&kxS;zows7a;>8eM6gP3@5il?% zpMdc(9h6UEgm6=iq1^JWpAH~Vfjx})}daVV^A>?cRz1zMf|vrM~vWUS*LBuf(6M3%UDA(Zd|Nv z-na$-gzf>5jze0?(f2x;Kb=X{BI{uZV2G4?ohhZK|UP~ z#D0Y{WYajh<}Tiu7OA!p8J;a`VcjtAP&*wi_XwD{fhLk(f)8_#9^Dj0V^{a(+5wXR@F$!M%+G)y;ns)Zx&R8>+!8U}dUO&rAw z(HMmno)zzN=MG)s=S~gvzKzkyx7Y?v{>D5MBRTJ1A95TBlLQG+@cipTVrYBh7vz2D zc07J`8{SQRG!c;~haYj?upi%&{|Ij_#gA(7-wy*vjPMyhKO(=R-dv2}K~|f1)!FEw z#+83B?b9XsQ8dRjzbBnQ_DYqsnbZm4{Cu2K4gP{U3w`sPEM$l4LKt@i>{k!h;LLBF z-4O{{BXacn5Ac%^)^?yRZQvRY@PEj0&@(9>RQwI^9uxk<^FI>tZTUn3=VLdAotk)e zrlpm8%fZW9x}lSL4Cg`PJ$A8E5$$q9v1f5^{)kN2UX%SNo{ycL4&FD1GGvB)?;jx> z2Ggm`KLGNS*3V~eGsJA?nGxz02#gmsJ zkR+!-QjvYa%&&^8X5DBF3P%EiCFbr&{%5F2ie;W6L52x2mkkqAZRu512}KPAT{9Y`#JYx)-8@H7#A^;ql9K|CE%uIUoCwp%fc^()0B zX7=IoO`&crNtRQ$a3_1&viNj2L0;W*W$~H0DEdC|*e3!p%Hbn&m}AXg-%JL5czp;m zHSezpJC7d@$G4#0o0Y-(iuy3_a0o$n!7$>yjlPGvj6i&97PP7;QwP#<=q`ANMV|v1 zq$=Q?$Or6S;SSDbCy2W?F;`m^wC-@C=mYuPuh3_)FQuFP8KGa!ru---g%{{Dy0N10 zyz8?l9~F#nK-Z^K9|bjmGATU0J_=R9)pMe6T9S18CI}YqO?C#M4`|=Syb~ii?(drp z0Kpuq37)@ia!_&EzWuVZzi&DLoO1f6F`$wv7L!CX&nCH-* zaW7cZ>C8rxBl6X)Bl3~Nh*}*wifb0k}gb8;Y%V0ye%)|KxBWoz3%p8Gc9o0C8QOI8~h+ za3*}EqXk{!gD0M%r#0)IjWSI5^aS(IV?BXi4p+57KT7d5(X}$29#2a?Xvp0Zx|0u* z1nWH48NWB)23j9b-o`u>BRtE`+hzgBlqm$y&)Z~9b|Bu?2YTi3wlwfkh}=NDtrh$O zGKFU(Nq*kOIoVRYtsomIHRXW3?f=T%URHZA|5xrVZX;3$(Qh`L)%;-Ws5c?NaZ8-nP6LeNWNY;hg^@JW3zM*TJJIfEb1x1gM^)|JD<)IFQ> z0^9$b^He7GuQftcJyU9J5%~fQ)5QJ*Yr#B2+36C`<;qe@&zyX4?t(@4yK*xQ%2OQ- zeRLou?ckVu@4UtBY95YfVl;sc*Au;`KFB*8qv)sStT%eU+HDMZ!!}~-s7v)R)c278 z$6;x9<0Fx8*$>gOzquJ!+8kchCK6L7l0Iu1!c2NE8uSnx$#+A=kjx&P{zQXe{0$5wXIW^?p z6Mn`QEUDK(7TwUor;>b5x7kOQvGllyqdFQ15M*{09lWTCcg>|%|v-E!|TJfLO zpS>AM?tgO-?lPtB0J370(5gv*p8r4Cdl|60vzB!?=kS_%c81ltCQtdC_mfsTk60Kd z3`d$mKLW3e`2600AL(;X=fC2eYfq=Val2Z38teqEKIBKgyKbENj9R-l8$vwDZ>Nmy z&DO@Smj^m`E5)(JlhDcEl{ta&0pi1a4I%%k0`VKOVXMap*e%&W^w;?*uk>bvF(*^O zy_&p>cNoSWxaSz-iHtQdkjLG?^|jHh`6?U##vQ}l&&mIB9V_N&>T9_#6?=q2u^Tb2 z>BSu8t+=?jCzpnxv(%>8j z>*Y<%x5O9of!43)1IcMw(g`HGvY1b);<&HEy?b_p1v+8uuL@!REz|V3Cr@4msWUg_ z4eX7@+8EyVT!nn90$rqG9OGCKz0I*ucLVmV*+Bmnvdl~VJCt0HI{)bm(!8Nk@&skY zG762`=;aCOWqlZFU_Ml)H#pU4q#yAIefH13e0aSmA1ad%JN(aK{D(m-wDz-dC8;)>YV}`&H=0c#e#lk4!JVIa-}aW%dGA0qy}*Yo_COWgEGVtP}ON zH5Is(c?i86>o4+i!^f;yxfaS4_$GilVnu(d)=dYZ&DmieTbAK{&=`5<0)05Ypf3gX z`I#K(WY7=RM^Kq9)U6?)hdQ&N0qr0hbni*%C(f6@b=tZzWPqsZqF zbbMj^HYbp3X4^rXy&3JN7iq+rZG0Pu-IuN49kTsxS=Qko$^-RbR1jqs!oTC>U(snO zvo6$|wP-i%RGw8q9>RDAb>r2;fzF4WfCGJ^)+O?u=JEJ0f;iwGIm_xoTf^PmbR)0x ztTV0dTJJ_(XH|4%U9)_VMRol|Aw?rT-fGcy;fIPX6k?8kkx&ab^VGoKsq4ez23pp6WP zLJxs||1;wHD$1Mr!Zt*@RuuI%y3VOguT^b`JZNw%#qXh8MH}iwJ?fj5t--$ZfTPJbS*c&6~Ko$R2Aq?V$b3#RbDk{bE{Qwi5naI}e^%B&Q;tp5c1m=3?DPQ9rvI4XosP z`l&U$B2#P9kziJ>r=RFi#Cq`4ebZdi5=<%d7WKq8=i3^LDkB|~ZlK#zhWQkP+cea* z6ysM|jT(XZ7DTvdcz#DQex(@<`NWiXUS3f{ta&7k_15$Kqv6t&T4*oBQQ?4`PM?();EvZEIWD-ln8-Xr$e* zl?!vHFq8=!5KYQ+JinUpX+ULNrTsT){{-@<0g0=Ho97?Z5hD4l7j*MGuCZIB-R*>^ z+-JY;%oec-)`F`YA^6 zZh;4DU|a{BKzXrFk$w2q30iq%t567NRR*puP_!__NBIR*7=Pue_c%!35W4?9GqJWKn_LIe1f_S_PjLQ&`9ONUr)#I~obw52o*O)!JLVY`F8VRjDW#)#b?)xmC1e(F{();&Z8#MU z-!IXp+Q@V<)c*#JL;r&AWWp=wTVF@^TQJhfT%S_&2%;AQc)OWD&6eD<0N*3|J?O6VlLzhv zy>fWqTfj@wZ z-7h=sLIC>`F@opGPRVljNXUlJf%yh`DU8QAC_7OOia~z43^G$dugg-h4b~P6O+TNr z~UA?D$-b2;Xtl&s`J%=)qoMe2%wT{@J^jwm~QB~)Vhio&a=b1iV)XS z1UntBuYk@Y06ElMSCPQFif5tYfnGQq!&)wk>%;MHU>(?#N=9%C%f`NF__sTu!- z@%WO+GvKuw{{J*@{ch!+Nyxl%pMcU}W>rnQlVLC+)Qq@e!LGHd$x{0G?AvD1Eq}x%%&K+0#pvpqi z{~KhXev~2kA^8<+hVVjD7UF)@a@L2=IgKpjjnP)L@hX4;*N2W9Czk;X%&Xq=$wKbl znP?94Vn`D9yWFY_6gjzq}`clruI*2h-F*gnUbu`_D@g2u@9M@InWgN%#5j^uSknUDvx$5V- zoS_(p;XW^n;lM{@&*yMfI3U)>I~xy^&vD&~jMb=rJ{b*UxmF|)WgKU!aO$0zE|sPd z;ncZvy#mftJIeHO&CUN|?``0#s?L1jeLeyq#Pk56rcAUONNa{hx&x@u(&+&r(iUw% zMp2n2K%!&}a0)@Ob>0RNAX4l^0lx;yvD#aIUhcf;=nSvdx%VKnWgPX=mbP4f+Y0PJjkPzkk|uy#q`D4w@aHi-cQ%- zK)m*tn|xAu45|-!w@M;l3LeI;XI*_h`{KR&qSq)_hUA;*dWilbF?KC;NIF}EGqmgd z)*iFGSZ9k_dyMKAQsImbH8|EyOMydIM(J;C2QTorwM2TsB*BN(&+(8q+ncjf_2C->v;&Xb+@!d&(__R0MC{e6dc9Ki!|^uc-W3e z8YR7;7eEW*WgZAf+QahV00LSC38vtg{?MJR?dyu#r(W+}S@hj}9FGD7x*O#M`!iU7 zo2`T16ir}#U=k13;c<^J?%LC95S`Qj`W97=w>!smr?`J_qV8+x^%Qo$!5#xnA~I`g zd&G?ahx-I<^Yi^4;Z%4629q}|e?k%u<&E7BW|)gdK;f>|#VV>&vvRA$=^5a(ty{Nd zEnaZ(P`)rNQFP2$f1)2$kIL_Hkk~$wGA4;U5|EM$%b266WGn}%zanEOJEZ=RMkgM= zDSjL=2K#L&3 z6g-hJofxAmM(4W1yQ=8%p;@}o4rEM?GgX}#9Z9FN%dq}A)|bw9C9xj0ORq&%Yk9rb zb7d`XL$=(Bu^6r;Zbcs^-ZI}Gg|*zvv6lP9IGnGOfnMd}>;jA!%wzc7!#$kuehn zDtSMtx2>ds#n<$gkd?O#%td&QTFbn2pln(9K;;9FvrStD&^IX?_4)KbiA7iC1<#Ll zdUK%hwBtRT8;7)hhH+qx`ETPL-v6{5Yv`F)?vsu<^Kw(+&;1WP`C_bNW55U4Yqq2>$;QuxGOK4j&iNI^JbaJvzKuv z*2j?-=sBYe*p^#n)?-J!e^l)PbyVVhoBAbiBz!sA6UNQ`1xu~>v6lbM2=Ly5`RXgL zuuJan&K2f2@BNC@rU$tGoO=LpmsY=|({Z?WWA8-Xp~bse5@^HNX7SEf?4i)_;JpaS zUfzj2X;hDNjAwEtpeL)lT^e*e*Pk0BAVQPV525 z=cmvJ=cS_In)`B0o;nGXo1*ccx-&;Ew zL{F=w?l+hP?{;5`G}PTeSb)D6_XAZ6L6|yBovDHmn8g+BH{0)e*1No0$PNqBwZp>i zoll&QiMn{wRSw!~F!DbFP71 zLtHG%WdD?XhCHxGk_WEsDhwx=9zh3&Y2&?@b0MvNBD3#Lz1)#IFqDR|ap=5<_Sq{>MZ3_KZI9t3voyA$*%Fi9acX zKS|-|^@&NL^i+rNt3&kd+D7{JXa?QxIr;|r0Rb>~(QgQVZhKCV?$4P}$^f35JiowQ z>MSyDPlcB`zgG}m?z9(#R|MzOYI+H$%Y?Jej>liGanoS@yNp|hR|f0&wfp1F_X@(R zoIf`1B+T*1?}G*5$gkCRsxGb4ubS^@>!gcUdefe2Z>6TSzH@me&9$kvH8fXt-jix; z#wCn*t|zup#`0F>yIy;*wNSL(1Q>Kfqu@?4C|xQQCTu;@s9y~%^in8FrdOkrcO2hU zJq>fz=nz$-5ZT{XZpr~DCgcq6vk{Y=_5s_~rXz|D zBl_0L-9!@#(<=J7H(vW`v^_++D;m`PjiCfyldQ4Xrk!A zbDWv+SJOly8jO23O$>x_4K>4;(nK{%8Fwem$ylFk+#G|7@?+2EIK8}nEexmhYqh(` z;;I5q#S-AD0?&Zc3VZ{e8^o8~SKw{^8k!L(p3SJXAL)iHESmqDQ(yZ#C>Ty`!K<880B|qkOmN?Xu{xEfsp*u-o+B z86th(4AI+T(JQy;JsP4{7aKf%yF>JzwCJ(-A?Z61qQ`sb2P=>LA$t2QdTg(R-jNW! zKG17~p8)X)89a9WJqLQE!}4WsM(F(tS5Uc&84r9Hcxk*i1#kT}9@1lanaA)BU=J$ee+^tZZ|Mw= z2VxzScCDv_SM{CIP4mXnGMB{2R?~70l|1+g1aRXeL0?Y@;P&-3U%y9INk?; z`fY=~G_fmpG3XPeAre>Wc2mbxpzZ(!N~Z)am}3$g=Du zne@!*7}qNYZU@3Su6PB;`+dU(mW1Dvi@4aMh;{f(N2S|?cbrKNEuP}9h}^8=#{#Hn z7TuO{v8=QrG>z5#Tux$DwR{W#yCe|L7WzdU+#R^t97#@oi? z`|wR~B94KJ96i<+PvE=)q|w2d16Xf7z_=^%UFC^Q&qlm?&*D43hv#|tJ--9*R$1?k z!Z|4XKD9On?=e5B+|BB}Qn%-Oc%Fyf^Iyk%v#s}zxvyr)FZ{+R&N(PWUe5NqpT&8$ z&&Iu;@8NkKe$W5@An(Pk_u|%jnB)2$p6B8B{4IEo`EU{P;h{y$howP2u#C4L{I{3= z;Y&>iFDW%b&eb?(F_$BC$KSD-J$v*^ND|yK|99 z-y6{>EBx4um40;cR%J$#jr}ak%C6nH*ow`*gS{iDx35D#9oUFyme%acT{gS7pZi64 zwnTMuOYUD#Pv&Es7yX8pKLea=VgFAsz0Q3(?+6~m={{!fbF-4>Wlcn3HGv6hGY!{7YAienbi8&CH1@0#(Ff8+}s zKi%xltzYSP~wl5l0_oL`M#d$TzQ{07uJk{r_Mo`Yo)BgpzO|-X{N*FC6kKoF@OZPag84m^X-dzwnW_e}b`309qpUffU4pVJPw&pXV#>W7 zxIDL~EWOzO??@NZ=cN6^sADfjov#moPkveroHCS0)P2nVwBvk-C(gLArm!@8*4|DSu!o>=B$}#dhho&!#7wMtLR?XAl^E{s8c>W&GIFR@7+<=GO2z#ADE!+a9!Dyj# zX&NisXm43X)m(HL3+8g)Lc=@g`1{<7hUnkuf%o5(abbQp$Aw*d<8jzE-~%lfY+Tqy zcqTwYFUkUr6T6n18o*TJ_FzVoMvzC~IW%tG3ELQ_-ncbBd#iciII|5LS8lXC*uPz1 z+$<}OOMWF3ep|@h7IJS0xwnMe4}{ztfMeHJjT_#zyraE!d1o6&3fFB|*|}j|8%Gcu z=iG8*^A~SuzWysWELq?*E9cy6=YM7KwZ^Np{Vqd>SIlAP@$2ntZeI&~=ht~V?wt-S zT;#Q34P9**lY|G3+gaJ%(Z0I9bG^pYp-yw_@_Rbk?^xA|J5#{>)llxZ){o{wWA+#m z0$!~VVg0Cv(pE(i4Q(UegV0?-6P`UZu|S1-O!XwKR}ilWc}$c1z_GVeG|}-zR8Dk! zeoQZE+>JC@q#tOEY>>>ghnQFj7++e8{9iu3Fw4bvkgWemjz6((3!q38)Zv#|pHwc# zX@PK~9K;YRq(ENZydHKGGir{8>X_rOE(wVBi}0}N^@3g#{78@Q5)XYrC7(%8l2i&$ z)@=cymx70l*DwU$9~wM)e--dL!~s+2eG7IweJ7AU7k*41rHG_&5A66vMz7#F=v^)j zm`oGFP8;2E5YNDqV@2e5(o5iBoS+xL5k&S!fh$ihtY5!_^z9!6&*;~z_*Acl)vvJ~ z%X1YBzsJGV2@Uk?3Y9ziINz_@ZwKwa*eN6IHk57w+QaUV)()~<@(@?)MNu0NuF+1m zdxiM=-qAe1)DFSVhtP-Z6vUwd<_p*NVGT_Ha!(>^q>YwKLT4o!!0H!olLwGHj-+Te>T)z`Pp65G0iu zV$CQ7{^k=dm}vjd_C_7#R631Wic0t+5I=>1tBbp(@5Vpb&&cMJnYA~@@g$y)$ee7?;GSukRt8@ zJE|iIWbqi}40WIL(Tj*rIYU!)B{2u{n==iF%iET(Xm=tmtkyka3b2g>j;;9QQIz#&|N$OwO+j^wQad&Xyd`9jCT5 zK%5A|$F*V%*WKFBair+v{Q6Ry3trabbo~-zF6ehH8bDem#@z=dMk70+g>9M`9oKy^ z_g|ht`i`c!#_$20AB{DZEf|l&7;&Yush?xXj^CH#oW$r%h5z8}ss8lS>Fm^_>Fk5A zP4`DBzZX1OR*G?|IL4GE;Jh7!e%5x3zT|6h6>G2Ss)e;q+NVeIWEW17-GMgC+fySi{T63PwlkLl~_ zAJc{M;F!2~;uOwgAMh|HE$_#1rZV5be8;3xp7Wl(&o9B*%xF_yFKN2YFKOa?#|L@u zcZ2sLNXwaR*jJ0PIe~Az`r88yF7iHxNAX!{I+9T9zS9%V#uEchJRK?Zx}zV9!X8aW zu#Yzyi@+XH^DwB=O=?^;0zZsfj(72H3~`V*9PlsGJKCMlk2GQ|a>4-Gf=N-BPk8BZ zQ|r?a$LpHtc$-R)t_e}h4)VQNDe@Q(X-{oHdf<<+acA+~)LBT6(}k`b>@$!a*g4iu zT2a^;2NE^u3GYBQg7Stu!MNh4oJtS)o~CO|u8U zn`n9<$9az!&i#)jF&>{xKOSpIKU30@e!Mh;`Maj{<0UDa4c?c2hVw7czVzd~4*=!= zEa_IJyZT2zv)vzy_4$s6?{d>Kc|LsHQD?zVi@V*YVmR9x>&>@U_TATCQh%QxbGa|z zmMrF#`bRDA_BjrG9mdGxSdTstJTVb@iA>Vucc9PD2x^N}v_CenY($$ST6&Jo|~ zD))D9p5jlg!hR~$+1-aG`!R2`Kecuf(i8Ke4c(y6_`iK>3it=IW&3Dv`x|lp6FJ6- zF>K`hV>!}~Ww76%Nqzf(gFLG1g*_ATzq6xG({gucdft{(agS-(okQ7!Z_EAfOql93 zo+%C8h&!#$%;&eLxbQtVhktwNfxY;4&e7e>@_(7%9ZB8HJrHGa?{o0Kk$WFt=h@@9 z2QJl(GKKuWdsyp9AP0 zNgl{zNU6+mxR0z!onx-#v{O02d@XUYzayddSdb4er!WwAADXz(dl>Q)ax}4ZVsv@; z#iZl3q_fyJFo|`Y^QC;Zq~P5xIR~tK#=a5;Cp}e3W<~ zM;ZFkgXBx+^=^;m?~=!rjFULIN2D^-#rpnwiF;pv6nElrkA4*M(UdvyME5DVx1!R! zp+A<{;V1lEm}Bkf|72HHe?_+2M*{`Xx2nIqPxxhLZd~nV%wgSkD(>z?UHNKu#*R4`DU&%uKW`Gjb8sf1I-bnTL6E#~GMGMBQ&A zpBFJNu)hiAgL!D?JIcB&kwp7zWI<&L`QCy)1M-l0$3D%Uu%3W-nP03=QkN>(Zd)>B znXYeH%oq9>T`^D5N7Z`WaZm;cX%koWmz3N%Fz*^wkDiWRmL6C<0eKA^woR3&*Oww) z=(GHE#?17OBVPJ2E}_Rsuy8h4f~&Q6$( zd0@OZaoHx?C(pRDyFMH*q|X=5%tKp@?_@oQrNF-}DBGsJxjM8R{H~LUeYvxF0e!_o zpm}z*<9I0BY9k90iTm?wEnM&;$~F%CO8B3_yfyRX*yLBU3AB}zp)qf+UxE4I9W%O> zOu>B~KZsqq^4L4htJ!jQ@6V3GJdu1g8=JH_6T5Zuu`|xAhu%rP`eWzLy}ydyw)a;h z-`M&$7mr=^RyBCq13x%`i@{6ao7c;}vF}%7@7(t*oTuJD>Km8+4fn-yptJy_P$6=o%`^uSb_m>~)LLVFQ%}=6l%e$Wc z7&2F#)wwm`9GoFJkIp+?|OweX-sz2^#1-Y?nI9cTi8> zMuAgy<_s-CS)cxgJIm)uI-T^1EjQ1)Yo2rThC5at`j7LR&p*&|YH4;} za>w%>CF_>W)8{wR9+^Nr8#{qOh8+xTYVi}#&) z_}QQAnLYFSPyKA_KYsD*&wu~z#((|T_h#&Uc*lP$ec`rG&0D*_wRY6evJxZ+{U+xR z@Nf*w9;fHnt3WR-)-gK;V}BfHsu4t(C-BUzsO%}(65krzhSSKtRN;1(RaA0P+_muD zQh07p>6X!3M{O(Vjo%mB&a=yy4uPex*zPpkkck1fu+24RVAlq|n0JZ{G2cEP^X+d| z)G*Bf05>#`Uy#m9MeE#j+Ua0A)jm0xUO-sSqt36W=^3-7bnEDCqk2p3i*Jv83tu_E z!i#3qy#K8g$UOTSSK)m-?~g0m`Lo^XEc&G?ZPh)aw~X3avMt^lyAQM*D{7-nWfj$P z$F8cthuYt|L(wwlWReAt5*7?LFJlEey!WQ?{n4sSnD-hW^ey1}gF^f<3jcI~Qy9v7ateJ= z87$y>gu-w;w>jQ+Q7D|F)p>|v)~N9PkLmP)KQut1S`foXXd(VMh5t@~Q#h&$-93bl z-me8QXJRNEO}7Qy2Ui&1$5njCgY~ zM*QCj;s2Jxj|b_|1AX#(45Q

zGVBMKPsq$5I&9aXPrFWDhUKqy_tbK6aCa?KbRz-``&X}=DmX>QI>Oyx&dy#$E7U(`EhoI&(PVsXyNxLMv4<@JW{HwxRRUHXtaLA zDnfNSe;>lN0(~ZbY8%Dz&Iu_;|J1gn#-nLkUIs0-9idV5X)fXVtNh7KcMR##T|>2= z|8%EJ9zL{%7d8zYVAH_fJLsviMUzoO0=V8w=5MYA^oM zF$<+n>R-_Dd~7BkZP+Ov1S#a>e8SS)2J<+>|S@ zvAGXlj@Qk(#VaqZNSv1#UOF;yLE<8=QvN_^LR4l(kx@C_w!TEURYAdQDj?E zXgSUtFAe#pL?fwpF$0Hp^$D6X>yua4cW{U9f)yQ&%Om=O`Tv{Z(c-=2zR(6IVZJh! zU{|ifc&XQ6mKKkdK3yB^#!bA+DMzok4gM4lH#twB^LNdp3GTt}uxXv~u9@r7>A|+a zoVC}c_rv&epZ&OU6W*Py$pRpD*bBs-cvID@t(_=KW6XVW6#~3eeBri7apU#KZ%6Z zTgp0u$2_;zlr+bDVYs%lhV=^0?#OND+QR!yY2uiruFqK?x94gZX41skwAO@}qi26; zDx2*kj-1vnv|f=&&FUfETynzmI%mfl645@jgS^e4`E1rddcAJ;<_65Scaq00)+Jec zN$uR2r>>3+;k;D2H#fn2dkOwVX#E0wI?-MApLG6+Pv@v1-Pv4MRaMaShhGXF`_Tsj z{Pv!|^WmVR?#aMw`{N#!TRJ_x=M;Ozw6_#~_2d-HAK>@(>FJMS|2XaF$$GP+-8}j! z^RG2szRBMyq~rf%?``0$EY7?C`@HQQmJK<`8aE4x2SbvL5_5yAqM`ACs6>f52r3#{ z7X^a}>Jc!KgtiA*bmgU4Wt*bGdXkX;WAo5<(@-Cq(q>gmsL>Rav}jFpUiLg8lo;}q zwlpE-|NYH9bN1fD@?w&IV)Ojxv-e*2+%t2{+cno*Gjq*#GKKRvyMM>Fzwa&SevQ{( ztmuwS#9LWOagG5$WJO@g)ui)qwd>)|=OfH>O0H69q=Te@(nlp$1k8tcwb0*n$Sy^WwG5QWAG^1ld{|9F{+0|tZ0ro3R z195cbbT59Tb7}6!ue|SphLY)^?~;X}-+F|PaiBAgQ#~^|)p(L!wErLRqAN!=zsbm7 zd@`$I-VE=LpD65&w%08gXwb#YoGQQCM0?#6c;8TC zf~xtT(_Z(`^iKK=;^>~w(D04I~8 zV@KZZq}{z_;ccI|oi)=#8tj&Z$TQKK+1(P9+2X@>RB6odiHwf=d6FrA$BFBcrezn^OjI$UcEE)7GW z$1F5$D-1>+Y=d9gqVU%xZ}>E)_?jCX9lUFNIVW0_lUyQsHp3&gn|>1wx^;!(X~bO3 z6UMg_Tn-08wf8G|592F>Pw9ov$uIJY#>4n_fv=r!&NNM>f)^bzgpL$~G;f2~s!Xy2Wgr8`@#vqA z=h|FX36Nmhkdk=K;FB1cPA~1d8A6 z<`I25zUIp7+C(vzkdSTQnsfN-`Nj?cey0{|FkjY<=S{M^5dtS$H%^-Dj1!-H@1j`8 zH)NyKm;EMm_1SW1N@Q3+d3y#TMM00d^w|#M2r@ zcRnKis{=9YL z#G&C#Od&U%9YoEQa%uMpy8mdV|;)QZ1@ye`PS#@`sAj<5NomCPyrAiIID zi_Zn;6NA~*Nr*D~{7Yngzc$`Ck!BISg?XR)z&XdOrtu*hkHKa7raoRhPn*H`RUeA~ zhzf*H{<%ED=iC8a!h2FK-z?w5Ja-oO(tHy>b*aO*fcG$uYzO(N@JQ(}>?SSKqj`ic z#iKmKJhGj9wFm4R$&9P#kxPhomx}~+@j|lIl2ehbCQt5|B3_zKpPWZZe#O;ftJ>aL zj^EN8&2KQWw-zn1chbY&2>eU;Ce7Yj|91wOi|nlx-){HT=2tGKY0r_aJbP=+nZoE% zo#u&XpDnry-CF-;>1DQQZ!BZF;f6|6Pa!sB2iA>{ET=lHL;bdYim-v9jOn>nt^V8!O2b&+FvmSN5btKG&Fi zG%vS~_StBDuRYjvy0LN=WuYDs^ipL@nBQl|z_PnrQE7hV{1_f3mh0rO%4*_M(Dt@;9RXlJLe8 z%1guTI^8zxuG13c$^Zo?_Ti;T@G;PvKxmWv``=}+DbxUil0hIXsJesSY89{l^ve?; z-bm{vjUngU$dQZ@p2Ld-h|VPQDUKeEimP~(+>NLKJPrq+YwuU^9>#Z&NJ=k!O6&05 z#CsUuK0Kmn=N#^j@F9%vFafT7!t3xYDY>P4$(W?eO*R&ODg|7}pQJQ;~tRPu4@lRK^qSFXhRoGeB+rt1aZ} zWuSSKuV6xge=c5F29lAUldcobzwiPCAl%7iAZ%>N)nuTQS|@amypdeuIfWp%%rB;^2eMWQN91 zn)rk5HJFo9XkH9E&3kT5sCLvEaa<^ZX!l)p{tK*M{h)a-Qx`tV`qMz2!PrU4DloIL zX8HL-?Wh?(E=}Zm_1%EMn~>11oBe9W=G!Q^YNy|aR9^C{oix|+XZ&W(ibr))Jbl-B zh+E5=`1n;9*=Ebw@EL+?*k9n>WQi(RKRu~J$9((EoU_8?GEP&sB2~WTyMPqN` zQ5-$$)600o-yF4Pcvl}e=kQJALl~dVIvl?6oF&;SjBhdiG>>x*-?e-QTtn zXTZ97!7U`;xxuUX@5)|3$D~Q5x;W?Jh36P8v`;q2OzxO$6{${PjtM%sHpjSi_Bhtp ztUXK3=y~|)vcy`E#x*M#w=T&YtU2$!N>9q~riHg^U4oMb!9Y(L>+RAN&CklnqGhf&J z*GGOJ+f~@aGCC)T9@gCKL&l51PRf)6df-SEq%*@B^m_c)vF}-sZpIkw;3)nVBYx~J zwD$>LLJy`;`dlnl?74Dn@!?71i%GAyn8?b$b)mBB%r6xq`F|ep`)8W9GzGW5mWlPXc zld%WETAMxxO|I;vN@dUJ^O*HF-{w>%nDSzGN8ee;kF#rh4;_&f6L(I<>6)M?$Ug9l zvf51gI@s|rcfd_wOkyv9Z>l5xLw}h5DQ`A$_SE!({+NAW`nf7yAoWX>-{(nX3l-h* z6<(Kr%-i?_{hp9?PZSTEQI$>jMZdp_J%A23V1U|78+H$1`lw9wMY9JGSd}GiJ&zQx zaju=0u$*(Eu>TG+kLsni(Oy8B_nEv0&T-4YH=GRQVhRo?^Q8F>ZCWQzJ?JF!43&|Z zO#XxMA?=VGZZF^+p>XlnaDU71_E=RD$wXR9$*B(|1I;$R;Gg3Ew)F?$%u?d>Uc(`vMF27RJ{FKGC;x4!3AOjBjhGe8Q`Ef_L+T@ohT}zPpGQ z#g!@YKd<)tuTRfH;~jda(V^z1bJRQ5Il2*q=E&sC&!!-e~9(c zkTc=}XT*g9XT)owDSxkiPtBYUBU|!1uR^wMP5DA4`xR_ir_Jw*Xid9cVIL%pZ2oy( z(fo#wdG8DPiLZ5Q%nQzuBm5rDNbHJ@x#Z5$7blyrm$cq%A&&?9IY%b$>pw@H$9)U$ zm67NUab~>$4>@J&g-0MRmDaDCY3-;z zNV#?%tsQmV=A7o|k6TX=&d@O{9N3yM5E875?hdV)!fQvJBoD46hd);)tvy&4mSb0v zcP|Nk^Fr&$EtF*(OhWw=Jv}JcG4~lD#xy~-`wjR>GUPskPK2gh%lN>(`U*$H8|O zal_@C5yHo4tKq9(PiDcFC)_z#zBPOZ@-gB*`)KgH6(f+}Bv;8kCGx?)=sZB*NQYcUSSJr*iqo76&IzJLzV(CG z<3Y}d_qjW%vyqXqwex{d{0=2@*-M-cJXJd%0Ov!xliI$fxcSNP#kluiG3IkV0KT1P zez9oeGWOYZA2pV-=L7cs>4h1q<7fTQ@4D+VGq7oFe(&&=M)U`5{%gp0)3!@C1?L0( z?tEY+WyMx6^-tQnqiQeh_p5x69w_Hm2oJt-&$q>$3D`3Pqu)n-b7nvqb3S0(Pj^zW z$K0fQsIN)x@@XH*X*v%;7Z5w9oEZ$ta@amK_k`bE3}iU3vsiiaQuHVDq@&MtPOz0U zjf5*~6k(F@6sEHQ{ca+CP(rqod#h;sS0UqxhdQUTxM9x+E*~`|y5~1rN06}>a&f~0 z^+9bSS??^~=kXpm$3X+1WWAy3Ycqq1pmTwt;YovUg2fih0yPh8v#BnAQ(b&WJLHBt z7kFnVT>RJRM(DHrAJ7X{OpfP{SP~)4jp&sG5p7)yY9w%?WkGoDu|0F&Nb~^lzSAH--Mw z_;OCNklaL`uw1g0d4D*$j(v$Ca@ZDdg-51)|6m=y9pF=5l5@gx-7R(a3gBz!n{y7I z);;0!?F663NWEOQf^XvEjvMSc4!-4e`1XYGX{0M(m3KXl@Hr=)jc(@wy7Ec>3zu&I zd>Ovg%XORi#ypt=7`Fn?smOKGy*rh2f+^(tF^3%J%3d$mO`w4u8zvrd-4v@3_z$-99dKewzrx zofEvTW3vBx=y3A+=S?;QdkW`OEo?I4hFxE1T@lH0e`Y%jYoY3^TQe+KwcBprRKc29@2 z4@INJp2yY~H;?CcpuLBSBl}oeq=oMnvv<>6vv*_5ktwY4GKEcFc%QX*lXmuQmR7Vr znq=yGO|b7vn`j@`tp}t(r1il6!#DljyVf4i7i`<=DY`e;vZsGsZCIp0xvtgW0z$}rseWSxog>s_C0g(!zz zpG;?c@_(uQ9JPtoClg>In|TkMlLP{v)+cXrK?XXB#D)K++RwSW&VG*k!{1~&&I(2G z-JY{aJIt;#-;on(d#zEV_aZ3S@xRR)Wk{ z-<)&!7VsgAPj+gCTc>=Qcwu}=gs0)~)!Wf&4dG+LtJU{279YSkAAH@;19aundL~@H zcJO8Rruu5XMDbK#o#lX{woZ}V?NeE&>?7W(tW#FdZ+DW1b7~8@`gO`;%C{{DGXGt? znjXpBxuvIa*ZUW>qod!hmYnhSqwkBf_j8V);tW6i>i1*ZNsgi?o%Sz{V(%~N`A?$9 z{9_YWzsE`ZlFF>MJ>H$B3}Mqm*l+OPNg0&W9W_yAoaVZ))83nCUM|BkoV^|GWvT1T zF=b$12XD=knpqR*tk0YcLXaBcQE29Msc$V^wB%f8?^@Um=Ulkx=DR<7)2&Mv+`h;= z_vcpd`gQ5n_%uP7Z)n|?;c?FOjL0cG&bN|C<67So$Bpx8ybGUm+80SX576POw>fdD zc655daVmUcC-M4u#M2yK6Ah`nu#}qXqOi#BHRsA+&o_>5M`!Zn^Mi$=`G2x=t4Zfw zaLRXAmIno`tt(}J>);jG(Gl-RzfkoGvehuB^kJ<%a_H);f{$cs=R}oA_KG4SX@7I) z+G4~%RE?yMR2x_eDUISIPhuWJ=PZTN!TbIu8B6c|KK2fqxe3me_he@Uj9B7A}eR{EmFL?Jjz?e`j0y+nIqMB zMqw@b4Y(%On4Ga4tVWA}P}XSfILQK=WcA4w_y(G|{)AdRBQLv{U; zsq;0J9|Ge&v?c4`XIV3eChGZZx<)bRqZ48JsB~9yZR5QS_a(aH_s7;rr{;~ugTwnL z8i}Iu<&NNMBQvPja6Fj)HBR*v4-StT!=K^7pIEeX89(O|=EL^WATL&)zf@lAa`+A9 z$7*lq9RIB6$A_cC^W)1%7)oyJHFP*+K!n30Q28462?DgZn zkARQ3NI(~leg2NuBadBlq21;`h4J6=|BrwAK4=8j^f6IG$mzEskSjyZQCRS4xbZJK zkXy(T9{=p}g*gDq1;0cd;I8rga+Ytu)^j(}{>k`2hB$7F@OoT6pf!1z4``h?93S`) z@&3Q&11wHz&Xv8M4{RsE-FH=F7Y{yAo7uH6JK4JI!VAwkWxF*!V)`LDU^FeHI~mdS z@BLxYf3O&$FUWuC;H+=JCrQ}VTB_5tSi2da?_=YP5T%IC2b+R?wKblRK7RmKx9 zRqW-CdvA4AHd9=kUR`WRtu21xeXEO+)T;7R$N`ceqJ_c(kwRe=a>1&|$Z-|sfTmPa z>uXW=j-)H-^<~SK@J;86sZ{XW$ve{I@!qE@`Sj|_j`Yq_!duV%|0|2BzOHIA+f{Ag zOsOHO@^)2Q3SHHaq#a@LCH>9ZY3QZgz14=!OG!7qIMT}(WtUHBl_uHQUB&iVlj;=j zJfoWIIfL)l89S|Lo0k&c-^p){D-Y$R-=I*LN7+17W^4wurEY9}P2XL)n|;o({I%5` z{+?2F{ofqmY_XE@*Hm`+J1HxAcj@kGoJaRJOgM5^+zb4vvs+&a(yy*c@6Vq!`Mi$v zFSu~ZMboBVI^(j-)p>*87TkQx!bP|0Tl*cH)xRgu3sqmL-y)QGN9u*r0Oz=Q){MGq zW6lfJ_WtLn>zoR|CCE8zp)$3wu{<(YDCu{@^&8?7c+xzwNic<{gU2uEx5Zzsj(`r7 z_MP6GF{rj18?{=ayKk~>JEC)L5!tAzgY(BJocTrkHRVRqG(aC-&$?>7bDhDNEUbHR z3U(`A;rHUr?`imJipn#BZlm!1tu0@Sy3l>bHo`gn^Mvn#29Ps*y2_EB`^)L{rR5vh zdyM}0(Leeg^tl3As~h&MXG!Q?e(CABuvvsnwc+CkI|4IOn11_kIq^>RI6NnUz2Gvs zGT=Q?JQtRSIk|ViS+-1Zgc$ezAQP2)KN(d1heCB${C(6}-v;dW=WHAF0=vk67inCW z^4FQc3_8^1HOs#1yHDHe3_s$(JP;YZs<=#T$o{OI>+K5NI0#(LcEF|-x) z?AZ4i^NgPubS1h|oMgJEIu5$PI!lF>+n7I(N{{yC>KgC}ru)`c^1=yBdt)olKx;bx zZp=Vu{?1A)RVeLEKUs`|GX|Z=R*KH{J^!WhA4I*cMZ6W2yQ1(LzqiC$`WVIlwVp>E zc!%!tec!6wMxL>JkiOWtv3!pI-D<*{SK?08=iyUdQM`!1`ZU>H@i<#YzO0q!59`Xa zH}iB+V=walZ&3!theyB{&PhYdl;!Oa@jl9eJ_6rOS-ceEMt;hj?|ZV+5()OaE>T-( zOl40iQ@#jgi~7Xlef0M_H=g#r^z)~`MBC`BU3q%xo6AX4#+R#c+H11y3qQTFtlzFN z{FnVOy1q?(VBB%S=Tj%n=Sw^Me=23XF~M&e`Nc6BuW|2@>Hzx9;%5iVy|g)%zo&g8 z(1q$5p$}HlhF)r8btU6h_4e}U8~9_(vT=g0$LUdj&1q`KF21!GoL-yJt)?E)%%w%q z!s>|k>=fFigKy_}-=$Bpy8qV{!JdC3?W8&9oc@jF2t3v6htGKM8R~BM40*Fx`)mq2 zQQsje)Y3&sH_@Z~^veiu-M(;|KOs#EY4W5glO~awY05&MJv*51+M)+fi)V-C_aWlM zp-+ZfpeG)x%OeT{Z=n04GF?-m4GNyWrqA6z}(mCw=p{|KLC~?V>c7@;rSL zbgr?I=Dws~D4j<-<)d*O@9Z5oCnY+)t~5t|3cWT0bvLlV8>F8H`KI^{$N`ajP>x9s z4|RyAdk3I{ilKunbN~>m5aNCZ5K19{OBo>ljV1H+9tbQoPo)(Lu^!>*(S~&F?U& zj_R)+XFXp!hxD5JwSRFo{j`j-I35(~(cDp}-2Goi*NI0ZS9KS=^Q(vOs5{8>9B`>D zD#vXq1AP-uZyGRT2iiLO=+Up4@kICn!WAzG6)n!GeCNN8wxvUOt|v_ViG8p( z^~29>KTKi_N1Ml1{*!U9c9x!#`qT7X`swNfi+>3?DRTmT7h|4_!tcgRw_%HISae4a zmLcr@gr)rTmd89&O*2lXDG%!6cw>zhQO@rQS08){T;~#xJ@Sfp9qhfW)qA8mfjh5> z53DJ@^EB>Bo#SL^uJ$w+LSTMUUw{OCfXx^ z<T`B0{9)jarnifi;8dSnPM#Io<}43F@KffIqG_) zt!wTI>UzEIE1SB$`W9PP`XL$#@i~8El`{oX&qPY+C_z1ymw4>gp@)>kH3eD{|D}JP zZOqWN$}js!HAXtsbHxS6ujgMJr=E+cXSjZkiH?V955}5_r*fG%w1G?adis3tGe3Wy z|JLj1^W6DCK9N+{F@1jZaoXaYb!{=@IBhYuF5b-J#2Z}~?<&Qk-6WfjgDz4ZW9^b< zj!tW>HaI>E%|IvHT2zNQl@xt@mgp8*adNw(8OafDE^svSuRjZo4d_MriDtCsbL#=& zn$_`WRbxV9P2=LCeTCB3 zf$t@rmsyTH$Xt=F!kh5-ZLDq}tj5bzy#xA9M&UY`ezMeegx~rjKjcp{Ph9mg*_vbi z`0MqRZxd$bn#`sF%`ZEdi{tc#=Hb~EXSi%;-lJT15Z3aJN8#~fE3M3tvMZ;#y)lC< zl-^m{n|Z3JIX;jpMGNb0w8^Ec$+({d6J8KX({H#rN zGja#>xRW~;k*8}bGk4KeYBT+2iK7QE1#RVPa!F|-d1UzJcwENF-0Q);zS`oiKmEod z(9PL{>tNaBlPt7IWmEqZn6KU+D|2tH)Y7xD>h%>W<9e8X=x53631~RL9nb??9uJ$d zW$1-FiOh}kvq!v?eeuXiomm{5*m!tj6N&Op`6TVSZx*zDwwg2Vn(c=7aq*xd; z659|SQ0Ka3g<1N`K!3XPIF7QV3fTXnY!}d;HQHdFmyJNR*V*(vzr88De3Kfog?G$c z!0#vU-OFyQUO;`tYa5|E$rfp7rk*E`C643>*Y-y8DGFetLBO1k$Ec z%nO~D7bRCZdO)5*E)VLYK5%`4d~=%mQhlfUjauKEdeN4TDj#Uuq|HA#5b04r&nqSJ zg|CRle@1@(ieQh`3%PdQ({;|Tb2^g>>m$twrPpsR9mnp(^ih5y+nks^GP?>M@{6BF5yiP=pvNA*Nw9nq#y6Q>(&`Zdls-ual?YS6_8 zUwPBHyL9IU9UBKBr}MI*=^IV_ByAkHAY6Mc&M$mN+$KBe!!E{d@6h~4um>MFC5f2b z;K3ByN*WqJ`0WG52;wt@LoQZl9Wln~z}YrjbfNwJ`g@I;PJ!0mT_Vv%>#(nT%=HL^vE6!#c&jLSZ8 z>uo`%3I@-DC5vvk^Nvs82?7S6Y@)53)oF1B!qg*gigz;PT-^a-M@wA1=KV7cQE^yXT)92Pq+&G{pB(Dz*y z&VrT6-)G@o3+FMZ==%-}2P|xcG3$HY!aWxDuo0mAw+S*HlQ7V6EE;?Z4+xU30J9r6 zo^lEjE(NV9>^d&UlN1C;v;Cg3kTr(6r@#<5I<4$68h@uCb@};pT*JKU+@*IeT(Eq> zxi^K`(77<4N#}M1$`rv*uZ4s89wZ7gNB1qvB!6jITRN75#D|=P;;lJ_$(s?*pJfArA`HELK=Vthcd{B2}Y``x1T(T8i$}AW>%5OT4l27K56F+!g z@M``muEKAzuqGiu-r z`Q&y0A3MinQPVvegCrC2?yBVYT}{S)(+>Z|lGcnqzssBUpRQ<)dNdm;>%0_su8H*r zdk4MPx4VY>r{0%6-Xl75N_Vlozf}9CtP9qZ<9=5)!MY;H?`OtYSGe^h`*%%Vwpih} z)%K@!CQN+gL0dKnC(V0yBt3_;*OWL`Gx=q_uJRP{O(l=G&%Sud?2lA@&W$@#K|a&7 zm1>-Dk9a0ea7X-0%i06eH-){TJgH|y^-Jj-eYWiEG-dp*a*T6vTBb?moNCI%+7umS z)kFDEuBIvajz2}6be^m;<}_!?p4PFPC991Zysmu;mrWp@lRh|dY*D|#=d*s(y7?^d zL<_99a_qbGV57g2clHaZ>wXV>rkyCe+ANV?T~xa^(vI$Y3AUoL4+?|;R;w&nJF0{S=aotsE=T_u9w?M1AJjIFlszN&U^8G**){zC@$d)OQG zc#ov7t9q%I7>~0{>;bjK(|m*9M074uSjSkupRs;F@djz`d+?mz-+Hv_XzFA5wI{E% z%nR&eJyc!(HuUtb5uBj*XM#oq^d$wU2pKV{5&cJHt=TmCKj zeEImX)!xx#tB>bjENy2l@j6#ASIjFt8}lwsPoxjvsTXh%tawTK&GR0t#yFP}|8VVi zuEn#`(9G)UcK@kTFYn1o`R|K%BI)k(W$pPT z3c+uliq{BtBQ{>Iqs%eyp?wqmtICo7-2;*IGcq(**{!#mr(+mwUjN0Z? z&N%(eFwhyR&cw|Ar0}VqH4d(Q-&N%XXu)HzP~Rh7uEKs?>HXxTHuh4RN{#t$2GYF= zh9P~Ct29x^7-Na=MUxNl;^-$f#3;vw=8vje^n`rtU67YdowDaC5bsR%`jn+A{;(f`+TWsScZM?XR zr?Z+Kn-6_Fq|JUzm}|4Vjl)FT9+{u|&`{?P=-~I4BuWcb^)%a#$)%eH_c5K{m$yMcR@4SlnWh3&L<~+tJ z{G`d!jNvDY-FK6x=3jUV(`I)9y`nb9ldiY8wsWSO0LS&U8{-XNC{Wb6!=#ToU?y8UaN_<0Y@&oiGH0MKCK8=Lqt<7CV1vDM9yvDLNkd+`L%&z3iX7k#oOrH|(+54IN9 zQh)W0`hc`1Pi!KZapc-W?ZEFa(H?Uv-Jc&@Epi^&0}kc;kI_EbIM|>7V*=3LGe*RW4+P88~vJD{} z^Itjl_HR@o{m%@X!Snw`j6bElFIuce7#|6Lpjcc0oARCCsC*Ouz~sU7N$UM1V?ptvBi~Z_x)}r4SE5VqjUkW6B7A$x z?cW&lSK!rn9z}j;PVz53Et2Uv4IW>H9#8)Z(wn-CA6dD?vSKoSZxNk~qGTYQ?Mjx3sU2vayJ>@!tDpgY^MKk%ZU6NnN1M`~m6K_UWoiq` zs{VPr6FE79oSa?5{BT|A|FHidnOJpcsLfsXmeb5pYLk`BTUxJ7Ofg@uUNLtC$6sUk z-j~Qn>3Z)XPWqa11ib?3ALS@d0(xieF7?pgn?FC&ta~E)d1YwV$S*4A-H~98rFl$i ztVn8g(HlJ*+_Nj6Q@j*%j>lRnC7JpDed>#d|I9!`;WC!AH?rTr`XLoROY!+_`zF!6 z)^;_$R@Mj|>L=>ml)bm;b*`y?7dm7z8{+=`=-{52+V&qAUyjB&kgCzxZPd3WS7oy0 zx2avh?PV;DrCusUps~}fJRtfKovH2PsX|HZsWFi7;R9*pWpo4#Er2Vo`oaqqNngRx zNqBzfKApW#)9+`g-}9|y(fd)YRXZi z&*Q8q7>}ifENOhoLpdS^WFqER^crP1dQ-$tuJ+X4(3}T9eGmC)jA=Z%^~EU0RXp|C zf#dbhz)z2wy$10LrBT{AV^V9Aqv#*ZI_pg2uDPYpq5mP8NJ<9@nK15T55_xtO98!j zYpUBbPnRBr7PV&h06akON0dSE4E$RrpNVWVw{+hL@a609{SN8&*mThCam%r^F5OWh zCqGz)e)hMVcV=}ZV^(=DJ^_ve7RO3x+q3og6Yw}*CO+nQPgTFgx6RYW8akI8`ylPu zfE*j?dk(dtpFwEbDgGmiJfNBY_;dnYNBH=gp@*>t$Ide@gDW_QQcJtGydHYe+Vz^s-w;>nBwuQuN8e`s^yn)ZKMOmc+w_a@&X>Nge7=BwY$Saa z^dWj=4o&MSFi~-~ZI|AgxKHgY<&yTjq9; zJ+FA?@^WH!S26By2hXOU-t5gLWK%u2rW)MsE;2T*tB95_{3&{N(6h#`#@=&3J$C)t z0H4vip1F`b=T$W36MP#>I*)ndTbiTjixIXD)b3rZB_!)KX4t>`yylFt)i;Y4Iq!FO-G z>8f(?D%L(c-&J1I)ci^ z*fkaIt{t-nA^kbWGr#&1=;LFpuMvNLjB&5EY%J4NjAbuFwV8Dq^?ZQ-Hfv()#C}<@ z?xD@Kzmf2{(?|S7b~SX(oRYo2%KX1y>#~PvN3E&fMt+|6hqZD3MevEgh<;*>Gq=x% z@>g4wwDIg``Q2pp1!>D}+CF32coVcyG~?n<%B((BJk53LGsP8MEu)_dpFkE>pX$5o z*C^!?Pt@8j-nnT&G$-CDy6NTlq3{mV$J%?+9N#?+enOtYxrKbTPjUR2^P{6j?Y<_u z>vmtWMvJuJVaA;1f6F#jPOA-U@#U?O%1#rs_M<)F8cGXXx!-OK%bQgy;==GW6Ch9CiEQON9sgtRs%0 zwU3+ry+*cgj-fU5jGJzu{Z`Pv3F@LX`%U2b*Z(}azjxZPW-^=eufK_&)IJk>MsEV{~~ft8VwMql|`v{RTa zyh5-pdB%Qs>rK(rOXMRyD}Ed6v@)yZx7R`=aqao|_f_xpgE8ag$n!-zc5H0{uiEBM z=riqO98y?zb2Z}KUAdY0=uX} zr}RpkJHX3~QK_!@+St9aan#}hfXF%MXC}M!-4A`=W4=%5I_6i$E+6Gbv*tG`t{ydk zbG=ZSX7pc9tm}Ds^T>GY>_}7do5IST(w^F3S5)XshC?UR1mKHopAU(5rJ_*`0|k7g$U|5E0o`$Yc{$P z@}I>s^jGB+A1)PgG3f2>)-Sq}E-2@PHK%OPvp&(5e&Zrz{Q?S~S?9mb`bBg4eY4KG z@Q+%*=<77v?-O<5pRV(-uJf;}^Z#+3|4ViLzB>Q^s`G!n&d-@&&8dDb*L*>J*`%pC zh5xYT3&IcA`O#HfcFTf0LaM3@mMyyVwiV}2nS9|z-c8HyzT=~dmP;uWb+5Z`zWvUn z=%b>vx|BHPmpzWrNDY4EZ5fKH3l@^h>ar>g8mcBMzDkYN3-nz*tKACPKx_4;+i$+< zmb;gt4!c6Bmn~Y3YV6HRm*07hEygXk@GBy>EdOL~(M=R^IU)Lmjhk-z=#o2cUcgU` z7~NMJVt!8Uwq^G$%PqKtk_WL(bn|L#?|Tbr6Y0IC1yK^4A_(Cz2N^xsZtL$Cgf0p| z*(cj-;bRtVvrv7i@a+~pVc`x7`z_pQ;VuiGvv9YCqEX@5YvHRF7A;g?D}0}Y8YA)_ zwD6FH>T`WRVj%<1_}L3FFlk}4g((YLENr!KoP}u%Cs@dSg26M@9nA9y-~`W`Aoxzk1=G*CccE`6 zNV*IHj$l_3NcuQ}kJ8N*B;9gB(iN=V=*xn?yNU0lD+=P*d?Wgl-mKt!3p*`bXyIZD zmspsyaJhvmEL>?}-oh>myDi*cVULBq7H+n1i-iRXw_5m^h1)Fbvv9kGPgp3uU)7`E z!krfGvhX zbW4}m@SNb;>?Q-1en9YTFk2Kug=dN&-@Dj-()V40d~XGZVAjH33!f8Y9Hm=;jH8So z<7mF%IgFRnfsErGLF%#7!WrnN3f~67R`kiOzZso!ecvfa{6iMbAdc`I6eN5KbD&8t zNIaiMaK0enn*}E_{sl>sX08<6E=c$R!S|wLta*mK2{QWTzV&wq!ZT)C|13dx!%FMV z3qr3yr#||itTJe^eu%6R`dpJwLf?jpC{7do=CC~UOH)Pvwb=txUqpD^Ns<#Kx5ou z3N8uB07Zr8M2dt&i?7w7gHtL;3}A4+rPbR+ns55rj4f0(h< z4I$|{5PFxtKm)ii*~nT9W0613(_-IO09O$2WRJshBA9L%%c)lae&*5ui}Qf!6k-OIdGonUoclh%G1(ndw}MOQSXp&e&iA&pL-m);!M z3InEd_ZeGZva@7tO*wm5gvAN_B>APx{DO_Q5}ov6uDF*qG9ok`2CgPh}lyFH3r8oMTnU2VFqM8a5cF zkgpqS4bi~%mFfszZqi;pXC&+&qjyPK*~}W@t>33KvA*@YH9ljcX{BBAq-o`BGLiXU zQGIm{Wl7A|xhHz7skKGnh-cSVz0UQF`yfx@Va@t%+&iN}eVXd+fBpL@*v#4lZ*l#i zwi92f?;rK+9`=~io*BIvjUj)w_a5HZ;rBY{<|B610c%Q7a zKodGMXt3izd`x|ZZLQQTobjF>^VaFCcbw(PdHO;05lLTOj;FBajm}Af&d4~okbUmB z|M@Cs4i_s8G!{#Y&lfpALNx%{7dU&b*~IH9L}>HCCSFfr^qM<2p4NQU z#?wb|hKSzH=STS1?jt|-h1#s0{ud67DdrwygKmPxJoR6p{=$|E_EH$*_f>r2&v-xg zg=j0yfsu^bFt9`Bc^j(}Df{!J6UOL@(S{QDjb*mj2#W~lkFJgA=@!$ z>nwzJl`gj06@F&gHATB#NtoI*Y^QAJe;xgr;;T)KtuWrXV^Fz-xUQ~`qpzAa?Y-Ib z-4w!f_9;APlaKCgIKCXq7gl*ag*86*(}0x`58Pk8zeoIg(}3Ue!6E!R;oVS5^c22A zn$iSto)gL=I4j&-%~O_fgsG4JmNpWddnxS3d4p$1>X+*&gY1c22G3C6F$O;W%q7p1 zREB^Su?yF;vHAzJVZ9wN4%&=;EJWK^be}9kIZ|I6-u~B$zYAZyB{oUHw|5j|#8doE)rQB)Z1%YVN_9y2*Z1 zecdve3#i`}!_-aon_{7QO+|12MD<#IoO(e^ZQ=T?fF8V@#{HbicE-Kz(1~xd?a?;Q zJAoa#Nj=66UEF_{u|qfh1Az@XFZW1QbQ6I#wxVmZ_S_TOqEmWfi;i@S^mDx}Iv@Vx za0~ChP~PGC>nEHat6rL4KBPFzd#;|RLW>8#G1ynHmlpqtyibJ|H(;MFlIl7xEgt&W z@U-}}t(#;C)o(xN-NUuPU)9BX?KtuNye{646_57PIzV(S{g6!7%s1#69&49u=jnl6 zvJ5nSmShlkhLKy~!H%wVUf*Q-ipngyejwaV)J6G;uA{`&+CyVDpy@eAc9@S1H;vV} z9k>5{oc8&&tr*EuYXXxdO%3^3f z!~AhbG67}N{32UT;^*<1@Kqi&S2A8E+cXNFWz)?ho#M^l*@-PNlMWu6@C&8qOdFq3 zxzWaD;yZ30b1m+3ZCsYuO_~#(ttatd*?L;d`M-}1H_dsP6X83<&U=Bp)X4l=KxCi8 zTv`|tWe%H&&DV&X6S042?2sLyocqvWcR1-EXdC&RJS2~Rz_igLNaQdQ6Z4{?{BvYuZ)J~H1x_)-_%g)xDk;9#>H`-l& ztn!$?p*$vUzAJC_joMjraOBhXRThv}eO$#;9cyzQv;x1a*+tX(L9{Bp$`lVa!DF7k zE+L)xICq;4pdTU|X_{+Vkl9+52W^9$I_?GZ4oH_mdXJx{eUJ@Joj*fMT^o{~q?&da%is=S~shRb_BA-yX8TmdqKQVPqik_n^y^o%g*PYJP=9bgwXfMLF6J zKgJFlx+;};e`A%owaM#$rFxWmH4VjC#kc?H&eETiDML|o^*a^r!#25md3jiN$dY~| z^5rYiccD!s>w&+p?zANMO*tw5KS++C4IG~zNnO$fWQ;!5x%IV{JpG*u=9Q1rPNE-2 zbI$IX?g&mLKjrbe>Z7*S*TjD`$0{G`_=y&jR&-pS-pqlNZ7TRr6z_JzvD;R{Zrd?q zT>3al>uBEOflb-X(l??kroLJ3>=TcEMxF}jqq*mi>ifaV+N>NIJ;*n8XG-$eC}^qK zd!$+=9c$CF=tXqV%=1I#nNpstse2wU`f*Mc)cUDF-lEqd+|Lbc;XhTnkTlwha&87M z-8|`E@X_AcFY+{#{wNM@qm`qY-{fWRJGX`NkrV6o%pBDpk8O{o>v{dXGmxvDPwhC2VEI{zJY{@d&P+GBN2ZMV{Sfb!p4 z=igB0N7v<^LBnhdy$K6EXM3n)%A}fMwvH*2(IzoEVmIAg`^{*nuh`VmHW^}JO{YvX zGj7&I+da~J!QR?Ew=9$OwL$A{H%pVn8D$G>s?jwm`dw#ZEf%t;WBlVROj|g?!gdQM zT8Qjy;&)g$#loo;W-Odx;YS(vqOu7&d~oNr;Lg$pfQY~d0Ma~3YQaD{~{EzDck zWns648!YUxu-C%P7H+YyVBuB^AG2_qg?$!ox9|xIcUahO;Z6&8S@@iVyDi*f;a&@0 zwXkU6fQ9=kJYeBL3lCX%*uoWBZ`{J9h0PYGEHpONh}UZU<19>DIKjep3nyCW zTWD;mk$#HxPqi>(;S39BS~$zXtcAv=8tLa*zs}24?oJCATDaK4B^Js?i{dS}a4S$Y z%bu{1Jv3w6Y^sIx1zXWcf-Rb}>I9H;=gqJkojFg1-N+VN!NOLA4Ea}Bm>n7TrBk8r z(n%1ME`gwQ00a+OsJo@|Z_pV(=Sf=xSpXFUIg{6!{y2o{9t&kdP5$MAq&p(W;<6py zrgY-NQOdkQ5F9;%u^by(baUn@sO8|+sl8=QO+rj+?70<rC1*DXB42WcC(oQXDL z-vu1Ldw37W+kTvQpRw_jR_+k-<_53kzr(j4U$}g)GEOw_seJmbcq-o(9*Ug<7&j9l ze6RBWRVKM`+2mhAJn=Ef1-u%3!Y|yeFL?D9(=MCzVx7as5E&Bh0Oi}}A^}}I&Wb0$ zE<0%cc~hpCW95^d6(4w~$*^`-tl!?!9dg+R(|SRB$+Xieo@{Y(E*AIrjSg$uD_Bcq zwPr~CyIJ29E3)||J8Dyq%Vk4N_SB-_2-{K9dD4mOs3lkr#H}s0xV5E*Ee33fSes@k zw>HaG*awBf6)UoJc04<3@$?wZT4tB%_a>de%6?j=A6sXsLgkWlU{fv1`bPO)lI^Pc z{ee9-)l+zt#?)PBM8t7+)D)(?^&9f;?AqLgCNdF6^L%wW+jl(9`1BvLf z8?XtsCbrODm5Apa8raeQB;Cw?z0N}EtM;sTM22+`X*}*o90nG726ztgG?IU?R?3#g zvrq6&(!P&+HPI$+9i=rk3vgm6FZ_KY*=|1NJ-p z-K0Bu^>(QSyrFifT>q~aCV%!IO3*~xzRbw#z6^Jaa=inp=ePMbzzyK zu5eg8Of>A*dpqTG-*yfY?!p8oQty_!x(~p#QlxYFPUT%T%NFv?B!-m%W@keM0|KHBNQ+SKqM79(==|jlMs`ckPKdI#R!?|L^0wqZ{DqInpiX+h@S> zG2VTCpCdS%xv$8*==}$=YbUyv-7fQ+Bxy_IIqvCXv=72>nqzyao}NWdS;o4fIsLv% zxID#NP#)R$`hA_dv2QclPnOZUh>eEUiA<<`E z^f|BcTjY`Vtc`+nwtSHC-NSjNsUx;h9?xO3fjg}U#@4rEfz5^kY0>h1n?pH z7u-`nL>nD}zD4T?$zw#%n&NQvq921N(1o1;$@L* zN*;H7Bk9HmwKw=>#;y25cs!|{IbLnpT~1=_L2(b}xo_1ovZ{T#bWdROA~v3_#b;|rOOFZ+eNr1t+v8eU7PZm5xJohso4$V3_Voqzo*VlzCEHl<(zZ>HsS0AkHU7~+mBGU zcxFvB?r%!yJ2YT)Uz}bQ-?&DNov*s_$Xs6DM|nq5he)=y{5Fk8>_=!mm{L%EUF)TdfsQy->2 zmV7M+Z)wcTC?-4EyX2fj=fo^g_B$GIW07S~TYR+2);*B$XBIDwTvwt^?4A4B71{$b5;4>J%x81&W)|UWn(vb0$s&;mUg5qoxF68 zpD8buS>!pT2p)t_hT2cRC54A0x8iQ`;ll+G7oCRPj;%l$2qRcuU;1aOX5o|MjnbW*I~D+ zwepsYyT-gk8DAjG&AIDjUx&Otq;?SBT;lH~jI1 z()Jwd5YlPR)fk}snTvO0n?i6^9l7kNW? zqS;l&Saxkux_=RVqZj*OZJN_%AItC$+B50R9xXZ=Vfi9^j~5@oueQd9NL!fhzNs@N z=34c^yKEn^ry0nUoTW)#Qo8>^8`SzIpDn|f&HN?2k0TFl*Zh@V10TP>bf4*)2diqE zMk^0VzLY$f%pwmVH%QJLu5VJGO1>6{mPcfU@;K8MJ%!S@D4Xj33i+G1qF?@zw%0k> zh!kx|JLJLzJL zGx2iivzYv$)kjGq93$Z29<&*jWu>=P>|u@~zUDsBR z8kW2qwv}>?tIfLF&U+7-eS%}{oUONGO#SyYc#X!GY<$&^G121%b$xi3`Y;83LSK(F zzP9@>(1)v$QLi^+?Ls@onn%-*wJ~-d_BWp_r74%jSZWpXF1Uy7OU~P4$R(0V&ShRw zducpqEKQ}|kv)uUE7^Mqk2%@Fsg1XAzaf*jeq-ynP2<6{{l=9j({C-*CG{kALcR%P z`sqcDv#9CAIT~*luO{Cpc{bA*EsROikF1q6J|}|5jHmqSqQReDW908+cn0Z55m)jL zOH}-jbL}cUA-&K9m z*tz4k=(U{GMYF!v)Abvvn)8HHdsFIvC$C~3b-&gH znkzkQVQ5`&9^cHK4z?{+ru!(9^bsUWeu}yZm)1s&sY{E~v_2Zf4suvl+?8T^UlV+W^shU8}Gc*OAWA8L* zcl1rRXP+*;L;QAK>uX6nE)clQxDdTdp3qt^OlzVe_yP07J@EB_??A&%M(@_ro%j|u z&JC>zkKV^+xwdj1bauX}%MF#gSX)ixeGhfeIM$fQE=*7l_Ag}9sxed#*@aOZ z#aE17vfR@p>7KSs3fcgD{^Pd6{JJ*SMH|er>8?FNx~uEbeM~gaQ=re`wX{j{0oHEQ zMpn-S-xh=K`qDIqZ* z-0P|3o1j0R1gFwzoW--72BM@_I+Z`pv(w^@ufiX~%N)30<8=(QY|27;<9X8aEt(B* zXbsHop6-uNQ@sXlVqy2Z?V!bL@>RMX($V&{yr+$3b=`oAyrROt(Z%jVAB>{Vsc$Mmy)2Q*H3_vWuEAIV_T55L}( zr_1ZN$t!|f{v&8x_IQNfV~*H9=1e1#%ifS=^?0gK;_jH4FHD=zUMjQf4ZT(QP|o4z z>y?yC^L*SZlw_MnbfI?9e4;k=us4}N&i_qRAi7-zwKG`updx?W1!b z=Q6y^u=ab>?j!IJ&&)xaKhZlzc{`u^#<#spD9)ZUPNvf%dp*%5b>@1!X-vRxBzrxq zmqISieskb5fN1UHFZd?=JwxL+Xd~A+wOO=wA{l&>PR`KyN$*_*bw+}4o$e`I``m#G z!kioOw z{L(QB8PvIH*{#^m2`twH_tVY$goR%1Ub#O>>PBIcIzue&NbSg(&8Zo(8P0x=Q#f)q zbMCnX%Q)E5L0M@S%Q`mHy9xcI<#!r0Il-$jj$=Ls_I+%)KDSd>>1r$#MBrW`$l-st zAe#ni%W+6dML~2VMC0!FBNZ+>*8Tp47B04MiG?`}ms_~P!j%^0E$p(e+rkYN_E^|! z;bsfBSXi)dtA&qQxXr>o3%6VNgoQgS?6+{Ig}W?dPsh}YJqQE$Sh&|h&Kk`3qJ;w% z?z8ZKg$FG>WZ_{8k5~x9FnHn?vW_?YW($oD5$)Sz{jC;`voLMp1Pj|OoM@rZAtHT; z^-r;Is)ZQ~XIMDX!dVs?9U{`twf=b)&bP4B!i5$tws47sMu&*>%dLNfg)1%0Ti9h` zw}l%l?6I)d!p#Q zOOWu*7WUcisYDR3OAtJJ1mDg$;9cqW3bLs;F3H1tRuI4LJS(3i@OQ<3LXdFrdyS*r z7VfcduZ6E#ShSE$LKACzTX zu&~|2i5B`6c33#Y!l@Q!ESzECObca4NcgiB&b4r!h4U@!v~Zz?i!EGYVa~$k7Ot>x zrG^;SLM?E!=70E(@QtaJPkf zEZl41s}>e59I$Yog$FD=XyG9X4_kP|LQU^#XW91|$2Zx}5xwpcOvB#=p~n;oL$Yr( zSMV(22|};!Y=|g+mmu-C2oit0AmijY!FO=ZfDom09fG9G36kG7>o>oD3Z5(ih42_% zJ;q0u{N%e+ko5WuYm+YvXXV2wkr_uhLE#ewKZ1vupL{{SFBIgvbo%5!V*Qevq7%4# zFZfRCBgo_1@5XKq=~m*`c(fD8wB%g-oaz!LF#PZeDLbaz1!}%)w_Dy)!rQo?(kSaoY!&w1s6`aXu-|5 zEL>!kP=nv5O}});WtR&{`yJT3d{5BE((h~1Z+`Z%2gClxZ0yqb+&}UPcCQlqAM^0X z*xS(l!4ChQN_lTgWiI#JXi{`%K3CN~GOL~dF+8uh8X$waHq}lU#^<_QsBn6%^2)X>dp5FP(!d#* z$`JAQ7<_+bf49`j6e|<>zRZ6cm^HzlF|k4?s3Q3{hqGs+*zo+nttBU z=BwBZh-3<-iK&g%EYD1y89eQs8~Oca*~{SGqd$hKshPDN!&$^da?AUuJoq$uon8`Lve5m)3n=_T3#_c+XQV_!jhW4>ag!u^WINdtC#Z6QRp7 zrzE;qmV3S`ULEn4SI$JgPi-29)@tY0ezrW3c;_}!f9lzhrmmDJ>R(!X`p&0Ix|{81 z!9$%UW+)%eOr9A$H{0^5AJXcruND~;Q|=_iZPPR3sj-T9Qp9D0h}|Mp`Z$JEO! zOV9&p^gl}<6~@pPv2o0Ub6W^xm2FSZ*45AZs_LkSAN>}oc>*}hoQ5qbeK&Lx8q@s7rLmnNp06=3T`skq;-zdnSEnCSzHpuPc0SGB?jUaD zBTpOpQQxQ^RG%5pcVn9R$c~QDqoXdo=Tpy6muo8HQX8umLw~AQJ9UbrPcO?R&m-ic z`hED4jb+)xi9v6djDOyY?RM&;_Sf&LiC&|fh0ilbeMSA2<(bJdgGb}}2xktu+x-*j zq`ECu`}vO~XxG!DQ`f|>=P(A|h9A2C{>usGxabVxy87~)cWtH}=+E!L7xgZ^dU&;Y zk1|eQhK|%G=~U46rmfM}e3Q*{Nhr_%m%FzCld8P${?EMaF3X0Dyaa+&27?JI>Y%8^ z&^X|tq>^@oRY|gmi=ZJ1iCe{lM4Aq;$f}TR6dOXZOe(h4l6Fmqr73Aw!MHKl5+x0> zrk$6aN+_YEwGBy4c|PC!{O;Ld+?AN8|Lf`XKi8i9&V9~(?$_Vj{f;b+C5MPpW4j7t z!a0-Cw+{?VA}oco>mAP(r(HU^vWhZj$IU#KvglbdB||wq46Rq|D!Zvx&6kP7E7Tw`%X zYU27a<4AX;e@NXdD&N9*REjity8CC|seE%a{);@*7<(lBUG@rMk1zPr>$^w~dM3je zH@`S}uk>MjPFJBTbE-akp6@e+c?;iukNIL5lS|u8w&vb485<~+*OK{?eJZC~c|9T? zJiCf87EmV|E9-~`k4Y}K$<4QmgF(4ms~;5Bzao1V;5U*%cf-dI+Fm;P{#E2;GON9w z2KO8JDbEyUa{T0qb zba+wcF}k=pXDEpt9LqDsy|E_lwQnHqj}dp$!t!ZgF5R=fd{rKYFP~gVpu?us=)-rD zuKN5aFSN%dN;fJjuOF4q%WBHd<)f|)eLmVI{Ay+RPUV9+Y}y}YxP0_-E{@I+n^2RF z# zhH?~MSmO2%a{C6MBO>VpJvEEUGn4GW1&=B`&I&C|%A!Ll^RE);P~{szHZp&=IK2}+ zpGPP4%5G!MB585+B!a;NfBlWn!k>{1)J~t=F#Jy|K?#wE}#k!0T4EVQUydnBIhb~e;H?44RZl3$(w`{Sip%?r<2S(XPWIaws;qV)2Sp32!yU*J z@r$Dk($V)B>>BY?nteVfvs#|Qe1B1CW4@f@<)D)^r743Tv>}zw*W>5kBi>VZiaaPD zc>CD^dXbG9O=*9_>&miGUA`4Zw!89mWRLWu@_r3z9x7j-t;yH5!}z(g#!nVM?S1fL zDqnp2#n9-x*A?FpWnO(Uq*ZJ==<}tQ8H|w|Cv?>)5*WfPX^nI{LCaRniD@M zD?9B*=Dghy`#k6DN{5K|oc)6R5rgioT=JaDzrJB^+mTfnebZJxGa9_uN;!D_g5C2t zZJRIa9nIO0pP)0*u21*q8o8tLcsLe3t1$Ep^TzU$2ZU4nxV0x*_5H{(<(c@2bgnC` zMgP_6G-&o4vNdFxl^1Iv`k*a%MRcY*5Y4><{pk5ImY!3H zWO4ajP3#aa=cO}MZmMI|(^Azf@kWq;oT=y9V^z7MwqDY;Eu3sqJ$RYJ20TN`5!Ucj z1^Ewn@Ak0j_+-iTA7!DN&X>_e`SO1;|7Ixp^P!qF zsXW#XqpR2-?38k2o?f+HGR%wJssqEhJ z9OU@Lv^$o-FWA_z#k5V*q<1NGaVKqU`!8iEE6s%;KXT5|`SIe%^*zp*=MZ!w29we}CAsdf2uGXJpnU*W`PQ@u(! zYIo9?;o6#N1517{Am5T1YFkZ;T3gfX|605MJ(P6@8qxl%Y8Qxh&>^l)WHvmO&Rdq;x`}zKj_2Mr*hcv${7A;Co$|E82VddbaJ7l#SMBX5MT`9QeG|TI zs`j)CFCDAy2iJo9bI)kAMycEDEX-EJZ5H;+qza>E434HmVU`p$%6S{HXG_7)dBrtFF0L6KXE^863wxl-9dj%5B=C34^>w5u>Umn zM=S?jLbLPxun9Uh(BGs!#P%2N=NtVd+{7~8VUI>>mnRe-=bDa|ypD8S9UWnMIOxk& z;yt-gudo-YWa(Y>RR`(6uW0ROtuC3C+r-}2p9JcS9u)pec z%Ja0LT=|kVhIw9`McF6w*l$_0-^~7ZZ3*^++m=>2w>ulIDV{sLxextEIu)n4K{Pkg z_m`>tvMtzD`Y5vHl(q!%sZAumvncNfVP^d?a2|8BR-v zebeguR9QA6vmC!srk@^$C$)x0_O9p4d&OUTFL@qiFTzNAj_WIvEc14#Y|@XyYbr0b zasGIS^71n5sOcQZ^{DkxC~U7Mm|!}jtl-@Gs;oGwxv!Lk%0M)`hdxo&eOTw+hc{9V z|A-8Vyem-(=<`YZ+NM(Sv6f?#GPLD#?D^aS|K%U5BzmL^LjH?Fvk7=ma>U!9Oe@$L zbl|7c&3AYGa#~AJ?dR0lwC0v>)BJkrmS`Vx2$~G~_PPBFkqzPghlTc1q>vwz2-=GQ zsJ#zMdS^E8^O4}*c$#!vz`l&>xrGJUO>X>ZT8?%aX^a$ye_M>_viGutgM4zjO?tkabIB!-{dmH^KufB(70j6qd3CVuC|mqi zY}B>Tujoj9f=XxAep-<~<7)0&9hoD%Xv?_r$&QB6@aC9wYEz~6=O-u9{&Zo8U+cq> z-yM9XIEH(F6*MS&;R)#Y8Yhd}V!NdKu~(oMWV7r4tVCw7bNkJ{1^%4>o!(=Vht^Y+ zyWy|Zw2fE6hf(Mv86f9KTR@qJFDIS9=xDryeHfErT`7*4`1vibPvM~j{O%@=vK#c? z+YSdv$10w+5?)Me1=IP5v4hwiWufZeyOGSgy^ zvfbXCT8rs|?H0cK`pHxjK41FP9Jbp9sr=W@PvsvT!TUA1IiKLg&lfh8Mv;$M<0e;@ z^8A4*PZsuG#G36XHy5I3tYtjyszO?84f^1nWQH_=L8iohG|#5l=RTTRP&%28m7>9i zXy0aZ{=n9?locWu`Zz$+_57&;t&RTzwxZs(Aa7#nwFS42CBHjJt7K{iWubl`WJy81 z@FeM*#`89w`)97Mkpq!;?JcX$=&N>n$Y&`-jYrG}Ri5I*`zc?^zs3yv-9RU@#beO7 zZ1F#UM?}BA%{%k5*Y;nrCSu4o%bl!a@-p>f@Q?VZe*A9*e$<}z{$!sI-E}=t9f6`@8Wf>gSh+zJPa*+8(d}N>G|eJNYA3>tD%oCQ6{xC9UG3OGlMjp`A%q~ z2dM+1JL)qWi%DZM;~o=9Q|pfA9!iMz?}FY%>+EGzh%p}PzvsJ%_8k!~sNWd9dtN%A zE>r7D-LB5|R`f2$m>grb_p;9B2zzBa{pVykV^L~rti+C%z7+izC==z2IV_Hs9DT@^ zhbBb_bD$yiY$*Pee2Z5^SGSU9@sKMg`T)MeJJFfwM|?Glv@2|lD|tEiQPOfj5_v&6 z-;sQ-@)hXE^-+j6$qTmGH`GRm1f$CkUvoXps;_}UY7YA(7L|8mi}^S|Z0TYB^pG_2 z1LUBmCD|Kl7ygUMMYY5Coj5tH9U?vI`wp?)UB4fDXb&0B-zXl!_w@K2x=1=i{h^88 ze35hP-FK3E^|}c`dWvp(H*w6PUjD0&-XudK9bNP#zrGw59jT5RlIseepj=k)ds!0N zpdUqjZE?~dn$W(&(%Ygx*GG$NP#tQ2;UH`K+rWF0=hHIbIHmNPbeXSPwcjqMK8NDZ z&sdp=FI6t;&r$h*iL&waFZ)mN%l4x#_o^QZ`g;0S${X2>{$E=iEA@4~j65aLOF?E? zX?zeoR^Nw12e#|O+0Pm1l2LDT++zXhR(eG*YR^d4O*nICU5))Xq?~(KO&H3v`Z|63 zmn+Zd@3If{qVh)Q8vRgiCB7Ewq6yg_OU*4XM&-%{e+l}0N7K(W8v8z~Zz6mnzF{AN zZ-`HqC&O{=Y#;SPIP*!jY+cFy6}TT5eRe^*$BjAT-}9+>RJ^*DI&R~eSO;fgr0;h6 z!}EEZ{A(^z68iNr;H^CCCayR49jHW-i(LP03v#CsdQBIgpTgWqH}OU|AE}$PMUo5Q z?e-$)BsIU2zGda5Ie8#)G8rLXb1VNTyA7LS)%3|O&*+-3p=%yT*L)ov^vK59tbasK z&;QQj$LJR+v-azV^fhC-W6+6Fjc2S)JvUDM@as~WXb(O`f6`p18!yMNlU49KV?)jF z#J#*jZBNeZ>YyHS$mBfqt^Bh-GuD}(@*VQ(c~^6}_Cw#2gS1U2Mmq9km5ppU$-yVB z>>?f7d+zQkt@`rQo;>R3VoZ^?B>h}HT8G_MY@jbQP5JNnPtn)1l5CC~e#L9F>pAaa zQ{@Mgvv^)QKEXTHo9e5V^3re5gKO}oJ=#=H;U3k`7I%>5RNa-XyVSPRlp4QZ^m5$( z>UsOHYs(fSvSSk0jZQ2)Be5u%XnS+w`ca7+-jukpC9!y9;(g6mkLroVey^c<)PlJU ziyPk8a6`k54Q&nAH!N&e)R1ksZq(Gd^hN!zUxVh$L8yJDHQ#aYO1L#+85l9V!uOhY z=G`h=t#R;feXn^~-mUk&to!k9y+2gr_HTsRhg$vzuSQL`c9+`jL+wL-s{f|yneU;0 zq)g2<)IQYb)x6g??=rXOLiEF+?x05FMYqtJ3zTVTj%bs zbNAG_StB;gHq@7=XH~bMzC6wO>qBir9e%5IU8ih9&9<;^qv;{`qPDH5Sv9t*vt}pi zo0hG-Z3*G<^IzRc);+W;UUA93=4(>hKCK08Xh-%#qfmTtA+tQs`8H;(zoQ?Er#@uI`>$^35N7h zyXPsxsfNrma?ht5rVVEr&N7^Bm@#ZMoNu_mFl*RmxY)4Wu)}bf;c~+jhMk5h4Obbi zHq04z8Fm|PH0&|lY`Dd6n_=E?hvB1!FM(RWcvJ|TBea}5Bcuaq6&Ou0Pv5Z1u-kB> z5FywjM7T}Guhu)ZG=OxfYQ2ua$)G%hI$vDagrF1Zd~2awKLe(;UWV^eOlWrg4Nn+O zA}&2YV3cZuuL0B+crFAE`)mtT8OlPjvjii}(D|c3?^)o{9f7G70A=CAK zH>mvYG3+zkXSiQTTnEg3&~O`Ns_*w1wiCA8`-K?4uNe05OwZkU(co;#Y*LDwH0gQ9 zaJgYp@3^;^pN&&Of3Fx$KRa}H3GuU2$h!kV;%$0c_bd$YOvfsjerP$?w`r?{raA z&L8CLuHpQ>gSXPgr}HQMp|CIJ)}`>~x?kZxY*Y7sfgx<;u2uY(&i0qr{LI`v;asC*&s{XXC4Gaq@UJx>sn`#r>7-@VlDv;)_cqBd{u(b4QpliupWJD)z7fZvav zP58+dDv{Je`ueUbvVZQxcxo%{Va?}*9<+y0`d-FC?sb0aX^;JLn^#>hNM9eut?yC) zw1Kx)+J9|(B}frI;YCy5eYuG~#G~d%VJi+FzUC>gzwfgun-Mi-Bme3@tbfivC)0e)lIt@ge{sr=y{KLcC_nOc z#OEuLZY|yT=0)YDpTE}iuMgbJUWfU7@vIN7FYjLqZ?l%?AiRC!m91+DZ!P@^54?2o z$o1S09=~?`di5{FIvCG_Rtoq##J!9A0Jrvp6i=VuH@EbgjAOTux8I~bwjoS+CRmef zsNVR!)_O1y}ezLeTHP04P(DmO=9pah%j2+^6e28bKgjW;S|5x!J6uFc|_j?nL;emF|PC%jLj$0<4U`U za~!fD2QB})_Ug$w?O(ns( z(VJ{PbiHd}zr&qiBz<>vze9z60QwYdioaK%3x6}0Czh6e8B@A}uy-pS^8Ihj<2pb* z2cz1XbADmhQ)gD@%+MIiI{1S%K-$+Y)m@>DyA`TrZorySOJ-0eGH(%?*j33<9@YGl z*Y8;V_mhUdW1WWb-&~XbU6y~<$*!9G@3Q>=19Kjg{{!T$KK~b3{`GFS{2wI$j^E}| z2HAYMf9{!;-M8yphu}z*JvZ~ziI=lWkh7u@)dzcHxc#;g?8V4B9L~JkdN@YCMv~7D zNIpzYU0c$8dHB7gG5U@(=2D;cLUXLQBMj!nP-g7Sh^`Nk`SKsX`C6tPp8S_TzVh1A z(%-!nIm$c(XeyBo_ff6N8ttV{xqgf|HNS$n0+>JDi5H+jAJ!ul)|T||9Rn=iN}!jhi(pO zNqb29F*DKOhlxkuCvxiw+8_IF@~`?)9q_G7AA1nKMz3rkOwC)`efyb}e(LgV(CdD} zQQVBJyEGn(hO~R&siA522h6?rE%?*RbIEJzj0IP3U*DL|7yAgC{5$!*^ft;7`5vH; zD4+G*5AMGi8bV$K!Sj{cJ*?jkE#(j}8&RYl^}7w>vj=%M+`XJ{bj$B>_hQ}+br0wN zjXdu;P237=sJQj)jl?sYU&XKeqN&&yFGO}mf^QAzEF96GXo-FDD_O=(rKbbrawOAM z`UChNf;{iLePpG%GnB^(f)TyOkcs2iZ{7dSGp8@fy0!N*CfmpR{iDyU?1MJMCqe34 zm2l7NapiaOz9|@2eh>3n;$RB?sFlyX!QSFKk!y|Ee5;|grjC616O17=;AX$TiH*2F ziaV4YoKGJtid{;Wjr$X&#+LT-KO+O<_>BZNj9Gzyt$Sn6NJ;zuh2PxZzB!}jn}6h+ zftyJy{4M*Ts(auSXX`=t?}`UoBk8M44V2YW$YqraW!W4VIj(#ivNn=jT=}PTq%@EB z7s1Do+E(^e=MLr^Hq1_xA|sh!nCh=QOWfjf)dBNRCaT=jX7S%dC?n0C zMKG~X;J7jk+G=?Pcdh%e^p0#{>5g8~`vJyaqU8Sq@{S!;);^pG$|f?hy-eHFrT6W~ zyRa-6lcW5lvvDWj<-}Rg26Ht6%2I1iis z_{WtO@x0l7H&Je~U8C9c)GcSWFb5#ozP>zx`1bLQ)`Rqcl5MdZdVn}&+y2HcUMt_` z5$-X*@1HT4R_$dz3t2dq^eT@TWT4W@nujB*uV~Anvi7`;wm)4?5U=ZNt2qz`I%Yu8HpycI~%G-al;mNpVIL zZj?B9uJZdU=G>{wRzSbe)PV$L7mKnB2H}jM49}QP86+~Bi;tT>jYq3&=komX*inDV z^POj_&d3j8=!^~KK}BgtCz_bYs<2yxd~+$^Xihx&8utyp6OaG9(W>%VwZA&|R=$eg zvp=-H{CUbx>HLDlzueNvUb!xvaZBe}_)jrEROKg{tSy7TDE#%Tc)5o$RKivne+4;_qka??{pigq+ug{4kgrBoe!X@t?~ZKg z7VJgYtKzvQa_r@u{ccgVsLm4!I@VSGC&SD10C9qpcULDMk7glp1pAjO4wCgXDKBk!1fsqGNucfw5|A zv~`hW?0(txKS2&l*C6MMjEOYIi9^pB7kE+e?Ptw=7$0^t@%=M=DO*mqiQ7|}a?-b2 zPZJ5(LO;MfptULs(Mpj1miFLn-ZfWsHn@N7g~*d$>O${M>?D{U4ht)CqI^JDZo@8Yk z3FyCItstuVu-Ye)^tT3@dah<2*!xs3mqe0@v*n+8L(P)on)BY6G`o^E((~vL(b0&G z?t=F8{~eHVCQ3gxbY4?9 zpL*zJuBrH2a;}!Yzt5b3e%>k1+E4rIoQbfL_=nn0`_D+5-i7U~a8GUZb2QDITv6Lc z-#_v?-~WMq@7hDQC-+nE;C#OK@jv)F-+yk1__bF^H{Ywy761Cz`Tn!^y=#wJ{5KQ7 zml=+3g1wcWP+r%tre)7U+6tKm2ejYBGk5*PXZI`|d1vsMuHX6jFHU}@B{A8_DxOjQ zT@}u@IZ{|lo1F5EB)i!wC9G4~9Y#$uRnaRb$t=F#dKB{ zGUpO_#J90O$Zy&_WznVhf7i|Q)ucijs;LKA!1HK^K0E4Fax=6Qv&A<<;|;X&`lIN4 z`nhQDqIbSK5F}~q!4t70{1BM~ZECGw*v{JwPcTQeoS=-FoGi+h)i&$5u=~l!BNvIE zm~#TXF6DPT7>qkYTdzOLKF&Ws>Du8+OOU$1$a)Pr)Ym7_8O{B~5oJy;V~NeI0V-=P zM-;njGk(>^M7=c2u9L11zx^q)PrMLI%`42+c}dka8g{9*(Y{PryU3^7X8WN5-#(Mw z^Luk}3T5d-5MMS_nFkVQ*khe)W~g4rD#i#C^;MQagMKG^BF})c$huQ{L+T zXu^hXq~4NSCmd71>Yq?HO_>`CUr`y67R|$qK(plKH8QnGxybH}Q%2tQ+(Uf6J$^Mh zUG_z7_{bDD|3@|^^NCzP%%^Nlkb4F#sa$U78FJ6r&5`5{uFO~`Qz{dl`c1^2nnxB* zT~*-RyoocQQOU~@o%v$_{byDV%?-=Bf&PS*QXY?t=Nn;`%_9-+%YkDs_3wrX!8;Dmn!g|U{>mhx)k3!do z_S6?3z7YQ@9oX9yPgi5{qkOu40M`8+wRW&pUPqDBQQ9|AXkYu+*Xv*DUbQneQ2q(Z zLHfe;yw0*}$gMB5qEEyt0cW5n{}KF0lKJu(p!$uSE~M``mWKB)UgUUUBxR^P`MzVx zp%(O3ER{clA%%%wr`~JzsOYd(mwpBN%=Ou0$4SmKF@MeXss9o0R1U|6=>O1qk3Vo> z=ga4P?pjwj2dN+Rn_Xk{s^|WhXg0!g-(T`I`O&xo=TV3k|55YsSSu>|Ex)9{_@{&) zg;xC8EuKE^CSNKaN0&w;T6^wk@^*f&bbJ(s{T;&IwNNtT!77af!TNFI@gw~pnu_Nh z98g-N3zP??;d}7v9^UQZnbv4%T#Y?M+%xs{Xs`Z5q*u=mf(N*p$d}se*TEOkNws!; zFJ~s~AuWDfz}LU>B0ji}^6pWYQrCIrq-vbNj}iPDc^;~sdn9j>2`VqTc3fS*q;KoS zO?VfM&Cu3YJ!_t#uV=dNT|NKn5cSL&wB`on*XKxggtqy3Y(llM7xPVqxtse&hy53t zo9_EGKF&MURjp1wPM<}K@yEj#p%N zpDkJn`ybaME0I;MkNkz2bcA-zx(e;pYMd>v6K8@rLmpXNj1J+?zhmC+#Gf<&Hr|mh zcEJy-w;u6M$CgSY_+)uKI`V$XMQwmkpz#rBUa$-S)g4LhNIHBP%8Hv$o%ko^o71}s`>tlwcqFV z7A03jQ>q{7(9iSUk3)Bmw{FTux<@*ObrG(QU36407d2+4db! zk-4L$C$b|G*EQ>$kJx#Ux`RIEOy}bzw=B8&BSGYBekLw$n-?_1n<673&C${Ev5|3+ z@v#Y!w?-yLSdRPJD^l|)9{hxy3|_II_O0f^oEk#xl-V(QA9wrD4u$}y)?AunJ*vj7 zSxB_agB{gp;d{;F46pG0W@^&A_5F?-x4!SJMiYL&GhyB>{1jXiUg3L<6L`0NrXeiv zR`?np@ov5EqHes~{}O7>b~PyXqS4J6(ofaJP;<7OH~YtsQ*f63R{d+vwW`x!O2#|A z1C;ySb?yaq?nQO(57fDDt8;&{&b_A2y|K>ydv)%I>fB$cbN@x1`)}&p&(^vBuFn1a zI(MPY{V#RypVqmVGhRJbWLYqE$>8}RmtTIlJ3qucXkK{jX(H~ZkW*)he|*UbW{wB9 z-xA_b$AkDoL_U5qhltc3U$Ru;GtY75ZOg)#mM&dEgdbjU+s#W>STyFrog}h!<)=Gu zxyhcmV@BAq_}1W#a8_hcJ<%i#Gdyy{1Qczu^JHgNBC;UotEh4j3LbJZgB{@D;-ohOZh*{3yL~!zRNP!=xc?K<96Q zA^msGoidziIL(kbQSN=(aHiob!`X%z!&bxjh6@ZC19aiE87?+#H|#K6X1LsNg<+@R zO2bu#s||C8U54F;8x4C5Hyds-+-8_J++p~r;ZDO|!(E2E4fh!K8SXReH{5S{!0@2q zA;Xsp3x)%RhYgP!9yff&@PuI;HKX~}?LsEwrjYk?&oY!g5M69B+-8_J+zHD63E`wr zKgj<|^n`Gg;cCO2VV7aI;YPzA!_9^|r$pgwGt3+AFnrW-ry+AToc~>hyAAgk_8IOo z>^IzRc);+W;UUA93=4(>hKCK08Xh-%#qfmTtA?l@m%g}RlVOWt(r~Qd1j9*&DZ{CT z(+sB@YF}%W*G$7%hO-SbhOLJ44Hp<@4ciPC8@3yE7%nqhZn(m*({QEXD#O)=Im0f) zZo`d+J%*bNw-|0S%p2}7eAIA-=EKoo*S_IeN3cSO`xW72)(6p%Iw{3D8p0{e;Wqbd z<_*gKDj{?%`$gq9)o_~Obi=gaOv71*vkfzbt%mar7Z_#@+YA>Qwi|XBE;C$ixWcg0 zaHZiY!_|g4!!E;a!;OYLhMNty7;ZDn8}2ZC)NrR^ui-Ak-G+M%`waIP_8aauJYaax z@Q~q4h6Td`!^4J04UZeXVtB&vRYMtxs=v5llVOWt(r~Qd1j9*&DZ{CT(+sB@rVVEr z&N7^Bm@#ZMoNu_mFl*Rmc(4V!!+>p~vqoHP|a#t@C3gFF_FWp1+Y z?Lm+cLi??T^M&sSf(629$V*V+^c&7+g1z{mokp7IeTxvcI}Zl8I|qhzq=`fCI}Ljc zj~mWsEy^V3@GlpVj&9+3%)J)EXKwuteCF2gz-KRM-45YRr9(jarCmt6l5{F5->pKv z+alyUt?LngYQ4^+^O<9$bvpR#7ZT1YzSZ|`oeuA35vHE^3whpw4ie^t(}`cm_w&iC zFmJd=$aiD8^?bJBV&Mgpix58p!V58yNTd9>3VD7|NIY@UtoI9qyx(Y85b}N{d2#Us z)C+khTaG?|rFA^+$QnCnZ-|9FwXdtIc5YsB$1S&hWYvYUWP|^YE!+8jcAgDY8br7+ z=GHZn8_`|8P_yp+dks+w?#l3A?LL3WpRV_C>-!A1u4T~l1Y`;98NgnF{Glp>CESWP z%B`!Puppc2<-_|7Pvp;ENAcI@9iaE8wqR|%tJ7hdQ}HT3AMXZ!V_J0r?#d7;dYleqOT-7ld;jw_>v2fm7kTe5?~nC3vu30QuhX6@ zGc$eJOy~Xd=gOp1xl}_4(`d7EJU0)tOh@&93Af%|%6%F4<=nHl)sA1neKYq`?q%G! zaNo+U>z55<4u0oyU&Y7kA(I-`wM08pITR0NO#uNyn7dYXPggGO0j=Wj6Sdy z#)~zU$Cz?)1bvXHrcFOeCd2;O@%O#wsNaW@v0Zl-fz}Vy?|~Dfe?RdB!cAn?74%Ia zn=AP57$1yG&2CCSgYG;E%>jT{wzA)3S$(fl6@PMXWh(nPBE29*3;~n&mrt*(#@5=wsSOHK^82S-v~ zO~j#n>D9M;{axFCto?7UzjphN+1s%67UnE2j<8?gU2i{Szt13jU!s*cZGOK`?O6u< zoU-3%-0k;yr`xwF(MNs>ue#sod2cxuoznAiJhiU6-{%!I`+cG^UYy<6!=5Ay)u-)K3tU&Yv{%1q_$%S|-GT)C3yWvDW%rIj3I za>_oVN7$D%IIH{*l$qxAN7yqfmdt-S9poQo&$w@BoJw;I;=vlXPnPyTY?-mHfPdyp z-@^FveHHCLgeEP9d~oWyF|6>tQqRRNlC8hV?Rn-S{Qd;D=R>^{j|p|@-4a8&F=O1b zJHZupp9|^|5Bp1e*uXha$%)O!fEaq6( zq%}Jlht?T9)HU-*Hp9b<%D>Cn1dTTxhJCm)-5O#RY*>^q||zXkZ$ULkGV z+ViW6JIB2`M_imaHIn$XW{9Q4}- zO=~*L)rgoWJGxpkJ4 ze)oe~vwphUhcgtaZK&t%7Qfv7uJ^yCK8<|m{p7Iw{cn$}u}l5$;jlJ-orC4$7VaQE zJxf|VJ1yTjTT5+`vE2Th;%~yA&N}sRO|$s*Tr?Dem)524F2p;2pR+lxDy36bGv{ex znK8kwsw?)CudX@M`A}}$2^#I-ooKg-XQDgNVFz>|dSxtU%nF?g)$#k4_2Nx1)w!Xp zGotFxm(e@s#+2{k-D>2B9~W2H8V`RHvPpD)%P{ZHVP3ZO;Bxa-p>JDMKv&X$^x<{X*yy3rHTo5pqVY&P#Cd!;KT zpcA5*s|wO*-()}3E}pgXOygoyX>*R>>={?m9FInxwIgfUBM^RMUKx8zis!|X1-_kC z_Z{cARKL?XQ~C})Ui~hb>pt)gd^el#a)kW?bF5PQ)*e%l%v_fy`sJRDw2Uu*j`=f6 zi+iWFij4gsBMRD=Rq4_ms!EH_M^HR#_>Ody;=y<~uU_>(p(fmK@m_nwP375yK>6j& zsnps$d&u{Smb8b}Oy+-0PaADf#*#mH<)|HAcy@BWKwaf3HHBc7qo6tS%xeBeR&XMJ% z6$SL*^bO@@N$nxKw!A#eevSdQLK1oy*?UZ9{wTfL6SJw0GAckHsZABp!7SXujiB_@$yXNwv4%`=s>D2cuIUT6I<#| zzPX0HZAE`v4L*c>1^y%H#**f)X88W9#^6QmvmLPi)d=2a(&0XUk&)xeQDpW=o@wu_ zTRZY)3bS^v4}cmonmt`IliPaxR-S(KHd)UqJ6gYozmy!5c}({Nk zWTPuzuDm#N>o53D>0M#vfR1wIkfa>GZ|`#C^Pq*VGT&-(#4`^JOz1=wKs$=-KS0H$ zu=(A5G7~RpPAT=Qb>dDg>1;B6CqFCLQ*{+Q6-{n%=YGnsY-jQGO6q%62X%`7c7984 zM1tQge-D|LNWl-xb?047Jgnc6r{bYp=ac2{pifjEUqwz!r$kbtOQM1I!cU4{<@Ye> zq-{Jq)LCB6JNkh~B+ER1XZWr9C633Pt|Q!QnbU(Fb9SL<_8RKh^EqqPs(gMZ6Q1=J zdDk;lx$!JI{1(dk8QOLJe4b6FPgXUuzc~6tI!<~do`jZ|4=TOlb({3bmyzF{@VE9o z)Ly{na=w=IQLS!VHjHk(TRM#O)zY!=x3e?!?PKgepHcZ!Pk#UPM|8Fp>1lH3LM<$_ z?_Nn~YdPI1+n2m+FZX(zMS4i`mpOtHrNb3I^CX?!Q>*t_TjutZ*L(UyUK9UVwPlIF z`&W$rFNxph#ixULe9yWvo};}ZC}Z@t@^f?=dtYWa(+Jz%moubBAJUGR;?CESKGvC9jREfoBM9;_bTPf!;ePbe zPZ4WBOJAjiv1j)&KZ><@M>;)Ci?8{udOMGGE7DD#Kb)NfkEjmCC$j%;WDkD%wfZeB z3pSO+OWNnQmUho)u9fG(Y2;gWggdK7=VS4`?7BE-3COlnSo+q-r?^<#VcmE>Q3MOVKwOkKRWrY`O@dh+!8dVH~i`K^lUjq>HcGvEGnd=X1`IlgFO zztVb|dh0Ox_#xpc-Qo+aH>{TnqJx7qe#Q;sN9Pjwa3)%LoQ}VGC;e(=(R-S*kbLlU zKlXyjuKs;_oH0x}{Jy1s1ZiK;_fX~B3pbUfa`sn(v%k)9XMcr!6oZcNmGwy{2qr1fbK_ATfbg{5!fskwRSR`LCGXkL4FXGHVZ z$B`v#S?t0>9{4iP6;Cw98CP?1g$Cw!)~Bo4rwjR_bm?5SKxyhA zP2%gCH2t;C6;gUKbMro5e`04{i9UWt8Pw}A=2kczvfrI`^~QN+n$@MkmkyJhl-)Zb zXp6lX3C}G{XSzzNBiR(HvyF4Z`Z-Mfs~n!kE>t;428os=6C@|RZvQcQa423GQ4_a# zYJmDy9ee%FL|LalpVnSHb-KGxd!-=5_PMjK-gv%`uM(r!!DUC^Pz|4Zyv*{3;VeS85t!oBY%=`z=c;MV7CV_v!TiB=z^ zY{<_sFJJa?uEC~5-<4y1vS;&a)Ha*Y$KKNc zw2*{n`JLkTeC}564EM)K|D#uK=lOVN|0*xoJg>1I!}ece^(-dZ<71-O=d{VkdD{|O znSPag`C`IcTo)!bk82aumi1#QgSxUF7)Bp|n0gi6d71nP;_z+7OQ|!p)kNPx(&m!0 z55H_^)u&{I`YqIslUz&TmTc3SEWUeOvh1mgo+`@r7LC>0-m&N}NRL-@_u7HW@b z4!HD5cy3e|XZLhbXZI#pM-!Wr-jukSddm>z*mPH=)6LrtZL~9n;FT8Rm8oYj2JtKC z)5$e-FJ5U)(q7FnHHFczeUNqSgE;RbPnuF|pU**4UGzn(uG9w=1m8y& ztf`T^*9=EV(|c zY(?XTWy#yg$V4wIBr7GG^=>@RhtgXg@Zsh*mD=zlIs5=TlFpF7U^8kgT>E$r@*#+X zeLSB>wl*=&A;Wd zFZBV)wu`(gR_fW>d`$c0&+3K0d*HoJc%cLShR3Jp6rMkCDzqKW*BYJ-dB`$0iofO* zWlxz>-^B#H;L1q*1_mFfK6CGLSC=|Fk)?g;E%;X7#rqm6tixyy`hLK93+?5`!h*tC z|9V^T&q~P1g8E24RQ@MhOC!65zL>4_<*|Og!S$JSk{9jW@6tfN6%XgSk8UC^*Y`(W zUVuJWZ(me?bzYTZ__PknfxNZ#Ah&Z5ReH8gJT|MBzSz#N|MXGHb11rd;b$7>{C=oU zpuNLpCrIBu|1s;YyEaWIA!HZ(9A9*t^XtGwCkzh5V|IS$)be`mA{OFwei{`t{T6_9|WK zb3H`5qO4U`|9gfo)dx@exb)`K-O&ctt;*jD!s6Z6X-g9J(ywan!ufVa(?*`n$G+`D zN349u_KG{7Df(1l@0;_*xsi@SFeO)5o8o*X_#^_okd9(JHAOP_*`{DYNpe>0_$c`h zZ~a{)IIl5DpKWqZVG8^gDXb~=P-cN>6Z(y(dn?-CGM?TzAl~~qc0~_mIEsEtwRL^F zB}to=adx0PSwtR2Z|_VTF8iTQ8wx+1i{y{ym}&6{XLoQ0gAY}Nl*Y$q(O$&yXu z=-=v8a-r{{zT&iCQ$_uuPW~W=oa{k=Dh-8mhzB`T+mFN^HbdI?XTS$ukI;@8QkFL1 zM{PXs?>6!@l+68a)^>S6J(7>ucCFm?GHw7~s+EW0C7lsG@qj!-c_7if!`}q=nBunM*B=l2zUQs4{sx3&lyY^_`=wHpozS`(p^d=kI z>;F!|3vIyH^7Z?vKaIQo7d#``ssFc5Z?CMSd?V?wZ&3C9@8n-?+ix>A@HF4wN~z zyC^HogUOKo7Rr(-3`gF`8Ay_c)A%+>Z!GA%D77KmlGJ4%&xv0&B>GW(|A4fJH^dha zFa>^{XFBhvtrNe!=%!9+E|)Kgc4RX~rmQV!U2L=?KV_rrAf87U4^7ZEhprt>Djw0P z^7c)_i>B8&Ij%UFD={Q}9{OoWpOQ^pR%D@h$soqvuu~rx(3n=jjd|z4oS;pZBCnE5 zm;aRWq=;)LVJFYiJcj3sv?0oS(oYrpc_&&FT{>HgZ$y_G?+L8^DI13~o}puvIkp+7 z{7TnP<97fKH7>0-rw>c=<`XJUuB85PwT2LAenf^_XUV3(G&gkO&Me{_rX$F!>Nv6H zkm!uE4Ec)jPX7OIZpHO~b7KPrn(5)sMbey2f2FV(hg^%>Iw~98(yY^sqFWuHZT&}J z>YQP|n>%WDBKzjVb)yms-;`L?l4u*5xW0M*r~`>uf24WT?763&owSg?%Kvp|Cou=7 z=8D(+)?DC3l{Uf`i2&o%T`J2c@7?$O4llT>=F&RaQ^Rkpd8_c*&FqvXP0s)9h<_Nq z*L<(=3g7ou;|t$w{!{Jy15*dx3jain+rJTNo$jgWYYrxuhYTq5xAuxLQ~Ol^BLg3F z=wCHFc*Wd|=vw!vQ|1yXZL}`>fFCu=iX4~ zX3k&rQu=D=Vav@th3X|Y>u^66u3f!wX)x8T#QoILPp%C7p&pmcxU71D)1@<5nQLb( z+1X1&o#$lXX|?Mq2RdmPuZv1=w2T-0lpW=CQ@DngCpT+-Zt$t4cj)jZR?Z5zR&r}C z#Y$*Pm=~S}LR)fA5IsY_lMJWJ{}k40;4ez0XAD~nX`i^~3k50j~ebY>^0nFxZ7}#VV~hX z!+yj4h6fA}8Xhuy$*^EJV0hT@sNr$LR}4=WzG{fDap~6@Qstw`kUmc5P8yCioM1S~ zFl9K^aGK$C!?Ypu(Oh`540S$(tAE2*!}*2_46}x9hKmig)>Yqk7%nqhZn(m*({QEX zD#O)=Im0f)Zo`d+J%*bNw-|0S%p2}7JP3-u4;!{Z_gb5@%&<%Nwjk&O#TWa8h_`+r z^Gx>(5tdqmDSxx+2%5xP)cuHfttC5wUxl{{g)H=I&t_8=a&Ix5$%JINr)muv*kh>k zG~`YqWQ1CqCUk4fz*o$@2LoKsXQP;ey9|#S?jx;wenN;0ZPyyHw+BH%$n#m`L8vpF zgzn5H@D)0K<<`2YN$+6pt=4?84l85m)_~z2OXEuZ<{KUoQV#vdmPymXZ}i@s;RL!f zoItmx3v5k={*%;&3rBb^^kVMaLel$^VJqLrpA?U9rI7c1Ld^vRRZj;E4+*KGmkbL+ z@;YGe4;vmge8rGH?jTBD@#@x)EiiXhNZtJ^Ys#b;w3KY-DQ7}Cb>Yu_y6KLpKDp`k z*ZMu>_29Cz6-z$xu{$oDC0*kK@&`ys=lsvDL<<6nB#3ZB?(V9!FZDq0bWvUIH*Dgr z;ru~bXmz*l>UI4|A1UmMov&~$Qn&pU#O-bcYtz?Z^fl6!wtDO1gOu@?uPBK z>ca5k_qVuf<1G-@GM@R%$J@z++IZ*lLN<%Pe7q}oP#bTWcom`Il^=yC?BZ5yuXWP z&P>lp4PK{RD|gAv85cY6r(Y|#Vup*Wx>jxsmZ|p9Pi8Lok@^)P8O_lMUJO#3>BG3H z6c6qnXbHLwCv)GVOZ?=&XpDwAyovvGefNd3o@)-|Ecz1E7VadRC}E^i_tQVUx2!&J zjVJ6$?^8clbDVHzvVKPMexa4e0)8iGFUM0?(Wl$R8m_B|S8?lHU&cuZKb{=y-wF5M zDwOp+Nm%+`aggR_g-P|C7f+3GeZthai*GjJX8O9ceyMzAs;e}MaMdPOyjNzsD(Sv1 z#&o)9k9Qq*@%g-~j~YJ#{^Nw9cW9sTS)7@13&nU2w|HWiE7I^^?b%<^9>ybjH_9AIUlFxpfg`ptTzf z_D=hICV0jQ^5Rq>?-*mLzTb1{nUv?E@+#)$`u)J}WZv#Rd#-YJdqXm}0D5iq;qFPC zdM1^p6>O{5#2;kx?hKs12S--=9@PGN%H!fP=RQr;c>iwVQh&Vi##+E5LGDYeMS(`L zI?HT+DW1BgBuGZ~;YyW{?=Jx)F!u=4Lp0`>Ya{Ig9|2Bj} z{WI^LFhm-)-+_OBqUN`MCiL;Qk?;B3K5n7TC)>j9HH5Bx1OEuyIU-m(XDo z`=4gNO#B3?jg`W z+!~|X&F`ybtSyM=e@0(qGxFd<#^y%-&NImNt^w^i`dMhpr}ZFmA^+>!E8WoFiQEIl zS8zwt^W52MH(oh!t!Q`k2e+?h>~bw~^MUtY2wgFjkDOf3{h(y2=;=2jkej|=H|_c-<<@5>j@Pi0EKiT;WDv)E`u&F0=_sNY!> zT_m&o*U}@o*|y^9O7B+x2KDL^$=-!qwybt7SKJ#M{Ui< zv*?#*>VE+Gj0funB0cY8{>QzgPicNvK40X_z9R?uCLY{T{C&P@z^~{)&osvS4QN$* zUiGKFHgnMA*9lYe;4~K2h%9;>KTXIu&Sf~lzPshG;BLgt8fO=dbRoJawo}iiH*!YL z!ZNa}IgVds*_bc$oU=AcT37NtzF{qUc^l85qw;rgC-^2ZlDXH!tMR-CLFu{&K#gq< zT*{d>q&t?LA2dLVK`vj0_7aD$ADMWP@5PT#BVWZQO1HDo7(eEBoqv4&nNBXN%#^N3&sC+!>SxC2T%6CiGlN=7 zns>rlUd{{}@6N_kKKkL;d*JhUaAFY)&1B~yyneX;9uN`}XF{2G-*=I-W`M3OYo>h3JxUa0k$a3oVI6R~MT~)7IJFyVi88coupXc751IMvP?!?a#*5^qR`{GVavrl^By7h(i z+3vz$;A7r0b=;~*DD;pu6`cmaX$ik-7ml936d!iBT_e#0- ztv_?z2W6wDwj{)h@pN~T@;pP&u-(UqH{z+UL4OO&JY!0$#-pz0tyUp+hWmD1 zNpbuT-j8I)m;RLw{#@ty(yh?Ve$pX19Z!F0pa6W zUm<=>ezfUW40?%mtl3aXfwZz=-tKg{vYr79%P4!cFDZX^j|2 z))#7B%S7!FA$_EC4irW_70!*(n#(45fVNAKer{yP^~~1}nh!p$INHla%BntIJySUP zMl{oZ3+GFHGz?dKJ0dx^z*_R+9P-gbITaGp$z3I-ITqZ=<|&%@wYG9H8r)mUL*i+T zYfDFKErsULsZQPm%}C#mP+j0hy0NPBS;hnpwfKMEZ-x7QPWbvbN9h zV?&K!&TdfK@sdc-_>$yhlC{~QpFe^3#XnK2d)2$@U-iyfj@Q)tJgaxr@e}NIJy`FH zi}bO&Iv=21BI)i@(-i8R-~H=3!{$NiyE9)*_2}H2r;3H^bq0#&9Cbry+T*^h__n(C zO(W+XI=eWHJ;A$!3K#vLdj1LZqIl*--p9NJ=zw#C^c*DE>vSGyb0c+q4`ax_PVeb~ z4mz`?L~cU?q1>!I1nhY(8sm&!C)2*joP3qx3gkyq?n?<|Tdb)E{$oBiGVTn{$8zJo zYA<%q++I;VsQoy~zTaTqFSqYmi|W2-{lEME%Y2{VJAEVmKl`&`T`Ig^Ae%li6Ffu!8v`2O@w#+lEHK|6Q;sqgL5ZG?j&9P_8uAO zo@pNfg>x<6?&6)&f(&sqrEmX%Z#C||p{DGDo^0t`(2dG!L#O!ko`UKv=vh}eoA5k6 z(I4;VNwllAl2zKJZVHsum9^(l(YD5BXjWdO7uPO=CkNX= zp3cr7ed1l3e-n3-ra1Etu@0LhQ$&BFF$C&FrB}b{K5sru+>$c`wcX+pkL1EgR{I$$f!@Dt$ctv_c^ZzQs@ElI7jtI{OWIdBF8zo zoiCuzsk`8TOKB!w(a!!p$id=l&N`Am_yPWXpwb9!x%^Ysm-;ZYA3JA9NM<!3 z^hHEQC|BW)cFSM3Jug@V+XRKGwjbmf4Y6=+Csw#~v@mIC(ml z7}PBX$EhB(W%dfe{#rLMB6St(oo+yv>0Gj=`^A4}@{RaG=k_Si3R|-OZsHbSMAP>a z&ft4j4%CU(D9|QLFwe%7jX%fd5uZ=;^hVC{A*{-s%-Q*11WFv@(*EqS1;t-~PPRn%?~YPG$BCzw2Nl1{OLXh>{S5T-6-~!3ME1MqR{qe(#7K(zq)tar zXM?tCXL&m5t@0${&_=29q?1A9i(#sXN`KIEPeJ))n9KE}9H$J9K7A%<6TYVq>b1EA z&4-OTo?PU3axL*jiL-?|R{E8$0QwdW-$U6b?XjM<1s6W{wRF&H;JF z!GT0r=E?IW9FyJg6#QG8XSux{s^>m0Kg9-+95|jp1|;88ILvRYos+zY=sf83w=4hh zi<4VrUq!Qne5CUoIPaw*`&=?qvNyPE?T^)8Fp6jWJX3t?i&pu1z4#B%mOrCLwDux% z2CLt*MnvD2@uT+Gr#SBvU0wcL3Hev;tgA{1^;HnI&iW9qIyv=pD5t(6Jwck)o(tgrNQQY=@`s-C&t$(yheV?par5C$dxF zYChtgJ4aTwP%e%ZkZ+>pM@ggPz~OVk{+Gkl*SHHbzgm6W$ooUrEx94r) zIc!@=v*U%|MvodFh`!YyR8L!t)K}0Wo$+aByNWl^BhBi=Nf@0ePd_%=QaJi8f3>uw zGGd*`M4kPj{OcWkMUDcaDk_@y^^s`wUo#8slwrwD9_a`Ycz1O>V=9-euDslDs;K+*F&eeB4;kW*~<+5eabL{it`YqUdviT*_ znH)da^(SinxB61m-*GMPRCl#?a-2GO96D702VHC~492frz3onf^0IGom{0kA%*w%+ zsn!;$40iBb_Mg@`-p83k>f5d5wYzyQUh;m{;wS3l;yUcPedR$piJLNyCoetadw(X> zN{fHchF)7)L;9sBG(NY2aAWC0QT-@yL$Ag%h4KTfQw!1w?rfa8aO3RLBN_Z5!p$^= zvWPw&>TrGKZfI5I^;PJhHtmauL-9$@RpUb5^SiwHlDE0IVj0fi878i)h%15Y*lYD6 z`P3&lhaLDD9h$*bBYnH?M6UCl+7#-8ScrewG&icQ?xdb_U&J0=T%OKaqN*K(zCL)) z$jU?LKqrS-ANE8K_Gsn>#$Y+m6nk{DJLBk{lHQNtoTL53bMQgVc!CyF=oitW&OEBM zUsNXQn`r95&V)`6UJoxN2m2Phjd=xWQ<{DQ^!BB)_-o)B z^@AL|9{I#K(n0^o9Dd0R^@)V`3VonK8}`amm194by>jZ=LO+6*-C2|=>^-G{uzcT& zbgt6U$aB$uV&)##3wK-F^L;ZcMfN{K?3IwqlHZ zoH<9QWZp{gG(uwO9BM9_optdw zJO3*q-c$H~e{|5T@EBjPD}1l9;qVH-UsdB)el)&W`+hJR;rAN5s(qhCNO`xupI+nk zZ-koneQN$%f^*Ho*GsB^EX zbFZy)BcH36;{QU`6{d$ZQq@cE^Ho>){!i=Ne^clFcAfiRo%@G%?!$HNAJ@5mR_E5d z^y&doOE_=o)(_vZvi9I6_nQgpH~T&7FP$~x)RUr^Z+_>^AHVJPTijzGo+h84GA+G& zWK(#u6f@7mv!Lu$DL+HqpDyK3lKRwA&W!r_%?i%Ky9w9QJ8x$y`>Nn37mPdc$^CLC zMcrXDRvE4~%o(~l>AdeYx0{oWyT{y{4YwF>Gt3*hIqCR+)ZA`PI__R` z?=swNxW};1(9KE5f4{lioOIj=%ze=Ckl{;)1w%I{9sh^T?dGK8K5p(;3{M!oYKY)- zGls2(^9>gmGH=SIug!3=VY^|6 z;WESJhARv^4ObejGF)w#Gwd?#Hr!~~W4PIHi{UoIyx|VRM-6ux_8RUo+-H=YJFkjx)Z3!) zb{H}j!MS%D_8RUo+--ZZZpgq?l64RaHnCf;V#47hIXZX zZxiCT`%R(0SB1P^z<_|(uyiY};7dZn$zUkz{3e|nC4b9>=W}kQaC#7^;V=JN=n$6w zf)Mv?CVk6)yKpM+g*-nl#9kST9q!hu2ruB7khG_S47f}clC};|;r0tjM?okfX)H)O zGD6a^N=W!Sgv5JLh`*yk@;i+|7QJ64#NBV$sWnABKPbEidqSx2$Ag5E7UG^S;pDb4&_A>p}ms=x(WqXc#cXTXQTiHEj||xpWE7Lw^Z*zDJ0^gThPD2TVp$`J{!)r{M`9@wJ~7KHn(Bz0cgo z%}wzIQGSyhw0nL92dnvC(bImaJTI;cMT{IAz(=sqd@nj!tP#{0}ZXqN)PS&H&Nju9=1&^iJ0l zZv94;yK6XqRJW#np4Ol0ras;b&-{f-bC>FJ1b4={;0d)O_?_gIAKh}#0;6ZKr4w1ebG_U*u)%5M;x5C8~byq$$^jTg{^H%=+wJ$~c$vZ$F@00wljdw8> z#Gi{75m$}(d459!oq)UAru=g2le+Mi;X_1kkm6RnNp8jIX^Nl0zNw@)qF>?Vf9kth zf88XmEQZg*;>iVRS)Cgl; z<>Ra?Lgc>~&CV@7LVu_FMw65^|m)G?jcv<_=uPZ$Ha*RIFb$#D@S^cU% zrQdNq{$rejlwkZJnp{JnGruxDCvjYBm$G^7Wq+iF{MGI~f!M5G%lOqgYHU|xef;j& z2K7At@7oJP{5g1eiVL4;FNoT!_KbApjTK-);Hr~t0G7C4jt`^g5ijrGkUV!{TLJ#h zE#LfqB|{|}Ro`BwNG7Yy{N+pfT|Dsop?6!j#oPY!{x0W1tqf4ViFj1?r&^Lf{hrTV zD+Bs*V?IS zbTVMZWtU$TdOy7kP+O3zDg#E*#~M#xP&q4ldpV69=wvNj6du>O^y-xMvDt{Km{^@fpTtJ@zc$DVLOAL|u)r}N?P$NIuel_#Ej&W(38u@6qbd?3w5 z*LW2s=y{z7*o!X1`a@7_{(KnvHklzD?%FW!)0hqG1B3MX%D+09a>0*wrMI)c)dfE~ zEBf2zm0AOseW0Q}hu&6AGiODR7w!Kufm`WD&NWB0-#cS5>?L{e(tFFx=3p{@bbCn+)=s6%H~nYxqtigzESbHdq)Lx zDM;~*zxMHC?x?1gQsuqq-xXY#ue%ebqE~?^EGt|LezHe4d0ujkCxM?$b+m zc?lA_G|p0cY21V+k-Jo`lF69c)l0l8S)@y4I2ws`sdI(@954G$W^L!PL_50NL_FHc1TzR`fYUiGWF_Jf2X1LR^50rgBR*13W^@HS<+zW*0 zjW?t(ZXdM&2RD!zYyec#`u|g#T=ng*xcyLF*XjxNPpXb#CnwY8PZV@Dw`8)XuEYEm zefZ0VHg{Pr@QpMm=GSL=seKD_I3*M_J5&J@oSp3>#RyOrO( z>IB?14Q2Jq=&{98YQ)_F=vH{jzv3jk>a`fhoT_Uu?e%(0{i&ZE!k@Qg!||ruE;_v) z^J?$(dTeS~Sf}W*QNaa2T60mpoJ1!`AMBd)TvhgK+eC!|RhKaIFHMq*d_wAH->6WJ{IAm? z;*Y^A&YXvEf2;6WNHG4rbjqpz8=U_^e)L=)ele6z5g+K%H_|C|KUFXBQ>y9;`HQZv z>ZSLxYyBnn)#k{7(m^PanxR@$j=2Nd#jCEXrB>VU>XzFWcwOT3lpR;D;3w&(U^;~8 znw4Ob$o~&}Zv$slb=?i``!O&X$H@hTX2LVdL5E~wMm)fvgOcPjjD{F&E=ZIlMCKDg z2e>kWVoKT(h7VK7LkuP~(QuoZXj5%TL-X+Fq3J|1p{d%5C4Fe3?fu}sA!y%Vv`=Y6 za^L@dpS|wgbGSHn$XG|~`u)~fd+)Q(+TUxhz0W@TY$Qd7>KKmutIU1ojp2GsLV*n# zli**(`&3FZdhTA+%UKByvhnCDadFC`W^naL&1moG@g^>29;1_Hgb)Q;MS^m@&2 zToen`Y<~P`guBqbJiUt`-S2FDPrd6Pob8jXmdGOJIAhD(4}Tv}fP94a18sR5A+OkY zBx^+aAzWMtXL}G3c{d`!mdE#e4#Jo|dpzodAGhKl8uR13m(zHeu!In;Cn@yMN7^1P~sW2!Z;szm9OV}7Eb z&$)jXdb_C2&pZpTkIiqurLC*2eYFZ)0%zHrrPr!);qt)S0u{lD;p)KTz&k=Ufp-R` z1TOZXl&3u^d8IF`Udq{bL%Q`8LPA4kw=6@u6zLD^Iw?Hi?T2FBcpxpr^HHbTK%FUe zH}ggv$#y6}In%@gs^#|F-P6&%uBR(+XKSBYp$Sdxp*A(k?;UBp@}&W@q-iB=|qBCk?qlS~0X9G!oj{)5Q{ZZvmhdhAr2l+3JqI$&cSM|t5OI7%@fkn^I z1R8TXg*v_fVO?)^`2cA_UO+LOf;Ais%qMklF4e>7(Q!mILPlrN6({R1ZMHwYx7W7C`M$Tw zufuubM^O!oDciyxhos;7^*}G$DEmG8GI@yfM}g8u;M8-=dO8e5$1fP#JLFbJJ$L==bHua)_17GJdoDm`HJZQ)(e4oqaMIEq&zUp z|4u;b1y+qL`LmvI#5%4%i@|HZv>BM5(X$zJgrlY^#*)3j@)nSq^XrM-R=*|>k$U0- zKi=^%bQlnM*T8Sv3kge}ttS?N&(;&2@Ry<|_JD5?INThh6Y*XKJ^@L)Ur+4E zjpf1wDtxdP=FT30y)e@)eI32Fh@Pl~o(OQxF@m)V>iw~%FABPWh3c(c6l@%6CA`P_ zXNxF+y>=mXgFUvf{Z1>eYn`I?MNe;AZ$V+u2aQ2;mdeo2P-ken0*TcW4V>`=%Wyfb zHB}wi=xq)`GRBhLuy1O;D`sC@(Ku)3%n|7gbJTSSd&#Pc=#4kJeQ}{Q1WmnliGmK1 z*5NS~(-*QX!M0NBx&$`g##eXd6^7?kD?I8`8EnI&Z)2D!N6pF@Tl#`^As{vA*B5)N z{!Jbt%X&T#xAM>emy`E-eDwO)CHUT>n7;6@OLXGdV*Q(OdfkiC@r63D6n#NE!_`lC z7s?^{^~C|)D84Q+XZDEpow>71em~MsL|?pF?2KZ1V{NTegDqLl&C28{oG4WDM<(wt;_cF&|;l{^8XBFLdZIAoBdS z!ZJL>x}-e2kNa(fWw>98t*`@p`+>u)T{atf{AT4z-XI=gw8F9RT zVsjAL%UKT=&OvPZkv8nKysW~Uq`Rl9tMCF<`=Cu2c$PZR;~(u0rfKxvp?YzSnnFR^ z#*z)fx)6{W^v_v1Cd(XyJVe?cQ6O&Rf#Wux6%ct`3$W)voP&!z+XlG-e6|g;1O8Ix zEC<0i2;`iF$aqCQi6KW8}xzGCk~@;1o2c-PvJ<}6Jm@3&Z9WPOw0Be{5& z%Ke=9XGfavQzHZT_6K_~D)H@41mDGm&38romWTU0?eB^zk#l=Z!>*es?pfdTMEFHd zO^l!C6u##fYil0GY?;D3le9Lkx{K)_nfoyBrS9L*RV}s*J!%E7XDJ`{qgo`8=@~uU zqaz$O)iaj#4(mWbYR<2Bl9rwz50QGuKlkZHSQIEA^89n3Qsh+Qfy~jjV|0XXN?pP_5RjVl>k{@su?fgSET&7? z|Lk#65?6gSBfqfi49YVE;)+yy{azhX)krpXvyEB_|FG=vwXu=Ojoci zc_1ys^Szp`;5u!oxB>559oq^@9kM$hih5xyyPMPaSHpymC#Vvp6g zUrkpmM43B40ci<-U2(4c9EvQ+m7BKwS*K<~pnN z@8fs-<|#aP3}5r}?61JNzE9)-a9-^`$4+~F#2y2CqzR{kr7rEohy0g)F)fGzJ8OP)Os;u%zwC(sK=R6L*}Z!z4qyfb*nK^W7= zbV>T!;kIq11Mrt(D;)=463DhDd1l*Xoc7u<=X38un1H0+zc$S8UG!mWhEe$NzNu+s z-}#rW``$VmgmrbczLNJz)F0GO_E^n2o+gzENHMP=hX7uM) zUYw(5EFoKCNe8hm1f-Aqb#5#s84NhoEd$cVWJ#GrSWFb8S_!zrRWU*zS(o>4FA5_*FtBwUh~vf zNqaG!@v8e~?`m6J+M0~}*7~hg-n1yI;2(+3VBHWzXOyyMR#%U#-_nDh%i-$N7M@)? z`uajgIBMGBjixK!TEF$$E9{F|Bm3_EtvzsF$$8hYvIp+2^{aaeM~`VAvmQ zvmCMH+3P0$Im-?RDmKSpoLGv;!$G(Pfn4JwGG0lqz0R=%4;GW>w?B@7uh^W$TjTBR z?CS19n=Ij-&@8v)y(oiThK78bcWOS*!(N=el-Y{y!TCcU%{X+o;(Wt6{;}=iAKOZu z|y#C2l^fm6cHHn{ibv$Iuef0qAwICalopTIvZGU5&~ zJxB}wEe_r#ng4|Ra=7)g&Ympqhn@T2--3Tx?8%nHT~4F1`M7 zTg$eEw}*D{Z#VPV*v8O#uUum*fV6%uq}Un`Z7~A#R_xullBT9@DdSQ4m%wT#p5eJ_ z#|@=@cHaNR$)B$#ag3g}8%w&5~GPupd6^Inl?GUR&2S;vts30Ob(;x-JgB72Yj< z6+YNcjUzh$WR`r0Jp8^p{+kz&*L8fK6*p)9ht=*Z{(Y6Ao&rw={(<#EIrIemNLxi& zB$0X5e;nueduO|P@4SkA)9f%t11+G<-mhV{L66+>%=htE7=%>{gK>{F z{bHw&El$p6WPXDA7U*Sy`erEq*=xvFcF`6q&RRph$S_cje#Zs%fOF~Bna`wq*LUI9 z;yqoSMv{BrjRG&iL+m#fVQ|s92@O`>aWx^F|74+EaQ^4t=cCukO26XDr{T@1zgW)# zqHh`yVCx$y3zoaQ?;#)k3xMp~(h4@hZMP4R$Nj~&ymCvPt-o$E@<257hp^2&TMxDz?XD}0 zEvId_DD1yzKkUB#uWEY_w%aS(#!F=4IIEVrl9c6Rzw>8*6j%y}r4z@TZN)ZJ0BK!b zNU{G2O50|>Xj`dXU3H!%MJK|4E1StvI9k%^X`9z?ZrFhGU|Sdc&>AM3gCUm9nA-@rVH?D^D5?*eP7;t@hP^EOX)B`zv64@A@9Xs^%yAcKR_73qIh)l z)|r@y(c7IfmgZfo2LY))HaS~AaD0~jOCBQIf&Y6a+AS_nK;&J609)P(OP+1FECQdc zZytfa6n%3He1kyFyNHZe(hGTcpdPs*?>o1?ISsz$Mffo9nlqO##0?Dh?e?r$SC+iS z^pL0A^LB=}k1)Y~f~o7<)~f5e+SLth>(%`DdeFPo^&8d#yVd*+x2hYv;_4$Ez3O+@ z-Kko-Iu!Ufw5`9J&#c!D69_8F!OH&W4^|tSoiKu{*B4i+hP6 za~)lfD?yZ>ci)IK+^}w~TDqZ2-Q3lwmaf{Mu3Nua-H5YcagRr~@xG?u>7fIBYdsgV z<0?#1^j+*}T)$eo@a%^5CT#k`tEb;^_4FH=zUgbOnBIBCbe-1eZO-&|XL^?-49;{t zJj}lV8W>pQ{>RC(rW5x*9>{*-0y%!R0NGy2 z&#{>81>zOUmi?d)xD&V+_y8~gd4qF4{$#g8@7Y?>y$+wx={sF&#R3Tf zqwaGQ!}UPsfRyq{S^lIgQ2dWjfS$lP|iFIB=utzD8Ty=|Nkfktdcx2b4LxP(D~6sn zw3-yQNewBR=Sa@M)^nO7&1=T`b^HS%e@{4bMx$q>m>^%v8?~v>>t(+*pva)chRlP? z;TH%S$F-p3n`Qj-KtIL+1LUK3nW3Jk4_%GGGlqvmr45rVy?W#FX24Qqh2I=dx-O|0M=HDtsgU=0xZ9= zHg3@-Er7HFFQnKUNya(mrTDuij5{cD?|TNlZ0Fd*{$>$aVENcy9#KVo>!?(fUt zFQvcl1mAuj+nJaye|@;l%JDXmwHn8 z)Pqoei4^Be)C;zK%W+pA3deQ)m*7oR>KVAln$8g0(@U?kB+plDO;z^(MZw~&sjgnL zdhM+}Z7aK0w0EqDd&&YT!VUzlwn<>)oxe@umpN)`;&t1L!~V}UZ|jLD`~p%N*C9aq z2JiI(`K*BOH6y^*C$uxzKdD1#29l3%PIT@5pMbxV{yzvl@-mKB>;G}Y`!4VZNZS4V zpX($Y!UQUOS2SMbj%?pv>3e+r{|uG>kA6_$V$C(+G^bTEkqO57l7WF}IuM6 z;l8e_vOlyHZ=qLKsl!h`Gv;)J{l7o26%{g2Oh<_RW8VBaVoleYVp_rr2LGt)2_tp% zG{x9@H^cH35FM}(0n(3nZx7I=!+`L$z;Ek{0X$SpSMWPVTUQ*0zZ6~Z3iuMh;dBM} zDqjXZ0ZF@GR}A7tmoR|}pP3u1iLYGUUDAHMD@#9k$NS^nm&lBF%=;X?vtf7` z_kTgVB943T2Y$LM&AoLk&b}=7xyZAs5Bu@ru{6et3O*y@d`9(cLt4D&>}T-)_hhib zE2-iBEo6@;2T;DgeReHXd&_UDsH$nc;N$wL=X_EfY&T=guHhWF0MhEc5b7-1cjtwa z={fPE`3F#=7KGGzAOCpGUzz8DVPio^xB5ar2;6MX1eWbY#BYxQEWbM5G(i6h@qp6b zkSnfl``BaF%wn;O6L1zoMUr8!>R4uyX4Jzu0Wrqn|3<)#8>i6*jOS}9qkKJX2ji^Zos(7 z@$qeH*NHmpqu@R%ogVC&h`9GpMtltpT!r`}k?rYlWLI{a3!B05 z#{TijNh-A~D?HrWfhJVJa$)*TaX&{ik+JI9jTz`^&b5w}rMt%EBsVV?|YU^99%GEBmVe#{%2WF=BoLE@Nn) z3Wufw*e!{Aq0INacH!M2%QT4le130Uz}a@kQ2Bm4queLIT+1uyN3X++c<%2VDsQNd zb_(@d0leAq!F<3_t11NUq5KzW`K%`ohTaW9a}Eu8yXL1J^#Hxaf>7RS@&ZHH#p6GN z$FcY+=e<7vY~yFUoQM&M-$4tI|AWTEb~zFG*InO)@xFfHZ}~fnn}qjoGk&(!iOAi0 z<0s*LjyD9B$wZDE&|y^VVusy?pJ8L`L*BSr(SwZ>YkOA~H_HmYwZ!HLW2@nXTsMzp zUenf%H^F!gOkHd5REA@SndU{#^ss-|Vv%+sDHPf&(y3ls45Aq_y|vT4F}@aqTnv7` zQ(S6j9q(Ui?t@0@M6AUol4on0u(?kglzd`aM&V}t3XqS`45VEa1ri$YfCI|5gr=Rh z1vy8u<9!Z(J|`gY#t~r0djkGt!UQVucEfGQyU2>S-0+e10quCB@D$7MR}7!zm$vF* zgb7HzUqXN#Z#N!Th%n}ta>>VdzXi1O!F~Ab5&|OcFA!kMI{$Iab@`lNZ)%u z0;K)&-aMc~hXLWc8h*Qvw%{T5A$#~km?yfFw6dP_lo!cb4Oos2PJeL!Y@2lJ=7Qs47$Q}Gy$PHmn z$c-6C^#wV;l9gksy(h#TV{375tdFrALkqT{zduXM0~3IInpsB#=8a?SJGIZd=)T^& z&Z`zZ2ICck@nh!Odw0A`FPZ9b7=yj;?@$cqH7*yHvr@+6p`{ozHMi>BHn4ZCjhSozg~C%H;S#jV+WHpJuq<#t0* z+YQmT>;}}xIqU|nS_*c9_P>_8!HZz@W(sfF4aN1s8^CTD(La>uj-uW0M%N4f1$Kk( zrbFxo6Y`qthPUj7x9kRtSD05cUF8&Dxb=paBRC7P&wC+}UvJ=d`T@6DuQOn848J?M zCy0G63g4<=ugS@PJ73>pxP%S224SyBaLzr})+GEoL>q19!tdFJ-WTiFV<`5WwVrR_ z_PORF?=iAj7T#HB>+b64UEj9W{4irhulVtnz2NRHxV^a%&pl&Yq{7D)fI4NPAye3FkDd8v&Wq zEI=JjW7X`=bt0-thbHA1S))2G&Z@iDngAnoUWVQ zG^gZ!i3dDIl-G6KXCKGjyUygkY-bdE)dmuoO6Rl5fctpnad%5{ORPT`Z2fU|3--}{ zE3zl`m+p^KQ(MQS$JN}E+A=qhx^&(>Nqps$dK`P~0t1_8Axl>W@Eu##(2Vs2Yl&dd}v2Q z()quJNhkWAPUmALoqqcubfLGnDsjgPUZdz%Z)vO0X1+*1ZSWOI1%)mf#y@W z(`q1kDwo6Ed1&y6f+wIP9>~oMsOZkztUv<&U~V9J4|Yoj61ck&cb~}J9Z2*k^#|a& zE!P)N18wS_fO1x=&4E_%Z-e_*wLRc~=iY#mSgHO{yK!W3;@#?h;%=A1dP$;7eNKme z9`2P2U&ADBRrf=htG)pDYV}22SK-6}2Qt5e@Wl$NoCtpq*W1)r5c_X0AmkiXL*Pw9}SbtyfMbRNt7bHG7odr9;BQuDm5d0x@6{9nZT z_ql(^-Q&5_fn-=Ia65mKyCle`t`4fiz_Vw`N?gCXWEDcbm|KnO7jn1hklW$@RdqM6 zi6!fF_#L?Zrg}ZD_vbc%=l2WHU0-7 zzn^;r64JSUgL^Rd?;+ORe}q)xOzuB*%6}b-qJC94Ijvqr!b$W>H=IPTjD?f)kL6m! zh+KUpoPYutz-H(1>U-e?dfeZK)xhc8U^t1vZDv`bu12+$C0b785|KomTlIs8a@?w? z^))dm`JNLWJ~b%;L8m7rklMal75&?n@2OP-fBW)gxSx4>ORW?A``SY zx5NFfFYkam)pGYmDjK}@)42AGR~MsD)t4_;1L@pXE>;QWrNqTdgPNL*hE@60q;n=0 znVNvRW@-X%M~Bzza96vVv^%PK7HXcwQx*7c)Yp&d>&^Q5v8f6YKB2Fl)YldI+N$NO z(sJTco#=G6erjvRoho-8;uX5i-_`kmNguZ)ZYOC|(+*3MyP(O7{^Zx|bXL3m$k_Bf- zozUSYaXpfI5&UOzFKY>>5i*ebPh7v3JEP^iYnn7;Cs#J8=!++BZAd`E8r=Qm$+fr}cwrr`r%uKZ^3uumTEd0~ z#`60OP9k}-ub~xo$O{dv2>GSHt1eHp48HX4%h8@+x?EqQU#I@>`+6%(t4khEK-U^ux;e&3AtPVQQg2e3+7VA*B1U-4C}arM~bmbd352LT-8N&mLBZWsg0I z>&G8^4A&Kp{kaa`kLz8JeG}K)ANxy$Z+Prma1RC!XbCs|nToo1HUd-(ex50fZ+y-}F<@|R!YM^rdb;(?!CI$Y1niTneKCNzoy5#56 zT7HqE>1DsC<~&7!cA$M8Y`xq79Yh{|-v|c(vErE{KhWoBH(xN;=91iJSb#9*cOEd0 zK^4~D+r{$?;k=6u&NYWVKTh*w%rn55K>;}Tw7=h@r9ac$cFEdC0GvaOQduO;aI@Yc2>5Z>n7oXws6TptP zo-PF4xuUnN9mj>))7cfb#b<5k;QO}?9kXtW!{P1c4x+Je&cyHfdP$L&TBMJ3Kj=kx z*~c;wz90&X?I}o$iWL4vQf7A~d+qY`-dD?0k!dj3>GYvhzRZr^(*Emqb_B~4MU9r> z0n3$bSwLEF0|HpwQFG%k#xTx1QI%-*h56@AaNF`8g`aItK;$h!fGzJS$fI7MJf?+w zl)nnd$7K$>3A&GMUqIyDg8(ZU^#Ft~6DCmM`!w8kyssc$2Vsnt;Sw*usY9IkuKWsa zUXCyUiHj6T%0nGyS5X9Bh>!_D%45HxY{>(hsuS_vLWcp7$7gK5Y9#C{!UQUOm`BeV z$(rGB`%d9E_&$tlg6F$esSar$Yr33uUI6bO2u?mgT8tM^?A$BS{mdKRIdY9lfOSq~ z=-;g51r**aIAG)VE7XVle}U+^^V4e*;hS^aj^!*MwbOtAyFc$l2ch1OzDz#)7XYR2 zz^QeELx%y8_W}5Ac|2D_`me2*V&Jp&19fI8`r#4q4FHGRtF#L7UJ5<|NxNS^a6PV7 zm_UUO`k`@-Q-I;t*+%k@f#`%50X!kFc?^x^qvcKOeK4}4-uULO) z*%Qdg{?7G(fg$}}Oeg7%uph)J{G)f?ok*sULIbC>t9`?*D^{*=;}PKVm)tO;t+#jm z>h=x2T|E+c36#2w)oj}Z_G8k{rWro;1r4+xY!JS8Bar=YI6fCV{&?-05x2kJx8k8< z{r*}b4@5%~u8!x_SCKa#KD*zu{}t=^v|EsexQL*QQA)qx0lxh}_IuGyB45e`w^S42 zolb`Vcs2O@{YKnqH}^<{5B>hi5%v4ua<4%#yI>@H4(gEhv8ESny~Who+I7 ziT9RWAT7!(zheEp6uZD|DKf`en(pq|1zyiI4R}=T0u$+5c0pmxWo^<<`0r*Hn7zqn zDR201nr6E4k?`=}F5pcWVaR-d@7;N}4(78J3h%#zc;}5}o0IbYSpIJj@7OZ1!7K27 ztmr?-DwW=o^aA;C1`t*S`zNc`zRBfo-{dfm@7tC69~sZJp`T;7JqJPjdDsY-y$(Ir z><%mgSTMZak@*Yr#rcT+eJX8B)oZHT`(D}eDDQj^-d+gge_!?511g7Q#WmLRTzfF` zN6o}|!>x%PgAq>MBKE!Lnr4KFeGaGop9<|00jX*KcT!0_By$9N?cpPM(4K=FgTItH zNIB${G6y*bKKuI`NxOdzatb$!eJ5pf&0THXxAW++VfXmV9KnBwc=iGyuWK$;l`8D+ z&T4&w{Ua)hy*kh}LFgQOJE+gU8s{WZIHxM({o~d9|0~2)1e|SYo^$#C;mj}U5Ap>J zpZq7*<~t5P@{qU8)q8s~{9o)O=(2L8f%|IG*fYX=A;^(?T7Rj@XSmb zcqS&#(;zVKJOfkp>ZaytIr)*S4)gj?vH!+K@hs1SY$0W*9m#tn@5}~?Nh>@ri0K$T zYwPuzV^KG;&)aK13HSx12Dw&h^Bsksbs`{q*C2p(95pv+FR;kD7Q)&lAN|y8qHEw( zCxDCSFd*_i48JXJ8RR(#qdc}2k+&RfTTeDZcqw|a6MTbsmg6zoF6D_Hw%2MJ5ijdV zK+^8llN-U;Eli-ocSYmek)2O|bG{Tl1rmJSR+&+ICEWXNe)cK-oD`Dsd}6p8C1(sFG4pD zHh({LtnT}%0BlR_zr_B?A14w2H-Uem+-+HXR^tEs>l4+Gg;U!ymF_)Bv{4)DIDG-0*@Qi-VYMZ_yZW%s3(tjYnb4NJ z2Z%aIR!8s4Mwrg%(qteqKRrI$->lUAS>6w$%#~W4Leu-sc-*7=OfL5gq&@jfq%rJ1 zi2NZ>IPcMoB_kEt7WItc`q5IeeY@51)Hw-i(g668a{Bn?)83Z_1cx|;9j$CZSSfTIFawx z-c?w*XC2f+A-RY%zb^tx^S86v{YiLp+U~3;0jXWKVS5ZYh0ZNHo;*a3N!J5KU&E=e zQ&UChFd*`-gWr}%0U~c4?uk6^2`b(7BZMu?(1U7T!h9de%h0K4 zZm0ImsR!*oBQ22K#@1W3X<7fYeaS;)F}DDzBcvrp;VveR;kG>NtIx}`_29?BCprgC zZRfjm7?AXFKbb9WDdaf_WBQmbNgs8Ytyed}Uy5FR6nqX6!o0ALQXccqIBmVk{fMg& zCLn3|>(ySQ?=E2i6+Y3cJzc$}t%=N*pOFo3>(_Y+9imtL|LKTeJ(k}G@horo|9b>$ z7u>hOCbXgSk zc1VjCezv*-@GNY;A11JzsC%bspLb!{OrQUK#_xb~Pp&;)lm7;DpM-wsVm6z+D%M`3 zSi4|H4)ycI=hbWC8`gKNi1*_AQa#(#J!y;4PteODa0~Z%%!z>lWookXG3Mx2^A%Tl$kcMAq5$K`1LXE>tXcqic-$_n>}Z?`D}G~eXI-DvU4XQRZB78eei~*YWhs~6SugR&uw_` z<)56s7JGeGZJ56HYU_$T+@QTPtSin4uvk2Hd_RTtoCf~8qSaf^sjr4^kJvewqdQqQCMSekN%A77MB}d6;FmxB^B>A{y;pD;j=Zn zccp))Zx{2Di9=qsW(^C5<`?9q?C<~+~{KUR&y}LE55Es*3;UrQ_hZ@+f z|A|4_UuPb$P7+RR&xV|%KMU!6EYW#Zt&$JVA3(aj=M$OzSVyzdUmo1`bEf^k_nuCD z8+Z`t4D8bJu&gj144a29Fb~dy+19_re?*XuvN+ypBodhz^U!)U+n{dB1X_=lu|95q z`&yLo^$dd_dCSyAyz*>mO-y3h)iGcAw)wk(r&G`ck!rPla(U|yCS&ZX2t^^=#rhbY zJ1`Ato{2OAkw4aF_6pS9b2Il%{xEn0>f@OjcYC%zz8(KJR8zuOf1><){I?~Bf4dwE zAieI5$paJcpEJJ0b^Ef)xhLB&h<}n`ovj``srN5P{{VJK0QvblZI66BgSFs_8}JV0 z0;Iu>Jeh68e_sOdEBKotTeI`v=bBa1;(gg=_-?vo=DzGA#G#^_(a!JBF66h=(R&cr zmTVZP+ii4fHi>5(l*PqpU$v<3acbAkDuh{XwPiF3CL=NoMreHyB_&fF8ep~ z+qxP3WqbDPxPJr6itnMyohP%b%j(3|Y$eJrg0kC+`_z{L)Y-O;$IqCZf)S+kI>)9c zkpH*kI&v8Qn_-&6NGB=RPQ%FukHdY|USK{ez_saftQp2a%L97R(282s;lXD9`xYKZAxgp906we4pcK0XPa4fbY1FWDC6i#6|OLW!62;JI?-3oXx;@U_;}3n;!Sb z!|;I5qNR;Gl)pk74Q8w4`w@lyV13xv&S>fwWp`IQ^nVJ;cL22@!u;&OnZBg*!x2Z41WB( z1%E?TE7x~*(LMA(F1#7PTlK8&>1bQKlJ|SpZNNu)5N<6?GcG1Ut>|pKyLhn$h0VGlMmjZ)Zb8 z*w}Q4)#65PruF)tYc6Y^ji`njfdZ&f=rCBrhH@T6*a4)z5)dcnSfhmEDJwfsusidFouzCp= zTLD5t?y|gwJ|7xVg1jGwm0*L^vKK}hX6SuXjs?ZuVOX~zf4uK`w)6tfrr~^_z?dhX z7qQL>p1({@^SruEO<+&y{gkdUJ)~NLl{J8QLz;PxdY!UJ&qptd7S?JtABm?^^FyVl zK-+rTW*EhL{vTmsnA5c=`ht5M^B&w25P5#R!~K-MCrqHihy6dZ%%YM*7*6jrjo?2M170L~ zz2p6XF~M)R-*EqJ;#g7uX$4*g^^y(LGaP>iY&%?!R~uHK>vpZz#y9?0y`iUTy$M;j z9z4}R+HM?!N30w4Dz#7KC>l|(w+^s%PqDsuEy_&VGn{(O*rCIK)Yg3X?LNB*53x^C zCToy$44rSLVK8$*0}lXP1MooeT!x)!^9*8`k1H z&+bxeg*i<#OI|lV#)fFw3f!}IOBB1b<^!973xF*^6#6aK0Y3;_2>cN6dfU<|kzh=RQZM({05fgc58A^(<}fy;nUsJCE!`j$@sQQ)^g5#RFrz!ge4NYFIk zCBRF8b-?MscL6z`)C1oGybMU)+5lvI%>Z5jbb&L0980(_iet_kAlC=30#e7%1zrv0 zcrp+8KH&R-9{@&y$i71M^?Nd8Um^Pn*;mNEo@XKZdW=E#^?VcASIE9X_VvC7WM8){ z&H<2ph3qS2Um^SY8~~0d$iDt>7uy@hp<95+zG?-w0o#Ecz)oNna3%0o;40v1;BCO$ zf!)A0z_q}2z&P*@AoWZSuot)icqi~K;6~uxz)t}=Mr;Cp8i?Xox1a#rjZG{Z#VIGnD{$P{2eC#4ikTeiNC|d-(lkKF!6Vo_&ZGe z9VY$`6Mu(^zr)1eVdC#F@pqc|J5BtZCjL$nf2WDR)5PCt;_o!^cbfP+P5hlE{!SBr zr-{GQ#NTP+?=P5diO{3}iTD^2_>P5diO{3}iTD^2_>P5diO{3}iT zD|P%#OBl$pu@V>oRs(B*wLk}02c#aR?qy<`AVx}E8U?lh7XlXnW5A`rWkBk>Rv;s$ z9;5Dx1ABoRfz(BPz<%Hk;7;If;2z*!-~+$}@FCzMz(;}mfd_yGfro$tz{9{Jz^8zN zz@xxpz~_KT;Bnvy;ETXhz*m5$foFgmpu<3ZyHp9JU0w~W0oDQ?U>&d?$g!R8j=9gj z2{;cJ1-1Ye0%>!^fJ=c~XXF^)3hV@~0(JxAz+T`+;3i-nuphVsxD&V=xCgiw_y8~g zdvv+*azGJ+zs3dOaLDN?gt(O z4gik;2Z6_cN#F_KDd1_K3L}0X_p8*Tzy$CS;C|pi-~jLla1eM5m;{~xo&uf*sxrh6i~wtZ4zM2R0-JzQ;6h*wxD40| zTm_5+Hv;>BJAk`^dw~hyBf$N@gTMjc5#S*37%&Mu0Xzjf4Gazgf!7v-;nx}F)3AI~ ztd9-1{#Bk||5E7pT;F;pvaSK`aDqZ(Fw+iiy$kOLI0@13dW_q!a}LXkVx%)HSrx&?ZCY85%XT#n6R@E;2M`=u$(M8M@riRzo`tU1eyup>acd4c%zy zCPVuS?KgCXp*s!TZRj3D_Zs?up$S7DGV~EcA2oEpp$7~-Xy_qB2Mj%I=n+GoGIY?; zqlO+c^f^P5h8{QcgrP4QddkpO3_We=8ABDuY+e6`mK$1WXvENJLu(AJHPkV*&d_>8 z8w_;~<$Ddr(`4v8L!*Xr-#70sG<1=nF+-Ocy3A1Sb0mMOp`C`VGPK*!xS_pKIyQXuY9) z?@qa{p^b(%89L9q5BOzVCX?Z4;eaO=wU;T82Xfg10yF?;JPsxop(!PlxdB^4pQk#@0RAZP@oZ9(#4U-%!P3 zX|$<|aeZ5p;}BM^a4tv0+*8;q+Si|TWBu92cz>4v*9rWO!g)d$;<;w$Xf|*S_LnN~ zxc%AOr32aA2l~?U5&j#v@vU?^3iq$!R+I-G%0a1Tv^;f3hUbnf)Kw761Y$T7gnMUO zK@rwu&ID-zk7Y9We~#qUmWlQJ3KdIcPT(0nFFcf!#WUYQcm!!;TCrN6 zL0iUufR?ZvFAF#~B7GlCO=aE?f7C&nz`oWdq&w^;QZDk<80pW>Lp?UfGTF`u^P9*7 z)C65;Vch>A(k}VKUgLZ|B%jO!^P<}o_WUAmQ<%1L$Sg;l)PQ~!X=K@I`S|`nfO7@x zIPhKl6#R$iq~z^!_=A-bGXqw9e~tV61`FxqnKUW$E!Ii)0`_718?0Ie8h8ZM_n!p4 z1}OKNP*B#HF~wwCyO5W~CqTbmknTEQEfjW?6os*z6oU=ts9Qo}T>otgi(G;D8Wkg%Fkre(WQj8-p<6lb3 zLGV1k4VIF%wp8ZJu@GkR{w8?W@1m$s1!%<{uw26kE2sn31;$csdytPk zuLWq!i(XN=7xfJwLjO)RQNtsUf{<7d@n?tmP4mnQ-I^C^h0kttR zjpIJP*;(#xO_yWb9B;{=@U7;AJul+lc`g9ei6ogmuF+fKCi!_!EOYd2igN@8?YJi zEf4HC6f5!!dls_zU5#tL)utb1;eB_5@4^0!X#ybqLu?23Re@Txv6iZu{&8E&wuQHc zcHnfL>#CgKO%+u&%@?%mtJc}V&;Hg@RoNff3Qjz@w4$oA`I#s2rT5tT9}}iP7D&(a zf@nt!y+2O(GwKNs&|xencCH5d7=dL-JHfWes9WBx?|K*dXZrj%`urP=pJhzDfqOj! z`21G!fYR>`vFNt>fnSe1cj+P33++w zgXeR3Um@-6=Qba|1L`fpCu3>%>b19*^4<7MxAb#77J9}(ek|qwKdvv-$M$6v=Cd5@ z0?_{o-*3v;hB-QZX6TI>Sf4OwBA-1TuTIq%3b0LFDjrb!p<})3v~(;3JiSVn!sg+%+|H-_0MB7#dN}vcIt>k&q3Bili=4`d}k(omOMo2h87@h<)IrcJ}V&dq6n~c4BxSdJX>ci1|Rx* zT%O+xM=3hy2>1qpwEc;USLEBeV=v-;5AF#_+Wk6)@A%q;2~_y-T|lEb=+hw#Yp>6q zIZHD-!=FvT_eX%dj-kCCz&a+r_YXC?eXzHgwZ)mnNFQe4`?CCAfDbrav!cE2exAB0 z)aYz6ys=E9+A=w8@sb~1V~9OUzd#)vw%>(+J}Yz#txv(cu^_DL*~y1Ui}M1ggNE{t z)BN>${wxlprdy z6}NV;Yj5l3$Gc!Eu=^Ho9Eb`+;WF((2xhg=uk{@Cp6EHIljpK&zH)fZZ>=StY9!IJ z-X!5~PWz2zCm=0})QAxs|4LTf^&Z!@e-QXt#8L{)15hMcH^8YuWFjx z*51+Cwer?gt8cr#d(GN)@jKS{^lrHGu8ntd>%Tg+;PRh8m4uFM#X3MAY&_U{Z&%+v z!Sj7C9H9Hr6ZDgY)K^Xf-G%8(^g6-L<4PsAsK`@UrM|z_!OzbFvFp-hyCEZe<2!thqR)5P!gpn==)VE$ zc*DSRpv_ga{o}We+g7$cyd!ik)*TjAEetNNs%3i+V4E0g;{@A&0hq!9@Y^)@j{=nG zzH%%dK!dRW{B~_9KPSZn;5V{1@SG0X#scgwct@szWy*6mrWrp|#&asv1~z@YgRl;t z!mZFl?ureoJ6GSiW*yHY=6&$C0y(#5T7xE;7h#UC#{pDI4Z|UhbA8&uQBoR3BN_+t zn+=#K`MlOTrBf%y8W)(h(X)^_FQ8r!T}qqY2GJQTL%Kx|or~|?;9+|hj<3PUv-cxR zN0_Yw|4`ySF+hIopj}=L zo7?}6xL6p=(SC1CzX1EI-#@ip0C)uVb*(rUs|{Dv*i|m zwl@1Ifn`HmyYQ?hXNtb-U3gF0jK@Dtf7>W5`dQN?^2-OFpH{cEa2oeQ)e7UlZ2;?r z=WkLD&#TdXG)VC?PTJX8-=Z_u8Gk(~vo<1qiw$1-du5Z9f@YP(jhb?Oy>zRKB4K}( zR?rAH%TPdC6T5(|lWNfaSmqpm$wOrE&Ij7^7Q$al-un=4%d5BKF)bpGx>fWEocg^Z z(<~tA`v?MTd3=BBAdKl_x!owAbiJjF64o-3USje(lk24c+Nx9ZKCiRRpkrPI=pJi& zaH#DkEx}81v2{+d{g@Z(G3p2b)}{H?n;d&k&`Q`R(uO0x)mn>I?k%vfs3sCwGoGJ=*fC3^fiU3<)Hy)C{Y3q{3;IsRF zEBvMO{oUZ(59GKjX%zW(-;W~RI`9Zc+Wmch6K=E#6R7ZE9rMbO{A+gR>?YIshhN8R z^b(ry`?Qz%UcH;=;YP7HkaOu+B6T6=wuUZBgh=DfCyY%L& zjjdIcL;7hw?zix4%SAlZa_s3O(J@RLTQci@k#>9jyb})UsGatLlfF?Lt80wIIOOr#m2zZHe-1efmlGMR&oezh^JBbx)5o{9`~{ z-d@Oa5azedZbO)@pHIVIihiy~B1%~crA_!j$P|#Y`}Old@aaWH!zg^v&m;O5_{=$_ zpJl`EVE||8XBE3I8;nASCO?{nUd3yV#hI#s!~`{vz!S?e)ZZcKSZo8W*u?oS_D7Ws zQ1?QA0}r`Rr_cw#vyuNVOC~ea@8tu~>%i|Oy>r2_6BO^MpwFGepD3017QWzz8#-P+ znAh)L{Q%ZE@k|6rnJ2N2>JPd0$@8hP*I&kgax{mo32byzTv$@IG0r_!7c9Z(fOR)v0;OJQ@&2`e?cK2| z_Jgrzw_@6AK^S`3I|ITClwRohI7STRAE)`LM?H|j~5qL4Ffn~@s!Y)_#Ygt!g z*>Q~ESwaH5Po=-M*dQT+#YPFaH*}cr_CjHtpx)u0C_Nq^6134FmMgRgfQwnX<0AA&9)&R@~%aIt=A)vS8SZ% zxlp1*DWeXaWpo%2d7psamghj8gE0R%(Tyh&TV6pv}} zj}uWOVw1T?B79fOaorK^N0?Lkegu9$33zLqzyu=b`-Gp0~O@zw{*GXRj-Oz2_~4VCrY5a9j5&v4QIK z{c-xdP+?)8qsA?wp7XkoD?NEno_DBnrhfRZUFXTCXoza|LPt+Ck0slk^(!E)$gh_- z!A32nm$|-S>*ap<*&YN$-U0;JdbuC+is@zAnXdix6E5VABXjlO8jF>#Xys04L%x6LyuHcVm*g@(YT(%Z``<+ zGEOZ`RjOTCM5E6mkaGqq@xQ69|AO!I^g2s2^DC^~obOtFL0@_0*IZTIU$!;8Ewmkb z(3-0r39qlHs&2mE4Yg)JR4+>p@fycy>TR~SVtQNbYR1Su*hGf``lH4zdflFz^1iyW z^X%0b38K|aOS`ayzv8a-t9!c`&i^0L5EtH|s@_}EN8v0)6x8{xq*#n{K>58I+d>c> zORwEj6!u)`wHx@Oyw43#=ec$x$wCq>-7leUPTg3&R7 z3jgn^2oC!PpTaoJiX9Cbo^7fC(xSZ(>i(hky|wtd`~$<=>|EO?u)R_DU#xxJg>AUO z=bz*AbDtDJbiY04G`in2g{`-@oq3a4YyN`oY{hTPXnWtCmnN>wzixUzpJH3>o22TX z&aU|M$-KbhWXy7GvupX@zVXwvEm+5sT@4wh8JmX^oGX_5z|oVcSVSjMz`6APM}6{m#-f8TzusSoFsQ#ch=$if?=KPIpptgK-sd?eJbOey_@MV? zBTY$qf9{pC>27$vUw4U)EwA_Ap?*i5#($_g-Opu%eX#R!jt5vO%5esW+6}}vDuMlY zzuTIaP`>-#iSNWcC;ZNzUv|g-6zZxX9J^NU*FoA(hSkj}m{~aY;;*t7U>-2e%meTb zW1O=U&+yC+exFkA?!dWUJF=(o|KM_WZ#I;_f8$vAPG^4ef|hHwS}KHj-|jHy^=mhDcfSYU>mbi6 z5lg?w_tjDCIo$7kw^NPz4w?|)XCgmM@tl!G0W~F{&s3YB&s4h> z_jv{!+B(i7`EoWm<(`bbfAtgk{-Ma6LuY3xHg z=-ZKYaF*T25m)e~eP8?)+D#lvU{jfg%PlvC+~?l$gCptSLZLy_}p zGz?jNR-CWK%X>U$z~(uG`33#;Rz99XN3nTc&CU2}o7p^POjx%GAB3Ox4_Y?{gkUT5uK*()H7zni7h8a!z1vBZ_wCZ`SrM#xV6RH{MeHTvKhl{$e_sE_m)B#_ zCz8}X*+Ms> zk21|)LY~Xn_hS>&$a?_!4!Yold&19JcTN16^YrA|?(^9)=|< z_bi(K6s|onpTQ`{kfoV_3aB5>gFiZeyhk>tXRGIt{#XV&t|Bn76Mph5OrcdSBdBTp8$2|^2}ni#bP@1 zTWCjidZ<5ZA-fOdFqw54{h&_wQp8_5ur(?26?Aks20e}RJ*V~a^2|SjzgQe!LLAI5 zWwU(3s1KBlUYE1W<{08YIj5`C=S~E8KBv1S5pcKcXZoqju~%7-(Uik_ZbyCbe5`Gd zFZIbfmwp{VJPXjy7$@7nFHi>6DEqK`-|=d+p%Bj9S^#`v1^OQQG0L|LeWp@$0G_$p zdj2GzkD}aTtp7d7x!;#Eczze3zY@>s`)E7i);-5(N7y%RO8pSev5(vging4$Jy`D( z__6~0<6_Yy*D@(HDsoVtI1}_Z+F(Yv!5G>g+8=p1ek}(d_1mw1jd)qE&gYL~4HWHZ zN#;~QeWMb2WxrKUdz#_8>@8i_jPiRg;-D<*zW2jVo<56bF2eYYZ@~T0@ypOA@Q$-W z^l_jM`_tly%*@~9K0|#y{*LX*?eWb+^z~(Up0d07tovXYbl_y@+fc;WJPA4%{#}#t zY#GMh;Khb_mBkyJwNmAZ@i2z@Z?puWD0HfZZ<(Om)L^I7vuz{+0$VbnA1 z_jms$H^s5a<3CxhsBh|R);GRU&QSNT{OjMlFUvZwyJjE850r5%kzxNkaOu;jgC-uP z=K-`?mMPm}v(=V9W!!AP^Gv&nn0P23dkVAPK>SR1*+3%2Hop+{9|g9wdNvnz!DVOz zS}#Ok%ODTeBmY5Ajw4upoZ_elvvsr3uHU~UHGLw!^>)H(v?twOgYMwZw9a-{@~pQh zEJKciC){1>aj^x-uOJ@}O-rP<&e)v#+5~*h?Rw7!k#83^8=vLb$N@b63ZIWarzzY+ z{7NN47>h8ak7fQh%0Ogt4A=p=S}!7P%IHNLsP~fy^doG$AFd86bhXWC=8t_cf;07a z4+FMm2y~u`+?%D{7>Ojbt_;IZy@2!bw9cb0sz7=;{;~X!wos*$2w*=Z zZS)tIwjR_u^`FF{^)lidF)S^=R-BvD~fzG&m0>zGd;-fOIChm ztk?N9>3h-2?^VU}i#Y#Zin>Btp2c|cEaUrqq?fw*V~|%&&pVWj zHsIy)o;1^N2kN>Q?@p9gHSST~!x#&S@l=|$+GQ5SGmU7U!2z7XjCyArEhvM9NMB)m z+?>7vd~7p+jk@CV^U&5J>`N?Tr%#tL+p5$%<|97|MEcUp-z{bAjlUd2ImX##Y_}=Q z^8$!BWS8+j{~G1M_)NRi=|`N5A9Keap1zXhyd+aO(67rGcEGbNXFc9KyR!fBYporBj*DH}nmKV$A_fRgn-N(+|?sS=;-7WkbDHE^V zUGggJ&h8UZCXADPZLdl9ka9uWW0@SEBYn*)cWHmn!Me?1>QJ`m)&IF?QG z8ICjcxUa`=jGs53K|I>_>q{%djk45ZlPzD5L6BWz?&oGsmKjCuy5;Y#~p;2~I?QL$qlw zLHT;|dUFttx6dQq#HF50*zNkvc&*zb&=06{J(i;0UjW~1=Xs=mNoEh?M4!#j)(%F{ zE(W~1T!?sE6xKM9U&hTd@v$FV*P|{IsYjH_KQdq7nFHI2b^+&cn7?EiVW06VR~Kmu zI?brd>#`gdIsOGPrUqM4-jQ9|A0Rz^K8iSQEf$B>R{l5Sv5lb|GJ$JC>2Q2kwq`fR zp+2N_H)Nx&vVDj8_*khBiuX-lT4efCI9{+P>U4S^ zM7psygL2r8{Ijiz&7+(x+OAsjE7sx78LY|792ZMmdbDky4lj@G$|hK5C_lyyTT_a=-ILY8LV;^Oi~AX+T=*BM)Xnt=A=K z_vF_o-G72kM_HrqvEHN}16cD^aqqtqTM<9X%xmxQM2h_}KSns4({1Q`9Gf|J{1dn< zAWz0zv4v)!U-LPcKVy!DGl+kx&me{^m!D%PH>u}imw`6`IR~h3P&TmRv*GxC#{+$A zhc~Cn;)!pvFV`cVE*9;p)ljI1x758AeE%1SCQ^qYKT3V@pKnNqu{QeMfur94FtEPR z`Tw)`HgHyz<=+3=Z^JM%;pWZe444~3ofLJWlw_0}1f`(byr@{18$rV&9Tkg`^R#(& zRH!kj&@i{fc_I(z97^<%hiZI19KsGN6>+Hc%k1QE$f(0pRCIX0zk6M4&zkL^*3;+z zoX`LNU!U3YTlZS`y6(5@zV5f{zHZKL*gE*R(qm6NR~pF~4Wql)G3HoX?Vyg2PBLfN zO}TPLhu4j4<#{W=#*Ve+9Pd?krAwkcKqL93@ayt~@=zU>?nqD;Iv0d|dA!dv+BVLg z7`k=rPf9t@A8T?R#NbSN#Zb=J7%W-|^69dl64vguPPZggcctsD7V;*%?-My$yEbt* zX;Ax$rj-L%HLf0TM?+`g&iGxiyU{A?vj#`qcY8*H4-ZiQlLn1`=73}5}NY4&~J=#2_LaGC(U4`frRZ+HWp|20%5|MK5!Za8oU<*a;-q6I1XdukPj z$<)v#8%=%bH#`3U4S#j1_k$Sp`ugvy%@ZRx`ljb3FVMGP%9gbvMwFo|#)?>9|H;~( zS>M0@_g*o#V>j#`+GmfUe9!28?bh2qWNz`Y^yqJ>d;ckOi?@f6-*?o#|9qW$L!DdY z9$X54XW#(kK2+!a&pJ121hq^4HR#o)Ix>Xvd4sw2Oz;1y&MiAh!KL?;>fBzSX6mn5 zbC8Bx+r8$Nb35kUviRJzH(G|ZZoSr4e6L+J@5YbbdhYlO(__6)U3be(*SY)iQD5q~ zZLx3I`_Xw|?T*>lWYEA^oVj zlRf6mzxlQsZb4%zbOy+4nFiMpBMU{!KP-e$Zq$(@wRrSVxvCFP=Zl0xtDPfK?{WU3 zn{ExqixDXKJ`&?*1!2n9n>mF6N1C!2397!z4q2DsI>Ysb%<;JQ^cEa$G~8sk*>H>D zR>N(E+YP%7pElfKxXW<2;T}WgOI>*T4U2|7hD@Tm_lFD*8y+z{YIw{Lf#dwg4I2$x z3}r7{`7q3|)o`R?%5b!y?9|Br7{j#TIK%OV%zrt58N&M};8m@`~p zxX^HsVTa*j!zG4G4fBR84Lc3j7<*zky9J3aT2G#2B9r+eOXbGOh8jy!{POd&#PA%lvM zXR=1ek3`V*2;V|EH-cy352XhAd)ja|JRtWL!~KRdNACGH!&dYr#HN1jG}3=gyTq3~Of{Ugt&z6yEYA>_LaLf-EMWj}DgkU@G;_(tMw z&kq<<^}SQxY`U7~_(~Wf&-Kr!AIbCek`FY9+l6V<#Bc z%`45_DI^UAb8i$f(EKxXKWj2PXcBrgfqI(@G(gQDVojXVhP=`&V(4vHkum$hE``bC z+BI$j=f(v@cpBU)4q<<(QRGqZGUN}vueZNF)qB0>9=x${w>^8Wt@pJ7+09kc`x;8m zSvpYByU+PWq>FhE<`dettSw)|-j4;G+ZoLo&!hFNqZjr8Ur7!Y|Kn zF~8!)%zNL}_;NJ!;!BO0VdXCo&gp!&0`yWptj38~$HeC9>1pQqlB>&?Gd~kUZ|K9! z!Kuy9)&0g(LF=E%t#fu?&#%94>z{Sd?zNsEoWSoGm@~MSu2OI>>_#Aj-MXI~^1r*E z_hJ8?w8`uFg`XYZnv6 z`hJ`>^)z}BDnrU+{n!zd?X1c~)~Oed(*4ZJ7ZP66_VkZSnwR%d#i5HS{{`v$SgS-o z0A5*Q-w>sy#oR}{TYI19IFrD;qC%Bu3g&Ci;r$2jy9?o`%T zJkd^FQT389q5?Fd#JQzy@f6QkGmU6YxNsMGPUugh?!;d&KmM3G)J5-nup02&eB8p`*1)s69 z7*B5{AMUmJvvt)3`>ec<71g8A(!8PS)x*%LFGtQdZTcL~KkKztzKGur!itSuQCyKi zpMd(+!FS|URe60H{!YRlx`a(@?EWsk(feq=vm!s}M;(l=>8z|A+*}@XO8%$p2Unp%&b9P;B8TxB; zNTO6G=_voaDOgo8eU?fTeiQ#uj}J~eXW7KOd}l10TOEz( zJBPx{gRggM*{zNi>-24n@Y^0^b)-E3)NU!@@Qyf z3}u@90CLO8tQV^5c^|wxop%buoo~!J#|lUCFpfO*Qg=RsPPLO)39naPp)26R`HxUM z$DykbPK(l^d>2nNrtd9DUaYcwP3BqG%CR;=-UR7vwC|}4E-&=`?|8reLZ2?>+b55H z%{$4Q4x_oq$_jbo$_l!!tp31S$Y+rYlv$hVZ{FqQ%nIjJMp@I1E*aIFU@bJE@P+~KwXl-pxb$rXbRp0Ajx?^y-#nt) zF_C&8z9gOaXUg-Qs@J`{dUkqx`MuCmpX39S#X>4dH{;*{b>GFa@vrh*!aM!s_e8%n zyzB3GBL9EN^Xab_{n)dWNcS^6arPrbjCbSdW!1}g z7x7q^_m)*7nc3wpQ!g4a^if-eRq{7CSJht~h+I)$7NLP`yS((PsCQQbxc`sTmDI5E zIp|2Kp5@`+HBXGFI$4=|raFN$l2YEV%A0uK2)<8xW1#eVRsW^)r@Ftzd$Ppb^1&2( z6n7BTZ#(WSDZVdICmJR+l%p-PD)cYfqKlrbBo?i%NZ;styvuthS2%mUDW7|`!rA2q zi{pB~ZzSDMP#@(l+I({5yZDp-a&*z^82znSgl8vz?Af8;g0AH5Ai{I?Iep0x_Eij_ zPL$!t;oszYmp1xc9fSQgtYa{B1D=;&h}wSnaWW@ej73z>NR!%NwXt2?|D1HIja@o# zMD;?_9#4OvCun2uCJ$?EY(86V2?{V7C z9Pw$P{fv=Uk>m?K$hGR2)U<7wKbWbeKQ*N#%&mk_4%k~WpDYG;BnMZel_i?1|VjYA)-CZKU8G>h4L z*jG^~eel$2<+s9PEOb{E&G=w~?}w`0Ph@H9$6ikP(1#&ERlZ73oP8DQN1RQ1m3E~^ zWu^8~ej6#L^-2$AAInTFZs1;dJ=t$R??q0n2)CbI6GtTI4>oO>F`~LYGNQVQevb0d zOJ~dLq5Cz$(f9E@@kuYQt|I*^8a4y~dK0q6%X)cBrk5_Wc*D`7a_vlw zU+E7j557bBiC>jJjAv^6`Z>}N&wrtZ8P!UWHTD{>vX*=k@5HNKwzK+J%I8)3Ql&GD zPo?)4UFP$tcr)PBt{Kf$$N%KR_)%(qU!;wFfpO|k_9zu11M-DP488iP)S*sG`;X9- zQaP=2X`fQ;P4^s2_p0hzc=Qg)L;Jr>->SNQD0N?#*LHgeM4?au`$28*jTu$ zsPFy-|4Hg9`;%&Uz!<%j2M>}5we}qw4d(`Vkg+^Sz6d|gEM=p9T~+#(52~wicwc!S zd6Iw^BI5C`UV9JAq?<%N|0h>|>z)6AC#V<0A61_ubp7Ud?_7xD{E*^Id5$4YOP3K| zdVP<|Q)PWKv{Rn-}s9ok;qbo`%8{ zbX`ACqOW{GBpE+V{$HXVsXfuyS2_9 z`VkkWFVymHR9*hD9@d+G8Vl9(Z%%1ukbi{HSU0AL(9sX(qCr0qkNnpJ|Yjg^DYktJP`=+=XO>>aFTwocgHx zTjkrsr=3b$GrROo>bK-gBW;k{!FV8Vk(qA`>Y=xyx;67u=|Rd=V}jpNpM_)TrwUI6 zGZ&m%T?!8}RxZ6Oa$=ens*DM5DfNJpZyeo!p)Z~1dwqM}t9;9xv@aX&I}~XSZnN*2 zUnL#!x^$f4`WBz7zAYrjB*Q%K$?7g>uAex&~`_1=z-D~R~?FY&-bY9 zW{l1_^3G~|#BaOTlh;v=e@S0``yI5oYHKflKlPCITV)rA9~V(hL2T}inbRG=HZ7;lqe0J?oBzd_j zw+Q==2Z%oDj(g-6>65%xAHk)QHg7;~Ws%8#CqrG|B(s9|BdR|qPb0}f<+q^9#xOi z(tBp^P;FN*f5@~gJUO%SazA5o>4OF`=DFV!SMvV@pPg1#-%LEFzKQgklOJh)89E1J z)F1VOW0{r3SawP=DDOuoFV}97R_2)eF)n$gd4L4_t`qoAWS29qh-}W@Sw+wEVCO{f z|GHWoQJ?Ia%C8*bU+Sdhy4LZ#M0`eD@qufmmDerfIlphJTpk)x{S>JFJaZqU@$)rW z^bZ(5%&CZfM#1mF+}4}8PZ4%J`-L9Kamm?E=zU1x+Pvls$_M5`19t~*^_w)dkLT{~ z5g$qJh!@uJ8$tZ~OUwHR$JJ~4jLJ_pCb2yIF)~bit9YnQQ$Fjx`1W?vq;|J+B6Xbi zdS2z(q49yNo>BTXy1DAJG^UqPzx{c|8ebxRNWW{7#f!nbqGb02(BTxA3Nv(W-08|b z7<(3;EKOJ1J@vPixp^)(7NNiOQN9c6c(@LTzTYR$R?ef&k28K>_gBcG&|K1We>Re{~GT%ARltPQ=JI<+2WJKjOnF|zHZ_x`MqS}h?mhN_vhO(tLaxPt_~zG z64W8lQ+@s&arq8>qjqNi?<6lJ!{a&nNclqPH+-J}HD}jxv*yWH7BycH?V=rkp1!H4 z*O+BagKsn!)p7HPY8CpD0jm3&uhbZxHAvFk%AQnsCPH5kI`L#z&rbFuh<}zwNF#d^ zzD+(U-2qQ|1%Hh3kM=y6;}AbGemW?5Ex8@bS-W9!dn9EQ*SIx(M|E}DuNy&|H<38G zGW3R4c7@9BU$_tI>r;fMJYzh0P;+X}iYK${s}b+E%Grz|#}oE!&JE~57un0+TV+m< zI&^u3wyYE(E>XgalGgF5&r^41RubGdq?Beq|75?vBlGP8gmF;$sl9ftjL8koN$~3Vq)-d02+_Vyqh{ zyasOoIt2p}`qC?X1Lv)rnO)jY(vi6Em7FZE23jrbe1t z-Y{lTL$+atl#Ki82IQc{0R$`Kt75CsVV*pwbxzZuuY=}m(gCw<>hc#qxjexg43Z={b*R)ns&JL9Ii_9RY8cwQ?7>|g%-*;?Fpm;YXK zoq?P7-kU200C)NC7l+)z8=>@@`-bnIu`{>kiIzKb>AZx#{u^C2Y&8RRxDB0sf{^e#~r*_GGP0hv9 z6ZgyN+_ZPKOYggCF5mygI``k!xgV=@)Be^j(R;S$^6Blaa~JE}2kPAaS?4}h=WdAf zK2Ugr>)hkao#UPKt52zWe|nvJthw8r|3>ef=AP=@l<&u{zjgk+8+#8(x^~{J*Ij?Z zl5@wOKYqMadr>fR9-Pkbt+()Q(IW0;UhyxZMC^`G^=`S&$7@V;`I?Vid(HgYZn@@T z^Okt%8KbuB@#vPtHw8-3^XD&eMjq!aP|Q$_TYQt^Re!eqHS-sLvg5jI%*So=asyh> z9rNZB{o8K*@O6vl_kQmPI8qq)am0Mh=CBE|P?lhPvNvL-I!jbQm{mG;A?U8V)mTH5_S}G8}Cv9W&7# zW0*D+59;}N!wH5N!^wusWjcS;4YP)`4d)onHOv_xwf47VG08$NBg!*G}3Zo@r>dkyy+77cq04;UUY zJZyNx@TlQ2Lplb2`5Q8~@7yhhNyA}=DR3luX3~oui9DW7XGHFW!c$nM6C$v?g}i5h z#J%4g2T@*Yg$G8aJa4gZ6nrl{4ZU6Ao8fbsBk3!zqeCgWvPUFTdno>yV<kQW$ZZIquZZzCvxY=-v;a0W8MhYSxJ9x*&>c+60ve}x-2Y&2{!Od1X|Y&9Hd zm@*t~*lsw+Fl{)_aJ=CJ!;Il%!>NYT4YP)`4d)onHOv_4hWmwlmuKcvctkh`9a-+>Z?ceZ))}@VJM?^s@EqQI=b79JnXA# z-`~^V89j?Y+rCe4>o2Ho|KI9dNA>lCD{eQii-*|qGUgr+|F+XkP+W`({2$GQv(p*@ zX-eF+3tBn57XFHCRDDSgMb0lh2n7pAuadZMMD=mhj` z<~~esHuR?QEVu%CALBuoUS}wNO}q=}t>9ktqWpAifF4!6b_Mh{@I?NCs~dm20tXoQ zThDzs+ydcdc&2nvRchgWo%cLzjx8r9da?|JJwpzF%9P{V=kZtESIB znA}P8U@SlF%ea8wIDT*C_cneP@*B_Z?fmBPyO!U4ehc_r$M1T6x?V4hiTItw?-G8K z`Ay+>DL-B9{BGoT8^1;Ndkd&5(7E@vWXq94p)}3**=vqawnCzs+cF!WKVofe0d`1_ zrS_GiM?IAFrKr=vAL4ZITX-*ft<;sa1bnsKSn?HP1Jzatpecil^oyWm`1u-Z3ASEmq?BmF0LAzv#n+ zZHw+?u6hYfy@86Q-=fgH-0@iNyXm}}VDGgjuZX~qpFN=V{=L>O2;eeoa+2_@a@xtGEQ z$f)JT<*5~{C9UsCvj&h(%C6{)3cBg{%Rb&0n1dbQ*}OS+MRo6GUaYp8&T=Eq#Cx*i zNVyM%Y}07?A+U>cgR?=ozPdtlx$t5tx4M$&zKQwYW}{2YD`%sFta_vRpt=z7`z6fN z|ChI~BtPixKCXJBeJ;p0YH+VkX4aM$5T`}BBk%C_y|$;G zE`7&)y0j&=wp_rzh3wkQ;g`kVTz)zHYCc#tRAe7i^V7BXq1Pf?D+z2|^m$I4WaC2b zw!ZZzr9#cl#XhrhvD4YP7=-P%db@+l3v{k4?<6m<-|Ou52KlVC{+fJK9Y2%zbG-Xq z+`{>DNb~U2v-PAuk|d3kBidxKQUvpKNie9wxy!zi9g8vWLAv?DGuqurs(a zb#i$m{$L60vrulT^O;FSl_wd!Q!+sIh|{D^@oJ)cwdN#SU0T;-?!1!jCOq^+;vTXA zT7hhMV^pRCW@*jCeZv|d>mKO+^4&PfU?6L=@*nHEbGKxP{0DY6PeNA8PE8_niHplL z;*yx5HTdPu&SxYkyPL#;^-rzM>U(D|40_Bx?2MzsNt&EJP10KpY>oaEVMt!Nw7N9; zHZ?tGQ*(y1o46LaEqlp|yYf!*PI5j;UIb;NviTZikRqHMx)sj8VnKFrcfP6}+%H7o zA>tG9ZmCGeD{Ko_>mw1_#U)(no}Pi;P|V5dwbg;|T%lAM-`KbLn(h+UVU`t2*P2Cf1@x014p3NlZvu^YDn0J@f zZS1;j4$LtfyV1@8G{!Vr(88Ztz`} zAM23A3PN{_}~S(y)>^#?$xrh;N-A@;U+^Z^fPF$MbTOIKronk6Dv+Yf-0@ z@53mICHNnYzoYDBiD&LXen|(4JSnV}&Zo0IDI3J&_+ELW{E72j#Jjn2nDTUX9?dqd z+F8OT?`M+tJ1Z}_uGXwdH@pzZww1pRKZ?HU&}T2k*6L|~oRqg(qfev@4|%)`>ROuT zKL0#`EzcE0csKl1;xB&rF0{h@QnSbTx6e9$Lr>NDBkU&SlkCC9llS{J%L;4V`e38# zKQhF(A-X<+T#eD5Mw7YKL)-10Z!>g#Lb}O%m*L$gdzVM{$hN5TFwot0c1(Xlc?5P$ z$*&cWd|?@OfL39n>@LS+wYEZeO1FM?e@MUPrkP^6w^eQ&S;2vRkJ-6s^yaKLf1JDGwV8exHmw zRFS<~+0*nqekMa;9%oN8rTtBX0ygZ|((YYS9+_4B_Ui-n{9s^*Vc&3(Y!lM{ zAh#Oh$Ski{#{DODCP}xmrx}(Fs#DA0p@5c?qr`=^^PMBJ#EEa>6McC$0s6>NU!G-N zDbKbO@BZ3|8=x=#6YW4wN>)oYVYj*8w5s3rYH8iVewaTet(Tr4t?|0FW@SJ0RnofZ z1Zh1N`axTy^xY0Wsl3q_sQiSwEc>nlKeo2q#l3U~HlnY!>RfEJMx^5yFC!01(F}X} z=+9cchwn!@8?DYZD|?qB=_Yi#W>s2~Ypd70dVgtg3T;kPj&tT zpP!GS%c1t9nfQvn+L9P?4ERN328|cCr!{Wy`!#Qex3xF(7sR6xzL{orvV#4UvR65o z=NZcWjDVk0@H6#NHr}ZNPH(8Oi*@!qX;=E|d7Hd=8rz=Eb}D-{;_+n%)Yj2HzaX1` z;_YVQDgF-PIyFgK4{z_JUsmI7#e?*Tw*wsrx37b5Wxp+wqMrb-d&!lK$Fl<@uidX#h2o>~sFekARat!a1ZCmjSK~M3y*gM67``6B%=^*_WzlI`kK%I2)a0t6fW~kCwT=CkD@FxL2DTpGuzdQ~RwxfoyHd-wgBfUi{SBMEVZ$BfEjl9$|Uy*i}zQR!YCc`7N=}~CW2N^EDniHbO-o3W|^5M%C=WsrtH;rBQ zlQkF67EXu4W2{wHda&X8uxzKwZmMf{v772-B+t4DTi-v-_u>3=HYWL2y40@y{pjjS zD>^+Yk9$J#*hcvAjQUQCE6aJ_npGcEby~J^dv%VIFF`*n?%j_G?Bo9-ec*0r(ie5#F6Nuor20jZ;K@tb z3tgzxT9l0l5J6j)UFR2@co$~TcXnIMW4&{;ncql^qD>HD#jwdTX{eq zryS3}ryT93J;I)-zKM4?RS!t#uKP#ThsN0)px_I0ncbmtT_SA5gg-rI4(Q+UOb?FIptqc8!Q^) z!IKG>F=RP{-drG0wZBR{c{;qNb1|Oad%aT|qxp(JE^5!8^zMUpTVrSOuI3}ueg|=r z4xQ%22H{tE7YDbb*V6xxd?Ww)i4PxDI#bjq`oD26uoaqB-FgTf`bInn->24AWgAtt zM@0)en)DaGSNbLC@Iu#Q?mPLtUY)rVe*aH?X}LI@IT^KA$+&~ zYucc%|0ZXHNAEKH=+^4CcFA66_>w-`*`WtX?kAXA{4j+4cu(E?Id$#@b?y~)?zMI9 zzpHa^t8?$GbN@%3yIkiES4hSG*LClQ)ymFaBVtc)?UMgdb?){$_xa`)Uk{-?1AQ|Q z(f8<^eZseWDFc}cywUT#zzW&8x1V3LfjRE&7of`J^gge-Eo|Y^K9+LUqMPQ=TXdb7 zxI``MgtjgJY*UjEHS3+PN7cuSzJCOM5jcH%p+SVFCqE>86gAN z4k7E&okG@hhtVM(nex1%a1?qxD%;cO6Cmd0Z=K;t#Jt>j!&Vx8xhELrgwUZ2;QKS& zVz}RMz4U|l?ucRgVBBv;pH4U$`a(Kz!)U@wWCp*&`m;UY!;%Mw8frpH6-fZDdZQQc+s;6Ux;oHj~xHaHFr*^PS2lo zrg^WK%9?DJoyu|NjtgtV^hzO%p|g!gFsCtFiNRr;V-8p zBUVCGIQ~Io*)g@;3&5`sREiAbK0^UJ$q6dqMew zeciQ}|LSK1m;C8^H$T>~ybM2Gd#Nk!yo3$uk@)l)!Rz>i>2<*aYNvxMpf`^PVS4H$ zsqGd$s*sDH=zW}@=uvImwGDb1yB7rX?&3b|@8}8qeZ~CgTV3PPQ(Nrcy8i*aFXIZw zFG>7TJX8Fr!nOGQ1NW3g2jH&F&^sq^fQpl@aNOkHk3Y#as**=Fb@Y^eg&CABx853L z)a%h{NfW>C>I1uiaM5YG;7`$M8Jm84dVEUPYwNUZ6f=f&TKd>%WQ^wJd>f5Av)0*Y z%xJ!PaOFr^HX8Spu3)SfVXZr`(fEGGozf3sT$zY>@%*9{u?6Y767i1vdStV4dvYhq zy0X%3x)lSVcK})*`^%1kJ^YIN4)d#xX<55|3*ns3ckhJ0#<2~aKbF!`bp2oL(zXBAT59FpX0vBz1A9Q&$ain&Q@U2 z>uW187*~Ih@9X2oJVEI<%#$6;G*=I0*yGu;u19(BEYD4P{Wci%_51?=uZE)= z`wt`hO()@n-Qj!bVTawi$97xoSqBAN|32)Np7r)R8U+NcwZ-(r5!k6s`0 zzlZz9geQIKfNl`Jo(JBK>;uq;H>y$U#A$?4AxkY}r@* zG;2JXBOIJ=EPGwW*kI~XPi917VAo3TUDOHLR%9K&Dc{jr{t$KXi0VOJ^~oi2@saceE&yXYGngFbssd*Ye{j?651T1!q1 z_?%?P1L*lkK85S8=CLP7Heyzcu_9gchKI>9#J;e3*%%^dFQB`H~A<3Wg%4qVU z#zBWtBZfDo*Cmo?HNGjLIeF&dujYO7qSis!4t>)x{KqpZqVe>-2|Y)4IlZMoCyr-B z|3Db^WfD)XEFU87e@*^IvaMzM@J+JoGC*YlKg82t?1{rGl7)}4=2t71B;}H1AGFFv zdBeV5XXi4DZJgwaY688xyIt9Q&b@2Iwu{Oyg1yRA9@{vqZyf1pcJsB$=j2BkU)Fr) zfXw7#V~)8~)^}paHrmpI%3I}OP#$#I+v0;2x6YnKdTQ~K$Q32>#B5>AsE{`?mCFli zi@M(J@>_e;MZ?YSr`2ZNirx-kP;j=oWSJDhK> zHV{YIK5+iX2d6WToK&31I>ATCuQ>acWp_+`guQ{m9y}@g5}VLTaqS9nUUgo)lR)24 zGN1EFS;J{{_44EB3djy5=NdO1!B0<;bfa&e_SQ>2S-lazvRBBQwUZSKX-676);Zgf z*nWw|u~!()6b3`b*(;oazXPIyT#=nKtS%}DfA^u7SlFbP(y)1#fyTlDfd%V$J zWVB@qQM6?XQM9kYpX@D)XCvg}zzp_NGuRgDYAs{;#o5YI9lQYjuRL-6jMCDj^1H96 z(Rl0Bet7Fk@S=FDG2pEZpSK3UTW1(=HI7pLc9t8ly(GVf^CPN9x|%ujsZdIF`8Js1 z*hzpPs8^lvvdU;y=_}9<*TVtWFjL=w@+mRyZBl)YU~ffygl*k6g)=#FRVh-lHOd-Q zQhYX}qBRcj(w)q^2fTV`7k#A;&XCIAQRJM{CZ$1gUOc=X*&sfU%pHfGgz`=DSm&?~ zOs_9}i2PCcB&|#agz~qiV?>oauY8ebalX}elHsxi8pv_%Xdcx4mk4JMx(NaOCJS?= zy=SfNpvwI3nQz}_{YVE9s-p7O!!}k5 zI+66d%V#1tc4elO&+IC^`6zKed2MH9;62z6&Qgbxz5TMY)0uK$!;Z+sn#-63vGwHN6`LLZmBisvB0-aV5@?%_H9zO zR+y)AGU#KJwPa9D{$N)rEW;E|JaY*$jJkqNXUVcl;Vs$KWGJ(5(ApiW8LsL{&@O(O zIu*q82k=T7d#rbK`1UNtgHhtm)I?LHu~l}AIYYV-i>0wCLw|{6wnf+MaJDVgpOH+F z?9S(RR3e?7I(zkCk+W9=da`f%GxRuu@ao3|kK$kbZ~8-K@3OUW^4c9k(OGMIo_DhK zC;9c)vUx^Wmnt8S4?17`i0Ur+sW$Ru>}#ZgehYQuqvWxZwN8FLU)tL7d`aI)eyNT; z?`;3wgKaKk++gHa(wAkfeM~=rU+UnD=IWk~Y3Qb6UnoV}k@WjT;kx7GR;o~9ezj>p z+Fz3mkB21Fx`~_GpeT8_M{!42lYSoku*qe~I>|XY2W@fWobDOQHnor@wQG&UuZ1*3 zQd5e_QA+PrRMWHAMk|cMZwa=(s57rN)whA9Z#?=3jf0!3XAvjKgrw-wFA$w*c3Cl& zT~(AmZiKT=8LPBOKE{$$eEC6sHhMD#i;o6coA`%_chNE2%4^n8+roUOa~D-cDg$(3 zT^YSZxUNshdEP2JeYZMXKKX1prt%@}qWc(a%U1PW^6I->S^AVKo6l91Hv_C~QU6l? z$;K>g3o=;!%>K$oYwmG)nRc*`jC1AGRVaOjaFzBa$zzvS>SL1k$+LVLS>&r*mzDpS z;c_FMar!Mmxj9)&x|rr`b9saPY^9SvlcSsHnu`0fBD!x{52mcHl0CbNR4*jU2PAF% z7hdh=8_^hu4ENy8a9{R0>OfBy?I!-!?-6hHbXlKF`R5TY^?Am^1N3KNgy(f&@2+FO za@8xfb?WonLp#YxOS*D>YzN(Kbxh^=cgPyoM^O1eJ6y-akDP1UTgNCvI^eF3wZLDG zQNOmPpQj9$)81d{>KZlz&ytW5W1=I+k44Tpb4Oe#`PA`g`$hU;99*?EiNXHU4?=#K{F#xziy>Vs$H#`Kmew_&6u z`2=;2zOCOsnpBLEr%_jivs`^!PPkFRY@sZMQ70WAF;-Ijr2TaLjaYtp(a}$>aDACq z$PB(8gkSZ28S1+7Z;beLMg813VLVCQ45wM{fCuzENXz@sZBZQ`7NLG)Z&l?X+lP`R z5!qTz@2F1tCdbG@ePnLH+UDr8{IczT{pmH+o^} z^K*8s>+`5jI3RgRaiaQ#{n(5T_v!zY{%w8Qce-aQt2-1==wfTl*T2C2l)@}_G!I`$ zx`X+K>$sQP)BIS`#Ro~iCEKRDl4;pmyu5TWwiY$kYIObAd#efhY(ai&4}u#SefpPI&_!t*<-j$_C0($+#WpkJw@%SF!g~ya1!QDuGJ}^o)J!h2)qD8#JXGMr_gYsH0db}53 zi>Gx~gn0D3#8Woi*u&bV|0Y}FpP}B#|A4&oAn)zbT#K8_?P#ukgYuB9_A->Y*HsH= z2<7>H;^yklGTE8z{jSNL`|~CD_C%p8dP+x}-}eYlb-NK>ci$7gcpiT|i)MYln#+*B ze|)0S(QE(j0>b^H#n;i-cU^o(-q*sIh`m0G!>}2Ii66a7a^J#lmE{Gp+vP=gJiR6P zWa)nFt!eBPBi=F5CSG6TnQWl#%}y)3GNzoRXBj8Hd-K!E$1=<@;nuyv48r;dVMXX; zqwweKqh$!wL*8#4daCPR%PySy-SK3h^e*1199^D}pNg~W!kwXTh(~{I?@h!@ZFbx% zlw>PS-z#6#HYg8eH!MM)89S^^9yXURr#xk^jXr>j59>pI9(d3o%p<8goeQs_rX(ryJegF~sufFDNg) z`z}23|Jz-Ag9o3~u0<@izJ|UScGse7>ddb7S)a>6?f^8>6`dh+|&Cc zjb7lU@9fD=NZ{6cjkg20-s{|}z^(V2Lhj&=u)lMq^}W{3{finHx@32)Z+siwTH@%M zA8Kys(zIn?|FwuaU$VQV@OrNnbgTU9G~o5vU1QwtF7cu4uF(gsU0U0`u;%jDdMDPo zr`Ne>)VXi1bAP_hy`j#%vCh4@&P{t;yA;3g)Lef2m=msDdcUvc^56H=xqn&b{(YVM z6yv2F&t+Gw-VWQK8n5~E1HHI*=fBZA)80>YZpsfmw-XpvOOFi((lnv5-Wllh&cMCq-|3yYsb8w?AE8x1!ZZZ_OvxYcl*;daAr!>0{* z816FMZMes9ui<{fqG6BW0mDOvhYgPy9yL5>NQ2?{F>WY*Ht}bRVG5K!*=!+vy+sJ0 zOVLDpofN|7I)72mmk39}r}qAcz0W{X{^khv9nFyZtrVUH-wSzu%-o}yTot`VjlMr7 z|J?gDlLpdL8-~~t=7fBw_EYg*V)$Biw$_-xE<@?p>HGDD8w?AE8x1!ZZZ_OvxYcl* z;daAr!>0{*816FMZMes9ui<{fqG6BW0mDOvhYgPy9yL5>C?zAMD{k0m*kYJ89A?;R zC_O`cmogk}*lsw+Fl{)_aJ=CJ!;Il%!>NYT4YP)`4d)onHOv_@r+uxZZGsVZm^t;U+_O&N%#;egpgmA9o2yqYo*BAKkg*r^C;3 zpMgIny~MA(h4>#sCrSP%3-Lc!Nc~tWJd-sgA>Zv6@?9$(2i1q!Lfq?w&^aoEPK)$4 zsYhdkgu6({_Zx)@S4cSOjLBcCQ1pbnUt;df=H6}YEd5NqSN}8G?(2I-nKaxe_gk>* zX7Am3>CkON=TG4{y-(a(xe2FJ2%V=5J!r_CH7po5vIwB(dBcS$waLEQIw5p633)%2 zzMH%aKV(}us`JEGs0hH)MmYo-e>ixH})u!=5aK-Ir3`i5?nhJN z^iU%p&5gSX(8}4pAfPve`!Kx))F}lkdiqxWMDJ>TVR{}D?c%lI3g}(MgD}0N&=W2F zL?@uPnENojcIZvzS#SmPI(QJKw+rWL zaDaio4cv#r-AK3@o+%xOyjr+_$9*iM*P3g4eR{23_|q5}u_dK0M^CgBCXZ`Z0U4ma zc5nr^`Y!CRhxmOv@B{|_&}$8hucdUomaVq2<1QHcHs|xT^;(aNa{(rNXlK9I5bxdZ zyVSek#_PTJO?;ns`cRn{;szW|$SvYBv<{g5w_)v&h!#KduhUqI(K$(lC@}qbZ?$NdGUF zroax{z})3Un%bsy>{VUQo=~k3%05FwYI)J?>a50doh}T{!+l{rdqV#f`)euu%Kn<- z5J~TG^v-VZn%r7qrdS!x^IOx;RY$t_KY#||cCq)B_2jVqwSQneV;qdSfXbp@Ds(UR z1Q;`T*NtpC%1`bdQ2kup?*hgDuk{P)^oJ5qdR_p#RB^!ISMPsmD2}q_8-B08x!jEw zH{EAxhr@pQyAOw-A#Fj}!ghp{o~<$3SqoGB@~P0C4F>NN{!;Q{LMY4w^bZuKp3Byb z$|#l;AN;r{GI&{WS#o(Xu)%{(rTa%G*H%BzTyL}0hdA{^{8pP%y* ztGWQ*&>9?TibEOOFyH*+>T=N`tR|zS^`>_>vUfT4Z>50mCu%KdZ9WljH7UTQJuzKkd7^FZMB=5t4;odWkQ$-2**z7kmAQn`~!%gtNzM`I{?L_NSh6 z^9$eyP3w}fce1>!b=LtryVYA;UI+b1l5+Ms52((n?(XBe@z7B|yYCdHzO(wi zILUW}7ll8XLf`#>?6lQ!97 zQ96{@F3!*xga4p>Rj%J*eMe;?yG{d?#`IH_=-rPT+Hw1qm(x6d_w8F>PX7K^FaMBp z$Gh)-)ZKS9c<;G2`IG8V*7T0DMmVxt;c!-c_pZvwZfua?j!~|c>5P|D;R#P=>iPD* zRF+xpr}C5il+PgB0=~zl)Ip^;#U6UeMAeOd3dPS$VUNLMy^OjN5#M;vIeTQc!ap~` zpXsdZ-N=r>=X+S+MW1R`Nqlo_$8*&)&;^!_jGuza^EkX%(;Z1?oo$}61IQo3AD1F8 zh;uZ3N%5(ho+`CNBb|i~X&#dy{`|0ISe?x8L&RTUx_DDgUm%aec_|sPH}ym@nnMOs%cng~XzKksa*-A)+?ay-&SA170&ycs)clJoJ2D~l^L zedYW}qe=a$@#M)oyEXk2!k$(64C|t)P(Gf-JLRYBzmb;-%5pgT980E_4~3_3V|yn3 z;{ik#Xdh>-G~lPCJ(r&pyv2TqHdj8}KSw_5UVDG$!qX}zo!h4JX;@e& zUCQs-PovM1@^yRWQ9n*Z_mUHov*<@Y_>_|$YNM1c*{zU7$Qg1u8x`eWxOFYq`tEiqzmdf7b4TPaEmDYzXeM#>3qW2l3^@p^X zx>uj_1s0DKP73mHFF_mE9%?V& zM!f3NqqNMjv?y)oP(Ng=s}}dVd<){fu=UT&xABTQx}yr?L~(zbxa&OC)==D=PZ0Of zp}0qhdnAk8ArDSLKFSW>4`>?_r>rgi&ryZa9p^4DeJ!H8*-)kql#p-E2A;`L54x z^T%^Re^PdA{66K-$_nIyj<{}g1(>95rn01{$BRG>Hp;lRx!mVt z!pYxGzfAQ#jXfvII9%r$5UB+oelkWILB-PHBt7HcCGCfC z_Drek1HCI^tpC!-DO4mYTz`xHQVhPjc;0g^{rcu1zEOWH=vzJ@8q^ET=e&)u>g$N= zhvKX9Rr*y=#Jkyk+A7KR{q&UrIjcH&89eLib7o>$^&6Yw&NeD*$**W5f6Ft~gV}HT z^JM+ELt(3pOd|)9^l{@k?0S(ezgEAUbf`aanWbBOj}^%DpzrZ}_bWyQxU#=pIZ$a{2xc^BzeQ5-_QDBMS(jz6xxmiDr*M0RV;J6rOD`Z$OBAsM1N>2*_1l$FX&vPyOI zTk5mmU-BuIo>+`z@LnV_+i?-m&gy?_4bA7B3Y z2e-Z4)pqjBk>u`|BFU$Errdtv%ZHI4zxm*Uzj(&x6Mg`XOtE|DwmJXs?Z3j)DhJxd zuS8QT3h89wtKw_Xi7^&D1|5x$nUis2VvW@$$ETBS)dh_S7ewj zUifvxqu8_57^jDD`)lLSy{+{{{*!MSROfTp!ps%k9HR|Yz0dM}FwRx^Zi1%fA%gj^ zixoa`mz)aH5tdEb^U`0~oG0E#4*vlD?ayCFoxdmW7t9^1pZJLre0MG1sf`c%TBpF@ zil=xkYGYdQalpf0C!X#->3H1ABb<()4DZ9=xTMCCjA5`b8c9!d^B^k!pbb}hu5<7E zOV5N*p5H;_34H@E7s_A00z zMZ1w9*dX<~pLTXcX|u3Fy02z~G!e2vT6TMq{O}e;y}L9ItiDhzJ*hYye$o0yd;S69 zOW%O_Cm$Y3IvyYm*ccT*kq2KfxfqP4r7JBN_88|(Yy2SFmKr;(ryNxmKFt_J@m2o) zlDzatgXgZ|#adTmEac7!`tbGFU$4hZ^`prtJ43!r(g7LLN7&srb(h*b?2i(@%41y8 zA8&>GL24)2TeI)qDUYCk2A{m5kMOAawa{1s4SoNowjo>D%MtWX)JG6ciVro{5N3Ov>BhQ|7D4tteZAtp;6AEJ-e$WwgeIE7un7eN4Bp)Pa^*)fbKO!DWcs3b&G3~=l z7rsin@rdT@kX_G5GAo`^AK;tBUF{j)mDQ$6Mv8AF&(zm(?GW$O)}54Ej;N=t^WQys zJQbym&;Mqgw(gu%;gPdbg|80e{W9FSsJHL4#kJ)@q+`*LQ>!|=;@(kD6rVb;P?|XE z+G2F@a@K4vDW+l8Bxy6IG&D`quz%Y7i6kmiF)@hC$C^r zcyV_R_I-K&B-`MQx7|bAs&_hHBbH_?=JNECVve|K9GN38G}cGH6;+?ECVpB2n9cLx znJa7Nz9R2+UE)qm|LdGu(n+`kTa5J|2q2Wtqj&8t4gd+2YfkDzk> zDRdg(&!8WobO$`zY&<{RZ4a zBk7p&(E|zb^KfL9_%}}3#8}4*zURBhRAi_4TXTF4o_9}F2?!_ zYkqg>Od!|CSDE6UeVLD|FA`zB`k(1*)R(pT>O`c;@6*q!+)O`S<*l;*FzF2H!gy#X z-!#V`wE2HcSjwMYl0T|vj(5~Af?vfW?7QBFos`lSc`y3nx$BLl%WuNIl6OIP>W7?@ zL}pMfw=g%u6Wz)&R64Id4F8uEkgWWJ+*O!9(_H`ft2)IRo&&(by))CSvpiH+0UJR@!KZsx8Bu%@MUr7@mAu&x_< zN<0;2Fy>E?AGNx{n0EubtvSs;V}8QZ9I5<{C%+@m9&=&P?#-=;uHO&IAD9}7|No>6 z)vpo#_M|VfwT`H<^)-~WtLKFG&5*zG=5M_DyBvSY&%p1u%&*EZ9PeMT7fN${&R?Fs z4{ca~eX5s2{#33S*JGroU%&hD8_?6a0FF;-W1cyB{DgCX%7j;3Do9CaE8csbeYC7k}P0lHSMqE$ub@@8)Au)KP^|xXamjm)^jQ$kYDv zzSH6?nXY(i+^+mTmAI=9ptIoAhG;CIzE&VxG)78O-ve2uxlDzxxk%*FQ<_6UHa){x zW;SJQFtlxR# zb3@@Nf3Jp4kPi!#cj@P=$H~9XAnWOCR3=jv+S5*-_h2kFsmR)+%U}E@n0Fn*+{qB? zd{o~=_(p9B_Cg+)Twjo6%;!;7-5_+bq)~NTeTYT4?;Ubl5gshLb!q&ISH|;PZHL+r z*`4p?+mpI?S0l+;Rqz_wZRsL>Rh(4q#D63?soY6ek>pI;uel}86>NGtb3=+- zQ*w9WcrrpfCsp4JFU=+nvE1@vJiXfWZGv`Y0X(37o6gjrZxq!TKFd?j4c9#Niqu-< z`;*MAO>%vtM~PR^PF*P8q2AJ{9#kJ;^q5m!{?HyhLVNTL+M`F|+rJq<;neC&zolLJ z-Zx%m{-W}0Xe`L7{du4|AxFOFNm~IvSNzyB9qTBJy2$$F>brggUep|>=K5H3rA=V2 zuS+%#W|tb6(@K+PU;Pbrg?3cD6Uh}SN}I;lYMb9kJeBrHjyXHh9_RuD>DO9sB)y=l z{_4*OCy+_fq5B)sraE{E&s9b$n;#N4wbQgaoENaqoe}Dv7qGMRW&F!uP)9$FAIX{= z{;!9|>peH%aORwU*LZY$^7+zbb|&g~y7!bc28|}4s4QSF^47u6l^%QIxzfnwy6Wie zb*xpdt#){8%hG8Y(+y9IKnB6bjXZDV*VwVPoa22wC4Qrg#GlsmQ}}iDo;-?^$C6)? zW$qdFILOn-`#eKF=v>CFV}DZ8x`x)4wx{>lnT$`nGZ_=BbU6R*1F5Sz7%3S312bK-)q|Yj1mrA zIun8I1)(e9#{3&=!T9f`gXmugZ69!#@*#>guF6yPd;QDzFTK3Lt@l%zAq?CKZ&An{ zyb(--_tv_G`Z*$csu1+Q`h!@T)7-*&?-*IjeVb@Ok#<<=WM zejW6C&sL~AIl&H2;OUYM{Jqxk3D+!GeA7Hds&-@o5xQ}H$0uv)?sITLJ;6WwbO?{N zWw-w{Eljb0hkTDxoi-V6Hr!&k)zIx%#ou;wcN;!!xWkb3N=J`zr^7vlZoewu?>BeR zu*dL#;UUArhDQwDepS9_jnUDS$Wy%IhK+_ThDpO=hOLGp4O51r4ciUJ7^V%!8ICuc zV3;wSY&g|$x?$E3y*U@pIfio$bA}5H7aA@y>@ZwxxWsU&Vcu}1VW;65!!E;hhU*PC z7#0jS8g4S&Y`Dd6tKl}o?S|ckPaEzq+-11iaF5|$!~KRu!ydx}hKCFf8y+z{YIw|0 zO`I!#L$_ZQesKF$!3@u}&pIoF&li|`jc^qEQiX{9Bf`_zM@n1e_LG6p1ZRF5&NiH5 zh|Zp;eQ!A-orNR#)xNux4dCgvZ}klJ?Lk}g(liyqm4=55Gc*}`zQ@oTgc~~Atf1$k z5yHYw!_9^{HniyZ7Q-A3vD|wNWouvV!^Bbh2N$6$FZTh%BypBIEkszm{d2fclyc9r zD4S_N-4eqrZM5=Zw&5JZoRDu8n0ujN2dMl$CWLMrfisfEa}PA-Zf75s!W}O>3;PyA z-p{5?^nROR(XfTG(erVJIm6wC#|*Rh5uGK%v)P|0B+M;Bev`>t;YP##LgLX%ndv!E z_D&%#JocjJ_#2f*vN*RAxAr@)7oLaw6Cym-$BVK^L>4$c++gm4kh0olZuyT6<=>xo zK1I-a>2!**^`}z=Fa3>ub~c4Ik$tuc2JL2TSD+nNq4qO)793ZhcJwc}QIIU6f8}ra z0RFF@S20NuuqzHKUegSzzV2GWfA!IVtI=*Q0|)ZUn0qt4(Mr9bsOio5`zPdg9=~vU z#bf-{E`_V>YJOpQPha5E5Ft4Dif5vy=K;M{ z+>2h6pRQqV@%{KN-=FU9;}`Zf`UL(^Fme9$jjnO{E4n-XUl6~)!>M>={KwuA;+N)L z@k0dG;`bfyW1)S5!;leF$J(Vh=?ce9?#cMm_yn=&`t}MpNIQ>f*KCL}zh1k7TYVSy zH+r1seZS_bH;s#Kxb~WP=Y0Hn-%iR+=e>@7f^R?HjfG!(pJ1y$XkhI_S35FhsCV7z zixvdY(0;!t`~5U`;xQl6zGZFs8|?WDpM|mgeE%$r7c?&tIt$}_ny<36Fru7&5xwZC zSUjcqhMf_ei4jS^(6i|@-~M6&8eQ7&mSPRHgL5Q#zJ=coe%<^w^E-6jgVk8>g_jz0 zCzroWSlWlT0^AhEes7levBtw(P3iPB>;1`mIXD~Qdgj*Dw^&g3+fQNDKa)F7LB5_} zf8PerMngmQ3mGJ?;U{DX zw~VOHWW8(iX|ioMv+_yGID8I?$~CaBHU)B9&X+&`9Foo4%Wi$`x$INcokOyjvTxr# ztsI=Gy=e$G@NAFidzd@+xZk9(lP^{yshO8 z!JMYov7*X6F6%qR%4X``CTP{i=^uzw7tcS7eiZu`+iH7WSnG;V*CNFK&AgB23zcxb z(|_M5ohrJWO_B7}a*Xnf{p!Ilel_78JU~NpfQGLVF4;nzs1I|o;zZth=@+WUMv&)e z<>yd8Kgny>9i+=%c54viZJct$-sV1!vLjy)26-AuPcC11(yYq-&rWmpJbSKft_~~| zN^iP)Rb|(5WDa{U_mJ)@FP^*{ddrzly?6il&8zr*zH{1xt2DnF%duVw4;S&bm)}-? zyZOn!u4K*G-IL1iV~wwcw7m~rh|{PnBy9oeehqbGFZfzN`90BZ4m85=Mib633ro*C zLid5cZZbc(?}K%;^zO)s{92s;p9p`C>V5Z%)X%vkL=F2?hgXPd(^j50UHwc&`5sB_ z=#jotJarE`tyZt7Pw~{U>eu19h+DT^M)}Nk{Hpz}O_ZP7uB}5PS6H){`^?a9qVw0_ zebSvt)Bx=R@QuFlGR0UVH@wWall|l%VLrqjqCC93i#-V2kt4Ftyd9Y({u4jQ&TZcF zZItW1hmGcp)kB5(Sk6DY#mg_NCcG<3oCR@~Y_#fK1NND>fRXg-ntf)`-VJ|>Hziw+ zwj*262aToG?hP$dnVPmK9Mb(FdaS$8A5q;Cl`Zk9#jQ_{s7@R!9fuXv5B5{a4soip z`d|dTGH(O=*2~H*nO<3aA99(|Misq)-t;T2mi}GD;lq~x`$Fm8YUx**d^VK+t(Jbz z(!aZ(^q*_#*Siy?e-G(*^=%S)kS$bpOd3($c8ku#@(xC^5&kH9Oad7{4;e2WQF%-v zj%tSz*p9xIc(r)m?Kk`H52)5_XgB>5rTx!mAMl;>UW9Q&4`f&MaihAnCO zAYQUi`Pxa-oc`}O=U?H{ z_6yRsjW{YjIyXhUc^SN*v@1R0#a)&Ur=u6E`V?pVJC>bV+{^uL%4SMrmh@llMYhpx za{4bMm-8xSjz~O=tlxXB&r3SMv|P`%}U>kza+c^DQXYedi)OBi^$; z@ig+-+GNhrsm_pozV-?smm`_k5kx)j~K-!)`J^=WuR^~6g(TlLTA7+$%U_l@503c6%%age#RKJs~s_f+X3q}lSbTPcBJ;CT)mbKS;0MBpYS!1qHnTK2Q|D%#~ z*=H(O-4!mre?Tq;@tsY4d#)uPkRAH2)~@lL>%&r~TI1gRk@ThI z2I@3(>h~+pDJK`F_anz6$vM@Zr6c7jynmQ{i{z)$_r0v#1kFH}DevD&J#CnvG@)me z+EKlauq8tzD;UJLsZ2CZ3%-evKiV6B&})lwk0NTVEWF!S{6cM->&w$FsjqoDYt%Y7 ziM`Qn(Jt1GNp}NzIt2Fs@>F}BThL#>177)U$Gs)-*#gM`(vu`__Y)VDh2o?9QhTTT z`z^eqcM*7zeq8kk;haQ#evYoL`m53GD)_Zf`Z#(Ddj4Mg|BUd?ClO!qO$HgLxQ@fEJdL)@s=R~x z5S{x>B|*5_W2^o>?NKGePqItlovl2=9X0ov=02MC)%>h7s3zG z)b0c}@ncahAB|^M4JGY^FC@OFeP~t1-vc;Y-w&5vdetT7<6XIlX04yo@l^F&mS5|P z_9CNAemdI3)6q`h@3Zuq?!w=e(^N*J2fsRV3ti$URekdL8NQ2B$Gcry&)(R%tLzM&;gyrGerD+7@UYtHLGY}2Cz8Ho zNF=jz2<(Z=q3S;k^C5I+NL)3l8Tn=MY~B*X^OX~wB=gb&d%)IAfi%B zy|Fi%`~IBgduE;;7T6@1p!K|7&wS>b=RD`{_k7Ry{QW}P+6%RVGFBhEV}#mOzH%+J zG>`YU;S7)Ks{$ zG)L*C%{?K$)m5yBzI3LoNPF&}&JK{>BrQ;`*Z#OvkR%t~3sAMvduO6!IenNYBwBP9fW4yHP zLK!PLPjfkO+J3TI`bpQ6W8HJhgF5Ip(sv&W(%-Gd(z|<8ZF5S4*vEsMwl0=V+%MUF zE#IrZfp7PG3?7su4!PgJ*g)}3J=@2JEKPj>o3<%=PV$Mkg#-LsF1P@=x9jWhLZFUNf)g8 z)-SQQ9=U)sPP0eo9K@hpX?QZXA$>JvA4{*&8JAjrm4xotZ#`E1*r39drRmhexYn@E ztNliKr1n&`@=ke{?u+Hf9hxucPjARF)eG;!u~w)%N^2RH zQ@*kEhO(CfBqJm;xzc5fUC{m5b9u)#XKx$*diFhsb$$e%qw(CQNQd<8NRD^30RLMI zjWi((4u&Sv4~_YW<_+0b+}xCVcj@P#c&g44#K<>o@tAh`FUTH}F_N@l$pexzhEm^t zT&MFoUnSmX_|T=>M<d@m`6}P2tvk1_&`r8$XgiMPV(E9gvS2TI8J>MeZEFa$ zz59N~GBZM+K8W!rx+2{8GnT)DHc}sd>JB*i1j^^Vl~h}?Cpre*r1ZmU611--$0Lgs zKW@}`aq+uoi;O{&q$QON$Do6)Y-1XOb`^UbAzt+-cTgUTL0wv9{}6mheS*f08rQ3? zln&(3s>)V8ZZ&@PDh(PpvWI>j|3$yEjx%oDapPI3Kj$0IGd}*G%)`Myif@F^+MLCH zzW;)olQ^gB$DHug5sHub%dydU;@y<9;#Zv7=Niw@^(JvA*<=l(BeEfbK7qO9B6}H1|@0ntycslsU*m z7Jhosb*_BoQ?|;hpM#7s7H@&~B{Id~42#AxriFIuyjXM?<;UC)f(mX8l z51Mx#%{!IPPx={0>pb5XF6?6EyiZ=^#^joNk<7c&=vD5jOO4m{?!V#g$KB(hd#~F` z?c&YsN!C0HbGyX(V2wt4$b*v`M4Lt@nveB#`BDBar_Jaby!eOWC+|Jt2ixa~hBnv2 z3WD{c$KqFfMf8>I*xakMiHG>K&nAsKdAA)mosri%(lvx7H_a1Bm(70Sk^4SyFVDyL zM&rG2Qh(xQQCW2xI)#Rjw|43;mKjmj+5-6<{U5)m>uvcN|HUV^5#}WA@z(s1bhjb{ zi6;EKUk3ikJWNIXVd7j?`W z9CGD%dxJFdPxR4=H1rgkPTSMj{&4PTlk!U4ryAP*Zqg{4-A#J`_(Iw~dunwKWHJAf zK|OA@{oV1QRrV3Pxk05R$lTw<`I;cetWO~?H}58nIA`zL$QNg$D>{1D*lyLN>%Yx0>PEE3)VFJMqsH-V!x{|l z!gU_T_Noi*<@W83scqNZe%eoaLYE;lgs_ei>IzZQo;meOOMdj3IPR zF@dgl$)p+TTl&b=zQtR`f4@!scC01u`3HJ626FCehgP4!Jpuo7eLQWH`Ddr&Q!*d> zkbaOrp3&U8^qcCulB+w~_0LF;Xt;xPrf5r#DzE9y%oQ@e%7k-ALD9|xFc!ECe~*zK zja9w;roQ4KeaAUk<}XUgoX(ZpT@7+~yR$rn@mpQ`88h@$xR+0PYoe`dePxiZThhW^ zGENp24Q_9HioBgw{TgNM{L>f9e^bQ2qdELI{~b^Dh$ki%bv&ao)HiNjhw@Vy`20lk zGLyWhZ-1J*UxVP&Rq4v~NcJQ$t;#3K*$~b)5hwfIy0=!7r8ie&r7%3k zlRd)-!>wbL9`4n*@|RW`a_9ji4K7a3sDx`@v=_oo6Ia^e8WwE)q2d`9Jp9APcg+E( zLfDOy3{t@$c0)C>bEw(v;Xfl7#@>4B!tKwGo*&660cOUW9SlHkS>ozggW|I2KCL#w z`md_DjQ%QOm`RTqofR1tv1|96{O_*0h3_*EKxo4E`C2gH`?iQ(-%o-ty?=$TwQz6O zd+9;(cD>gcinr^1hls+NFnsOB@pio*1x`}hX?qz3!c2KxfDw-J}lzD#d;e^rB>v)s;z-;98s+RQ%3 z*`Wr%y>M|bp*@(eD7bOa@+CKYaMcA;XcFt zh6fBwhP{Rd4G$Y0F+6Jctl@Kp2sW-9l7_7FID3m>+HjQN7{hUf6G5F<*&;kA2-=vS zlzoMePUu15xzMxlocj3|^}njO`G)R1i|WtKn3`X@)t&S%z~A=Nje>=Nm3CTxi&4*lswH zwCdc_J|P|C#HP@`O~}~-9U{=Vp^OkgXRg_w72>}YIZ<@%^yU#p3A^&|^yYz1ZyxCM z=7COc9_aMufzO(Mr#BC~gfo4gG;A_#F-#kdG8|*5vt{}&V>rQZqTwXNtYNF+RKsb8 zIm20oa}4Ji<_+f?E-+kZ*k;&nxYTf&VZm^P;VQ$`h8>2Th8qm;HS99nWcZ-r7Q>?9 zBZiL}K4!ShaJ%6S!<~lRhPw=R8}2dOYq-yFzu^JHl3}mmLBqp_M+}b|K5O`#p$3|+ z{tcT9TMW~Nhne6UH;MX2JRkRF+8c`yqC<^K;ukPl7hcF7WZ^i@0SL39{=PVE`9ayi zEkgVkg_AiS2adZ4KFwY@g}1@5iOB`ElW`+?p!)?v?DI#3_ANrvbHwafod?8U!El?Q z)3e7}oQcx2mt|j?u$6vANPMH1>{2*c;hR`-6w>}45uP6e-NGs4hY2Y8+an~N)vp2h zzE{ZmEVCzapTL1Ih0`Gq_c=n`3qt%Sd1RjzaJ~q)JUH%h z>IICyg?cyl31-Ku^GA_7fBrkFBZ!k0ipkN{0<*htc-d+84MNJcX!b{hl;MjyM;I9~ z^mC9f^0v=OLMJ0fTjm0fGEA@hs+1xIVlEgw=-K8z0^cI7GwK zSwhj5!W+!v!&}M!Xm~paPju>y5AUNmM8i8kc(5TCp4@$Sck@3QUWxFOH*b7+ci<2W z?{Fl2u-RI8pX0y6i}T1#M1Cd6n(^Un$3_0UnTx+Y-U51m+xQ=iH%Z0ia8tR!rfcy& z!T$tJ9dKsMgn^wooP)m-AHs@*@jQxG<)k=qu9=Ax@`ob{_J5U*sJ~gH@4L0H>Ul&r z;iavax;g2Y!zmYCG}U=O`I*Co@IXwTGly9mCi95isVaA77Zx7ChTU9}KDmr%5zmc0 zi+S34mhjxfBQwx2rsH=8&rF_KJXi3{=J7^n9@F={_wXd zTI^mV_ILCQVV*qGwDE_!BT4hpXWnzwVSi^f>#a_|lg=46-c=c7KbN|Xa8u0P>zh=* zqvXF!aZlxh{KgdY;BNp)7kFw0YR+0|z2@Jl$;@Nq>(kY^_B6P4RMuoN#m9Be_J3#%mAUpw%(Wl+ z)YlJQLB6k1{M})`bvIRGzMHnOk0rmcn(hwohf@Bp0bJ8gGwjo?+y*6 zyqbtZ`kCbS`j2n@vF^~k{+g{n=6=ZXtJ#0NAjW<0AAduiyUBy>J*ipj&-Hhc>we-m zYsS93$ZK=b-A%sI-EW!dCclJNyPN#HSN|kFzU!G}W?k)W^2;N4lOr1ZU|M$Ikwf>(B*0?)rb&q7rfVW%O>5q3q)S za#P>1%$_%aGHS!#s2vXC>~YY|-pgXKXC8Nywa_MY*KBMX_1MM!Dd?xbBbtz&QJw44 z-lKN>P|r1equeFy^o>4;o>X2MrzbK+ub26{>vF*flU4`?`Bma~79g>l*h4=Q%Sj3tb zemZC)owOURo9b@VID1TjF7!5V_DgX|Z$oE#WA$6y4;s}oitalX?po6`nrvh3EMH=8 zh}IfA%MaeI!b-q!X(T^ zZki|4_nHR~jsm6Uw1vmNQ~b;DC*7+)F6kWAf4OT-HbHw`m%XEuZ2K(w%Vw6dnc3{U zoL6Bl!9%L6Pm50mA%B#PQTj6L{a9+gL^iMYT6gTYii7gBL41GrM}e5$x)@`ofLn*{|AI?#^ti?&aBy zzkNLW@vF4x-svIaLF>utcU=0|1ChzIKZ<(<`?!-P-6N=XJE#3~&zP9MOYooUF2TQb zcM0AR4-Tz{|7xF-FGJ<$xxt)6qMc?PZwxt;)_}cEQ^{U38cTWO^&Uja>KXP?XphUE z>U=zP8DkHG+SS$QGaN%6CobXvTXEC-Nucih<_=`1ry>W&vu8Serem@XkES0UF($il zbSG}pcn6udzH$tGVmvpqr2c#p`aU`-tA)5}uK{G&+`)hDwk~T=)nMEf(${nlZ<6#3 z;$BnnC-IA?_*Qp?M!!S%VC_5UHr02?F}3gF9UJz3gYTyCT?b)rf~V@vYu!m2%gu0U z`X={U$6C&;ybJ!Tw77RV)6M=1_*Y3ffs`)kZctjJvr6$iOt`wwHyNBsABJqfw__sV za{l+}3~m!}8xttq=sC@-EuzO}o9H}480EfD>!nZ49y16eipnlWTGyli&Uw5}k zuW63wui&SP`RHr7Wlyo-ffJRfcnjw>b#QLi^TzojCcK@3|}Ni=shS zKc+WTyp#Rsm5ZUD^C=_QRsI)Z_j&j!aivAWxd(d36gF1JQx7@puLa|@3x&u3=I3+C zvi8c8PTiy6;+Ni2eJ4MwIR~(+P4soA(`PQfk{QROH&$0rZmZfTTl_ENf2il_qmp@= zQyI#Eb0EBXJAf7mri8-(fEn{L9HIs{g-M>VvOB`}s;8(|s8SHgOQyCyQJoT@l2w z4w-Tdw6OlEUqZLUnW*)-_lJFMT7JQ?I1eL$!zw)j;zmff0 z8N%}P@aN`_y>1nswq>M+emzCsn?TlzrwezEl#Vrhv((L;G?1har5c zyBO5ZeAaZ9>f1MQ_BWS@7NJ>xkNpHY4?Mx?4V_ov9^Fw9uxm4jb|y3M_y$7j8$rP^80kKNBC)1#?y8G4P{K< zfNMDWec%nQkb^1$Rcp1L+1>|8*KY2h% z>NgK>jO0P*c*WDC+vGzUPk}$9fBn+yH`GH877ZGNEe%>GPbE%cz$=dmR&NIB2vYUC5vQu6?o$TN)eOLG7 zS$VzSIOTSMrT-12eQx)|)h{tVlT0uH{i!MRr=IKdr-to0L3@r(-ttT;y@|Gbw$q=g zwyO3leNdYBlHN77S?M2;yfsdC9?4yYa9fsBzd666enb6JE<<~wu4eIQ?h&5xdA(qsI$N;(BBh7*0_~ER`J9$=)IiYQ5wXaccn}HCt*FVuo-8C>57Hv za(XnCrnXR*COQwoIT_M)hUqI#=4KTA_na|zx=lqR=pZ?!Kg;7Lx?SP)o4)Y&r8DZj zU8z46&z5XIB$%K0GG|I9b7pg$Wz~^nJ=NXz8DagbrG8Wn-z1C^@wuNf*QD{9_}st3 zn+ti$k$F|c^G~k7zP|Dq&SkfxXO*QVFDF?RULT`A;*uRqPx!rduT$HFY7cqGOJ<2j z2K6$O?7;ZdolA(0&iOP7P@P9(pf zzpYvRVjsV=G7W!z3?dm-WvA~|W@q!Am+h~EP9&RtlDumFdvY7YRe-m_^8WUZc>E>j z6niG{Xbh!#>A{~HN00`M!@DCoS~u%V4sjfK)z+%@9Ve8rpP^pF6C|6fTw}_<@b=oqI9c#hGXKvHJzo<)yOzw3utR}%*I`eBbjR|Rz6Ib9C=$9rrMF( zb$_zL7dR{Dd5h$Q5^bWtK2bVN#oOgq{(eOGqIKQ(ScEn-A0Yk`r0t9o=L$vB-=V&g z=Sle0T!GW)iCz7Q&J6S2!-YD|RR`iN{no>A zWMFiz)cOjapOw^s=LMeD=p2rrHSWzi)L%Jrw!BX{eu8p5UYXBs@VgYhehyMPj=1N> z>2C{iE6T1tEV7z^if-bq+$uT5HmO3y4!M`qP{!0Trf-$-U-Rmla1@EaY&d)=ac#ksvk zzPT2^q8ZVF?mQZlEuN!3OFUuDw5?8__;cE88}y;DHJ>5gA3Hyee%9unOlpJAb+I;6 zgw6`c-fiKUlERqUp)kFE*066ppRsn3qmRn77Kz_x=0ikd&`OWa<+{AYHty_j2`KCb+Q-vnqOotvh87X zyN>NX%%#-#^I5)0&ROMAPFp0R;H>qE`3?8Ahs@;pu#rxIAs82}*A5~d> z0rxMvIpXZPr<5-BJDl-ojqdu51X8Bc_JK}>l<1c^92#a@L*+3ekZ&dpL z&Np47_u}?EGHW+^+w-QaRi|fk#FM3`=s#u*UsQ^XUsGC}LC>hhZIp44CSRG1=02Wo z%1keJQyv-%yS3zOQ2o7laNf5Gi?#UDc-oAUkGj{CyK?mNqCMy{ncc=5_O-~`oxSQG zv_9AZFVtMU>N`(*3*;s5>V~yJ(+Q}p87r{;To`xGBg8>MZIUQJ&@8*u&5r1Zw>hv}!(met;4Y35a+c~}0(jt?Lc zh)-w@Wlp4j(;A!B8-K<6BNrMU60K_-r?dH6r3;?^DVAL`0vaDpyG?;9$&r6XTUQ&8 z7ifpH>vq$(`hm8P_LYA1qmmQGQLpc!9OvZGVNBSPQyIs6|24EB?c*6&Ag^8U)dKvl zgMOh4-bvfkSclc_?+1(SC=J1{WDU8+G+!f~riClx+_?}}d(zk@*yEjsm7l4HG!k~g_WRfZMCC2 z+<%Y^)>bcd?eiZMKK&Kr;aslh!`RDs%FRWR-i+F6QDd|EeC}CltK{MED7DpaOcqbB z4aa1pSLycix!SLz`cyr3XUH4=$xGN)314kh^cnRhKa>2tBJaBKlcb#~&Q-*zwx)Pp zJI;|W%132(UL;Rjj}z{z30LLk+8ts4wfSpY_mxgl-#*kf&VUyBYe&*)>f7)$^qpR> z-;izGQ3}n77DX@d^rG*@(#5AVPbYr+`^QNi=d=5ykF)4bb`qV6CyPEso4QM?zw|ss zdi=bF(xrI{rC;|NscpG-$@f}+6m5&AMb{xWBWE>JUkZCDb?4jP^W4*c-c#hgP**2q z{l&(4{&S6o?;G*rc=#qOOO1;}7qRqu#{)e5h%WA<-HHd4XzK&j<@qVn?dS(upGw+7 z`mufhUM;?@e&819M{^b$KS}50$M{YnVm(V`->-1_qF5ZuTB{PdB z$Mb=kZn_BwGCasIf%+%Wrsgd*rc_(e7(;r_C3{LR~Ns z1Z+L7nG7A~jA0Wxhpcb9WAL4WHl*%K-krDy9hb9)<>L=FON(awAqVuRwXfJq$O2Tq z-^~~{EtP*&>e^wcd1s`qYe~%?nz|lcod=p{3_IAI$PI2DHf=_uo=(CY6AhdHQC*zV z>6A_<{hA#AiI`;MzxH^i+`jO-V=7<(=8VcZ&U^Pg|3gEoj2PWf&^P?Sk+%w;8#Md4 zG&%pw-IxjAYj0m@!uMUZWQOl|MC^*M;|+EH3cnb!`!_$t?YA}9H#gXke``kH|8>n4hWB)X{cwZ*mksu#4ff|6?8#c)hvC1W!9Jl*Hm>*x%i^ME5P&$Gmll= zX~F4Se;>`A97DQ&`H~eY3wqO_X!Awu#f)n9YzVU-HK4j_!Nne4GjO{p|7=XntxJ|I z;pT>j0?`|FJwkB%;^oVhd?er!13_H{XsrnQTwK7uRLXo@2Bge|YS+?XSY#j|`xx;M zSjIR*u|}N*m%lg-=Mlq44IeXP9^Ad(Zn(p6r(w6@F2mi1dkps)?latPc)+k^*lT#u z@UY<#!=r}J8a`(TV|3|rXXVLs6^Z#ds@f#E{KHp6zqrH0E43x+EUR~fE0>@e&!++cXGVVB`1 z!v_tw7#0m5F?`hUF~e zS;OZH=~%-0H*`8aslTb%Mc;D`Hwe#VFLx58kCGm0-F=V~!oS_!1~9JGvU9kh2*w$l zKVtZ(koNPK*|!N1KDG-PVDAKVR<$q)WO8g3-LKA=b|Sp%tgp@rE8Nv|Tf+T@InpZo z7Q<;A5RiSTkZ`2WOZLNtbLbeHf5UFWiOhD&y~A)W!h`Hn*-RzeFd7^}`q`r{`#!@a z@*o|SMIr7-4Kr*Mkv%88kTc0<-!9COFGjsO^SaG&DrF%1gmED8WOUY+?>mK)$*Ebi&HEfxHJK;_f z5^j#Vmp{oZs^3l_^}50EUUT0hBu@{TeT(5XP~kl%B;6!8cr9@ed=O`%gyIh3_M8hkLOW)t|pQ0@Q&g>^V*m2D$O)}B6$=-ygHa;A|{|t}fRsI!cq}qd} zMEX7-2=Dw~m3!3RYSQ%XGcjj9OTl2qz?48!HA$7=dK@Zi-K+~=D*52gxO>)AsRBH6m zJttAS|KEoDKpyYEKkS6a<*vI?gtGgm(f?9vsL{>achNWc{~lLG(!IZ*_wwiC?1a7uW1ve^&L? zpSZJdz5Rv8)t`UGFJ85GJ-m(box>gtovqsq4Xu@q#Pmqc96!N1gX=1P z#)Mfqb7q--WbE#5a{o1cg3P_u(&)3Q2e7MNLfvYtm$E0XiFMO|fd2O2PkZ3Rui3^2 z9}W46XsmQDdi}6#57tip&z!urBz}YLBG!-=RL*A2bJ!=o&0d(!-Xv$j{t(*oY262X zZeWkj2I%kEjt6>l?{6%7h11#kp0{7IRRW()hFix4s}4Ij}wQ^@S)4;5cm66 z{sKRP`HnjeT-fS==@%1^$$ipbbpOq(+(KJO;ul^v^7FW(pR26%c7M+|>@Tlu!3{d9 zd>4C)Z(>8ymq0w)H?SF0Kl=cvJoZjOryuD~Wak8fpv9o0Sb_FZ2d^KRdV=rO9={2H zRXb5Sl^*H;_#e1wZ;@mYm5J^n*E+n?`msn_bEI|WAJg_oPmD6#eLer7`{qo@OOLES z%kgEEqtX@Ynpuvm{`N@e*SpK<1DsXX-niij=>t5of-LLuv77e#AniPv9^rU|bONrU z4wC3jSDHfkVWyKGd|cxH;vr@BZ48>Ga=Fg&8r^p?lXM;q>%a0d!VzByGCCU^%3Iop zAsvBhwI7=Q9ia3M?YV;b&u^;f9olonQ1lM1|HRs4@S!NL`6laJui`t-sEkF{sY<5& zp1E;OE_CBOo!oWCZ_?B{Z)u`jI3M)1=RMK#Q=T4&U#TvCt~zNtvm(C6p1G0S?Viwj zr|!H*PsG^x>Tg%l)bG>y7wtiVj`m`!?$myG>Tf|sXY`snII9G$y!sR09{JboKmR)K z*dtY|Gs$d7heiL3!9Ur01bV3uVSDmApNBjw+{qu4E6!9-6 z-&u5aq^@0GTA$xg+JSrS(ydPJB^?!~%kW&2fj4t+JT&wx;uP$-66G zbk4c5TuNS=IzF4?jAEjR^N30I1yi=eSMq%-`?~`F0QKNoGIWEB>rDk!62DM__w>)A{o5(L<{X;1j#3 z3))!qtLS~$Uicn+=GL+2WI+$>O6Q>iqT0**Saw6XX?({s^1FLIx??sYzZ8l+nJ(!_ zd$Ol=z4T>iuiS>-5@DfZspswnnR+mKa@ChoHa*LDw@=~17bNGSSA4AExgz#n_9b!O zK04>*4ifCO(jVPC7&^a;^lj&qx*^{Ku%4(+IpmF8sT zv(@*L|E3J|(Q#KiCVeopm+tjvjsAVylbHuos&C3WPCFVdH_B@yh1HzQe3|smtKc@0 zyK%;9Kh*HdV9q+162slM>&l8_I%O8iomu`7-*gntEI*B1G$VQu-IPGl%^z`IqmgbH z4LZ6}U4JzfrJMOZs)zaPs}${sMEI?I`Y^kO{G4{~alZ@zuyB$-K&R^);Mpk=!Ev zXQGp220F=VZ`1Nh6Eu|I-AeMRa-j=u-uF$#v9QuZSvAHhH-)2b#G`jFL4WCo!f?gk zhoonexF4ivI{8>YIh9gsE28N<{n>kl6EF0>wz?QSbWvU_-mg6}lI1=C9UMj%tLj92 zg1y0xcc8Gu(Lw@x68&AE{S@X;eYpG=z-_qcJLtgCyJ(Q}KZk~p*E=KaCFshR7gBF3 z(>n_)>$^&-zo2Vf^>M=SJmll_8{#37OQ%szwYEa}mWY%6C(RkpM;PN@DOwnPmXlST zzRJRPnR`GV4m>1a?-&ISE!^j5p$S@e-ydF64(VY-xdlCAnGT}~(%pLn`N&XaX`Ss1 z`?ctp#_-jUh4f{$XnP~Pu=FVpKk19)KQZC(u@+CMHk{Zq7xd$SoJ~r z&wjP$gTyUb=_MZrNqda@e-4vZX5>mu?0JT6#^aa0D8c0$Iz&tC@gZ(~6TnM*M-Q#0 zNR!I*u)>9hDx7$3O(~JLt{pCV7-IC$5)Up9WsU19 z=*1h0-m*ik-y)6bw+_G~BqOLU&a}EpsqGSP*mm#l-Q&`JT}Am~Z%e(tpn-oPzbb#F z@2k|+_RM#CL<4bjeJX8RtiBH7XK=0U-dR??sqMNtqmB-5rVk~aXniSuSB`|!WM>i6 zmpA={Y4$^nI%cVpKzdGOeA%nsrl}26$EsiLS&Y{2s%YI32Xbw#ZXGRCo-B8aRo;TG zyGr6;Oxe4!_YunH@Hfw5kJVMBuuq&(ic`07SGU)>x?M}WapG*Dew8;@znOelw6KwI zT-|l8ExGWK$<%)xL!W#<48N*#ME+*gWp66vrRnq7>qgj5LI=@2%N~^heO`_t+lZcy zq@bnrRi%Uc*EvklZ7j&cU;d_wl9z|XYvXyNN6HXgJ;cAh3V|N-0)B5w~s zclEq%6@O6}0lJ0IKPMT)$s^M{o>6}i6aPR4QJ={=5{EEG38Y6uk z{o=^Ql^?=yHQ)1mK3Ptwza)Q&+yv%;Nob+_MpFG*oG`3d4;y8H28jwdq|*3=rmWa+g;ABv-%`-s&KU@)#(?@jx4Ku zcB~va`abro`nkMM@?ZVvF5V5HoLqZ^p2TauMn2RhA3QglH#wL(t2+A4+?SK)EQok` zX6@O$JC{AT6}`K6La1}~G4kbj)kmQd_>}5U^{#oG#`Zlpqk0wp|Co~{#GmLB80%i& zld`t1eE-@swYo_P0TNmHaA{eNjj&V`+7$s z;?@5v2<|>!oB5t^ch+V^W1pjrS4F=6n-hHhWIx{zqmFd$>YebUSBs9jiqHc6R)Kxk znZM+N-N5i1 zPZ0e%zJRWG+ZH_8b1t-#6d%n~pFvkGT*j$mH}Re1 z1lt>iwX$+u(WCy~vSuAxn+{#=?m!o9h1zOSX{`k~cFD8JGbDvP?# z?1|9bVN0j-k?gv^SNS+{MVQvZ;6WbMtKREfGIwQJddysXZXW7rruMEY{MLU*r+p}f z9P&RYGtDMJmebXb{(W1K$e$2T*uk-My5uJzBWsR@@Z_*%n zQs-mejm}2R3#$y&u0^xg@?QMX`*{a`;*Ni>Lq6P9sq=H}&_yymr4LW{dMn>g}`jq{*1j`Q@FtP|vl-E{>leC;Xhb87K31-BC^C@1n1kj1#Uc{++e|()zGX zs0^65?U9aLwOP@!+QHZHH>iVrGCtjRJ$#BV)EE67Its-*G*%5|N9Hht`N)n>R)6)M zk{#>%iM8wK7toW_9iBnN3vc}K(~0IX|2|i19+as#|NBF?M?8~HR0J>%9+{m(UOlE!}R^=PSU0FWBmS`56Ki|)A+Ed$yP5f@O=iM*xMCfZ^W+ewMHG9@cV2n8R7R@SB<{kp|xUX!uMJS^LB;5O&fTe3E%ID z*!>%!&PVi3f0Il9!kQ-?y|A!7%rI{gYvC?~&|h z^Tc=`HHn7M670-^{GCxd7{S8zno8|)nocI51uQGAcp zY~kLiFE`j(Gprf;f2w8+{XgAc|N92}4;$?N-eCV#gMDy~7Q^sIG}zBi?248sui0%4DXdkx(g2JG$(1IWCwd(T3Y zLwAM&cXx&XbY~dABlg~%VZiRrFo4gQdk_!5PZ~BEwiu=jM;VSW9A}s@oM1T7aFSux zu+?y?;WWdX;Vi>BhI0+`hOEQ5e6r5xaG_zFVY}f{!)1mA!xe_B3|AX=7;co!&^^FEo3bVY{KuTIl;_ zh6TeFhN}!$8+I6W8g4MW*RacQlOg*gT=-iIi-wOFK5FRBa*&Q~X5VhO!*Hizx8W|s z-G+M%_Zsdq+;4cmuw>Y4c+l{$;Ss~5hR+&4XNc(K@{=@dGHfwS8;&v@V>r$*V>rQZ zqTwXNtYNF+RKsb8Im20oa}4Ji<_+f?E-+kZ*k;&nxCNO_^eNd*bg zdkyy)?l(MOSTgK2T+ zh6fD~8y+!SMxMnF_ZhYzs_X35qe9#>Ou`GNBBJRG)?-5G^*P}r4ig}X%e^E-$ew^; zulEat*jEereiA~h{C5cP-z&TTc|eH&78V6`CW)1|@Jy8u|5?T;^8cU^|J%Vhn-+Em zC(~YpsUYYUUWB|NBySqqDE`Aj!kxrqlFn+i3kkPNNW9%b{OuQ#&QTm%()+v+`-4K| z&)lc7=;`t&oPeAp#Q!K3yXAkU5c@2hDZ7|*5E6btNPI=J?-1hufZ?by*!gb0;dVoJ z1`YSQEWYaf0U`Mw!_1iM?#x*${nc66N#~1O-6QeKp)+$Qsz7#)6XcJmoIn2^)eyupcBTxPU10WwLh7Q^>>GrXVbSc52q}{n zbH>ama`Yl~{RCNfEbN$+`zr`LcfXMVbun4wJ1|vTDTzQEA>EJL@wv`t3Y- zrh4`!$save@i0uNofFg8QFd?SNA?dH4zd?>LCphrBY!eC@jyaBjz?z98{rG^Jy=Gd zZ{@FvXDyGy_2C7XAZWwxjSue+afpWZsM;xR3Qytq@HX>58eUtb|8r;e;V&9qH{qpm zQ+On^7T%xpKN{YKO#gZ%{}g}G@b*U1*AfZu>lR)dl-ZlLMD3#VK(d2*(1PI^A=qSjEYWai}O(=;x_)Xt|33(g4AS?+Gi zXdU$d)-1Fy%B`m!lE*mq81KBB>MwdfjqKjQ+WX9>scfcC;>TSg5yZ~sZ)(c?D}q7E zrr3~Jb9_W{RBUwY%*2@3Yhq(#uk&<(x0>-~Cx>M4Z_n3W@F&rSDrD~)LZVNt=zX$J z`V^w*LTx8Bo{~aaf|eM~U!-L^51PM>8qH6N)?`!`BM4tzfj26TiQWRrPM7M8{%ig) zxb1`W>pB(%6WVJIns2dpn)3PJ&4rb>F1ewwg8%*-+{MpcdxrH}$Vy7T?5;nfF)Oc< zV#v1@5OWt>s{i`s@SeczwpFJ?mt^W-w4=JqisH7`^*NoEmFJdW<`-%AZ)2>r>5Y7a7AR%H6RX7p}C z%@($utl9N0A+~@x&YP_v@AuS+=Md zpZ5NEqQ*Slcz?_-UUXS~YVqVe@!~0$3{+0k-Uv(|IWbv!b9LF?ca-B#lq!=-%rmAp zy8FC2m)$d}JJhGvQVQ<{54f+JdB{qTd5Uk)nR4Xe-lq8T&kywO?na(kAG@+nM#5$c zOMWsoV_4yRC^?M2o5;K0q&uud?>U~(cnS?|nzIxyuA4!weN3o1_?8no^v8QOzb&IO z(;Q|-7Bh;QWjkk7ZsN65%`R|l@wVlSlbAQuoWysRM`to?Z~Dw>D(rF0UuHnbr%HdE zz$LHh4oTIY<}tHoZxu>7c~SG2eUew_#Py_|GERItjn`Gb-X!hMBrwY7mLXfISQ};2 zD{&J~@zk`6|Ee=@e0Vc)h=#X<@I)gDPv6R)!v8%U&!hMo6nW<8j~O4HWY}nUorIUc ztx+~zid&QqAH+V8dCV~+BF!USqIRTsm0raevN!%a7ikKj*b#%Br*>>9hY5i|f zxPuqVx1;k&lIv#-YwC1b4ptS0HDOoV_hur0PG{aNI;xv+y{S-h@KhZ-^taxm^{ELp z|Gu?(|0<2TiLO7X+{C-tE>Sb0=lJcnYuEJ*{ML(T6vl3LAOC-QjX z!<&Ialvityu4qW%MR|YY8rELk&*kyPhu64IZ_-muYTaOJs^YYu^sfho?)|&d%(2bS8eR`T*&QldLYi$CB5-Q40GAoxxO? zLAH~yLY^-iO(*@OG z+3*ZtQ>33!eMQ&ZGGTSNU(x35u>Y7ntZ-BFu%;P9-%l?R?PJ70X8ArQop*iAbTx+4 zXx{>&aK!i)5jv^g==*+{!!*r<)wb(Y_kj0X0v8jS*c%mi`fNw z4`=^KKSIBE>qqMMuljTa;eI^?uTFv-2a2zZqk@%}IK--SYTttRlH`A-M|RBcbl!-YguV;T?&D z7wrdrAAg>gDvVKB=If6cAD;S)Xn11w8QdECfe+yp?FW_;-az_+2bBmO@fAIaSNT_* zA$#Qy=0WnIagaCqOs26P$neo0gsc8ZK65d@>j&I8;y1b< zfF(wZZxNx>@#cQSJ454JYG~`PAMkTOz8}cgmjbl`-+p{QaB0JP^#kFGUUYz9PSy+5 zR{UyyPnSNRma;xwK9gqLd#BY>eAC80<<^PRy zK*!_%jdMWH5nhHk8u|ZH++c$Rz?okM|5x6;@qE3J|7%`+mG=aCe-}=?o^p{L1{fGmxp>Ne z=an^|fvNEnogMhy`rfbSOhV2TwSGK>h7PB4j(8S9_BTg-ei&744!ABq*7)GDB3?~& z(&}E#a@%qfo}%X!CKCS3y0%wKPE@S3gq=E;d0O#I)vY(4f*N_|QW%tYq~s>~(IdNf zq4<~ho{VG{)tNUwycsw|d1is|#M2aBlxH^1?-qGKhsPTqUgP|32jOM#r0|q3pT3*; zALYRZu@8g?zmT=P9ASE+vXE)y!9~*7|NQR7tuJU?KRG+#`CXMUrpAN4To>f#l@pq$ zMXp1v_?pga)$XU`zBJb4xMCsS15VYQXOjCg?3k)-^V^0pjh=8doMM&4GU(Ta{6<-x0P^X*w-tl){(xexCO+@rkhSw0dy$Sum- z-i!i)CePtVEZ!6NbI@aK(Bdm}Guf-i_KdgJ}sxq#(vG4p}}oC|2ZWWc;g z`h77qUgXY_{%)VaD{`(?ePrE)XA}xG2T#?ZgZN@!|Ka-4gqr_j`DX1Ef3(lQkG0i) z#7CoZ1!^bfL_Uyxa)VubPeyWu){|yATlgdYu+flYBiju8Dt(__2HvsHCIjc#XHrq| zNak!8z7l&3d^)2dXqe1X#-&fEc}3BMH=g<$dGsE5mUy&iQGWDD&J*ty|MFD$DF0P| z-uUpQ;}GT1x(iISqwu0UT4Q$45Bcl(?p*ybX-^ct=Z?fI~dt=6|(49<`~zq z?~Iw3`u>9M?>PM$vGlBRj5~dU?ovg2(MIuT-@rF`FB!GIA9x*m&GP7-2+q^K;H>tS z@r~PKz`nClJpLQ@BoLSOuC1?f@ARQx$DV>MRLqQFEuD$=;jXk>n}@Y99omNnPQ}mZ zzNg>}PhbvxD+nD=xNf_xez|4j zZiM-St$hR=48=!Ymi+|vghe^Nx&C&pC8?gh@zm7F^R=hU^Jw|eBi?!?kNB78`Fr^< zy70z_Hxq{_&o4#7i}L)&wWKBj7cF?>!)shi(%ys&o*H@nQruv-1^@j*!W)R3f3Gsd z(*o#Gyvo1wKzKECFY(T*+3NjOBhOFs(W-v@!SknH`a;%{T3^~;0<9&Ts{O?3176NO z#VWu0p5j}7EA|xE2kGGegan5-k-_7-bfj+#(Ip^c;CAf)i zqWnKIK>nY{-$3>hYp#2KBz-CinMVGvy#)QwIk&#By#%%6Cnw)au#L1~`p)zG?#?h* zD0NB-t^M&^^XQN_Y&4HVYF@QPni&_Uf2maUqc%#4bLG|_9b`OMT zwQgSiyK&xFkKDD1i_Na~p*e-%Hmi0&k8E}ckWq0mGGzca^0H^RF86Zs#)yDu*Yeg9 z^IJJj{8ISh4C;6weDQa8hV?&B9P-86Z(Mm33xmuZob(LxC6fodS8QC^DfN*Vk4)$M zSzEpwV}3Z!JTa`Zd2064Rq439i2u(8`+CM?H&ug)>|+Shm9vG}&gyvHrR9!4&a*bh zn@3dIGn-PQ(wnOB^PWt!XF5|shX2hSi9~ir>G^!ByffGp(_Yt9!Rf7g@|+;}K@3u!T=zV4mdt@vhBZ=2nm_8gUUFJvDeEp#I zR7fwRo1bQ11^jQU((TemdX?sXu>G`8gN^-B;}M5E0VDe4V(gq#oM^)vPl2L?=v>1B z#@-p+8s+m@xao6GiS1aTH0Hz0;U^m2D#BBJDm;BFf1-8mDTyQ}SdArzn>RkZc{oJF z(|(K$ZVFG~`0y68eA{=`=NrE)yi@)qJE#wfizr{ny(+%_yRc3j19+w8^7?E4DnD<0sY@pG zZA0(6cqZzP8Sn3M?9ujLtUaf>AEYHyjFsB% zOO@KTj83LE#uGXE^n9`B68dr7GeRGqxI0@+1R5V^*Qe6#9V*z}R13IkMBzxEcaYyw zg=1IZe6Mi%j&L6!+y_RZyF3=l6o)H(#$m&;4^P2s1`>xd(a2jeax{|%=L}1CCf6tK zV4OB%Smu4hL<<>vFIdVG(T#oeuuPltbGq{)@tV2HfHR)@Lz~8QeR)^7|FkW9&9Com zy?^zHbraoxsxlNWi}uMXL$zBOm7m6J>bJeod*q&wbZf)5s5;#bEW72#Maymowd#7W zeMV}^TbxX`2??;>?2dPmInO(%${qVOp|bHpc^f2!i@Ob0HyAFqFcse(q!A;>QT|Ry7{EzbXStNEKyj^EQ(>yJF4@Y$2DZPp_ zWSRWIbP{jQ{R@Bi#F<9kuC?wJ_DUDGmSiC7cXw~o$W?AwR^u!Db@S-r zE9$?6r<$)2$0_41r<1IsviHW_+O#&a^hqW#e4N9Avu~8(znGl5o8;nfWsId6nnfTHSr_Kjqb&%&hB8W*&ET z%_}j6Wc<0Vda^m?S>)|>;~}cUy73egy7V`%Bw18Od9isVS3NeZr2j9C7ucMV3+R+_ zfLBhoP}>%%c?nPaQf23jFY(4XXUeAjNuV$7KuXw&U%A-tU+ZGQv(VX(~#Y=A;P}|Phl+pm^l=p;*Iks(Q zH0HPt`JkhWSOMu@SJ66r0{3`u@-?A}fMzYIVJ zu#S7#OKiW%Y>u^@aK6B;2?bw9U%`DG1J3vS0+~J@ImSj!!<-w?^08#N*wZor=5G*OX> z8~(p!?dZ670d&}8Zt|l?_8B}OiSh?Cl_#S=W_);!dx?EttvI6N=yzd{%GwLC52UZ& zfWK`#8iSok)}BgYUyC1aeA*jjZS~bRcu%1B$NbzSQ(nLv|7Cu9ZUAjvV|UDNd|UV9 zT9=!ev=-X>YwNB(^IEi`w$8?rnu)gc=tLT=k!dYWvi%y{`>C8bBS*h!ZGIv2*k7BU zMP7V+P(>ZD&F6R*u&SoiNhP8_Qp1^b;3p76X^Zb`}cwEv%Ji2 z_kR&>KAbyaevEmrIOFRe)1m+D(_*eHyS6u()m+(i6*pI=J6p1APdZnod6Lsj9uS|d z8{bQWE+?8RQ(kIgZK|Wz{j&q>CH3{SxiSJeb=~|c*5=iJi+-bXWhy&we2F)XwU^={ z<2`}iU*lMN8G)-Ui$9!bu1x*%K>F_;_$%^=H=L;dmK>sb_C|S>X>7}y%RBK{dwJm_ z1CiBhH$t6!9z5N!zUJC;xAseGE<9h+SX=jh1iAaFEhV|nuf()RioH>^Z_dgDhmzU9 zbnTmR*PL39_E@(B?=0nF?6G3qJ{f$&h4oY1nQuF091ty=Hp=DdP(RaY*ZxmD9!RN5 zYexI8{dk}a*IN5m71kI47T%p29-y#J9TRw^`u+ZRfXdGs-?kg~U~a<0MDGdo{x0W# zv_JQ2_KiH?8vI53^PSiS!UGQDugG&U9-w*f=y(vTGmShzdjNjV-U+yv>zwjtCM&0=z}uF9<8;@&F|G|(q2ogzn|bN z+n7i`bNr9)-)V`wQ~UVMk_862F)@Je0N1vUM zVSlPKY#9RA8Mam-XV+AJI=iO0;t;vg5k0$>HM{(4uH!}Tl~gWBq~m;E9>VDqvcgwP z9#R>p{YT}Y9CmL!kDG);l*cWkPgmPgeKan^l0 z3eOwKP1C#u^x<90|7dvHvzWn6=~KFV`flWZln3v^J`f&!6n_~KBAU~q@I-ftlkjS0 z6!Ffk+3IO;n?6f#j`a&WYS&3)YmGU}=Jbr8SxhHsrZ>>J?N@r@#4cJ_(l_G?gFf>I?|bXa^4Zy$%LRvWf?s4O$$HuWPZo%QWF<`D&G8$ zUvLDZen4&JTppdj6pD{rz;hl?JC98CeSh!db`ek1f1^F>=RynfWNvtKaW4Z`%7S?> zk5BW>k^eq!pFZzjX_uS&IPb^1`82A(Yjne@7PsPmA>W=TJe9f1Sn2WMM&tHwybg}M z>&-vB=3h9^qO&J?=0dj7M%$Px=_>YQ^U}?Je^qpPZgAa5c+gn=U#oeP^!?TIgKI0< z;M$R~LNUP;Yf9gr3JS%Mle5#y$=uozO}VukJ7E7(M{ynH_|O&jU&^=d0&fD(#ozTt z)95==hxXE4r3%v7b>EQokmQEl4ZtVMc zwlLD&!J}_VpgOZO&omw<8&kJBJ9N#zY^1I?mXCbu>jz`$+2s`XRQ#XkpMNMd`JQKz z8SbaZuP?8Gza+V@BAM$fZ`Oalo0{HOZe~7BVNK0Fj4aKa7#+o)yLiv3aqUqXsqhKs z%xD~Yhi$FyyJ|EOR3mBC6_M7^#Az$^Ir?{>r1KN-97tAOOOrk z+c>Dbv6;^D?-R$pgwshlO@#Ad!r?B9Lrs~_LYwm{Ey28zg<)Gqw{YI-{%m*p$+s7W zcV`!;*JanG6O(78=ko1bzP*a?{>8qV^|r0mp?v#DrubAbQ~bXAq-6Sm>W*Ne&Usdz zC$HOEH|pMtAH`VfPXx;=`=5XQ?pSs<|F7@);`7g+H~6DhlvDq0NohxBV>#1CTj^L| z8vN0FO3j~NTS~N17SOcHvkCvn;7_aViJ*B9|3AmKx@#j9d+3=wY4{K3Arz19j82oM zN8d_6Ksw^XA9&_?Y59uM(mlJ}LU?y7E#t2!Z_kqUV0|e*{+^QJO{TS9khs%-RQ)r` zQhu55xcuY9GlaTQoTID^X}3M+CxWkKU%Rz>|Kul1lwr>k7cDL&Ca<$+Mrjo964^UT z4~&1J^wfpCKl?`FS{pu-XO@nR+gfeUt}8zmTh9QC)C zcQO2}R(`QRX7*Lsli0UlU&;UCG|Hi{v0S8HR1UfaC0Z{#xZ_*==vMMpYDM=k=CV|MKPk29^KhE6TCVmF2|bdrCoJeTinsywdeOujifWB9{Icx^Yw& zU#L4St%=s9pr<_RV!(tXfBG18D8gt zrP78@UlAj1c%cw5U<#;Up`^p7Qwkb_n3Re}ec0S|$h4htW=Myb@y*9Kul&=anNi!B z*fYL7r{AqAYMRhantYzG$Ilznyzg(Hz0TeDaG@?*c@`w=bI)C8|2gaIv-e(WueJZ4 zMLsFcjE>rPGfv+#I=SO6&ik2Pd7v;@d6s&T>FBQpor{i*alyV!u ztvV(@?Q`>DCi=le9kesiQr1OZRY9(dt|u?&mhT_V^e-IF6?RaEZyNbHadOdC);(?= zW&Ygsr>5^2&F5o&%yWih#C;3pj7&<(+REo||KZ3Fp5t5lc<0peW4!lf>P7i`eBY1g z(HzNBM=s7r|GJAb>s^mu@?7QL@g2`m-_IP}Ivi!A)|IT`w(`G_INYD9{5m@uP49$m zC(ll8B~7F&t8eKq)7;)X#5;Z{*{1sUHf8&9>aE@}mv?@R@3;`TlEZHv>DM>6^zIn0 ze3Cq+etnd0wr{v26a6&Ge50}n8dE8QC;x2EsCc#&c^#GcmU8(=dGb#2^Bqr&=F7;R zSiTN@ly6&e<(|<8nx3ybdq#Qa`AfPhXHvJ8{20Hsot3AaW6$GfcUIzSenm2r{-A#i z-JfL2tCUebZ9+O_c9+eTT};m38#ksCZiS zsjdGp$LGz+MCHfNc*kom?HL`I^>Sqp`SEfnKh7;ya^#8f;q{r6OMm=rqH`zZ`8mo{ zvbUN3+|T~Qk;hv}gW4?d)<%`}+_=sipw9i@xQ)lVsBaN@PWg?zbKWaM%FC!y9zm}j zQr$g_Unl&3b^dzf{`14ne;wVYck*zy_dAu}KDRuS-%P!&{Ig1CaQ^V_Z@gH!?u@&J z+dp;p(C22;?{rXgx_@}!Td!7L{>$>vi_i5`+VYDl*RWT>Ao>1kQ+MU%&pcnb>)E?1 zQU1ZoPGsTWXTIm;;SBOAgWt2b6(;{|$AguoNce$DQ=wdGqt57Tf;Xa9hVJ5h<=@#l z)K8jP_=b1#uMEAxWi+zc_*nz9yJx7tsEx( zsuu@8v4^&>st^2+Ump3vfBa>&y#Ml-M;=F}C*}S3LD)-#nJhzXn|?(Q@2w!-zwz-3 z@PXBv1BB1JJgzspsW+>sH&ZE>h&uOa>S`zH8bCG-df8BI3yYP15!A82`eki9(gKe- zzAQX8s=6<^L4AF`nf7GscL)APVed3k$IG`3KaLFjci$FY_g4n9Yn)E>=EvjrzHu3G z@^@DrKlAy@;Kz_pQ&veYQ@pBpMISFLzxyb^TZlU&{}^o= zvVSV_4c)RSzo25eMK*s|WdZHQzRo?Pe@NVE#N9WCvXI_`&as8^IO6#>t%u$5%c}0P z@RwujKDYhyNNaPnOuEmGdAv*Vsf+ivHPGIEA$ZqC4ZQ33d6(%~=kl&ev<;JJ8zvQ& z4$teofAp?@h~;HVv}3r1d{JGH?xJ=~`AJt?H^kMpuuBu=zP0yXbXEgUbR}*cO>qjaf zm&m^;`t-r)_KY5+|LLtP{Uhhn$CPzpu75<&(>9D;MjJnew*D3JQQsn+fqZmn`YF25 zD%v`9&n#_1liE$=X|9q9i3!=kZ;emChD1M_HCDVvv{TUq%mdHvLEwNIs?D571D%FjDJCXyag z8X)1(cy?xV|L7gApL8PapkeE+38|v*DQ^>?V%Vl0}cA&*Dcvro8gqPmHbrFJg>n7vbA|8T}9Zo_+U7 z>#X1z_D}rLGx)1tnSRgcpZwql7l5LV-SfBCzo{GGq0ZlZa2LYn<=E-|G0~&lT-{vL zGEwx+?c2Bi#gG2vfi>J8#%~t*DexIE&ci(WWg4?|e_Eb!x&Y{GD3547EQ|f{?xp>) zoGixniQ9W5DmP&Vj^?6xox1ib>KH_xsE>zwtNc|Tfc75}Io!zgW6y;xWNXhu*-r=c zg7(gBr`^+X@8oYx+TQ%l+>WOE+%6)opSGaAa$5H9TiZJqoZjpHSMTiy`M@>@fT9g zF~s2-hc&mtvA+_xo}Ur8Eksyz02N*ZBxC>@@2?G~LIt2PzS{J+MCbW%m2Z}CJ-;(~ zCXRm~NpBoJSA!J}RKu%)DV?H^IT1h;p|$UCbMKpx#HkH!V)jC<4;FX;O>Tsx>e0j~ zqxx_SI=IpN8w0uLn*%KObt(4^DfhCJ`_`0OeZ>Z%r|~QUx%vGx;goxC z%Kemg7r;}<@BQALckZ_6fAel3z3&z87B5ZFY!F6JZ|z&VZgo8By7u-B%fGsM#m40; zR^7Jg_P$7?u**5`&_&_4?+=%6TF(&dm-SrVhD|+Da_ZH(Tkya)S&|(`cai;xiG*s< zcKPxzt?ujl!?o*g-4OMxxaIZ;vg}jpDX-?0S1nhPZ2udA*J~&K<;z$0K`u$M2&Fd4 ziNA&UroDV$w%MP%0^aQ1TRiUfc$>%DJ>Kc@fXBN$e$->hZ_zD#tn!fiNsm~Qdxpn(k2^h{>9N`{#VdF`$K$yk&-1wGahJ!EfqHJh<6R!p zH|G3zdtCN-ug6b%{FKN0Jl^l|(;h$L@u0^qc>I#bFMIr&$FF<*hR1JuT=DpT#|J%r z%j3fyzwPlm9>41`Le+gw&SRaMtMAsHgTk8oChY1Va@EyCu&ak)R}aCi9)im%Pq3?p zU{?>pt{#G2Jp{XY2zK=l?CK$S&_D0$A#PU>!LA;HT|ET5dI)y)5bWw9xZjt2|!gagWEn9`|{?+2bu9_j|m}K`@otaH9`E(|NspiMc%R4nJ$~BbXFMMC_yvz&^7v(sU-S5NkKge4O^+)c9{|tD z!}rwR8RtgP7UA=vD32C8<9yCP6z-&6diT4+s3RN-@4_SM{EUyI0}Fowc`XdRy}~^I zwlMMcq2kQ=ZR)2m^at=09u(%<-4eTZqH4&0Aqv0fE)||hdms$m0pU+lzlDjns4d1% z3iH0HABu6mFzVA8 zfS#8wmF3xa9(M`PB7NRn626FDS?}%^CT**{dyRMZcz3VIeIECFyv^h79`E${DUbIF zLw8z4y2uZb8O^|IoB_@j_yf+tJr$h&XdF*+iz0SzvdHmuw|B1+{s{Tw-TlI6dwIt5 zyX6+~_q0Dp$UO%qT&g?D>w@p_3Txo4nwy8ehOOkWG0vRe!kNAQPSns-&?66`()c|@Snr*tWv z@Izc7y=TsfZB@J-7`<=f3h8y87e6n0`W~bAeeOegZ$U4QpMlZ)E*>GhS_A-yi>mGD#gluo1f zQ|_Arb9X=V5LF4-yM(ieZxkIMp4th?l028_iLTy>cLF);mGln-qo*PdkmHr#% zF-M0o(UuX?-kPiYXjEft+AEs91ExoVS5+3ByP&e@dir~LZi=3%u%3zVOtJi7@}`x3 z;gP06#&0S+r{*gAM>F{aQ<(oic6@P!`5e0zT@LjJxKMmrI$f||J+s8wa^Oi=VAIhM2h(|M% zfTcYxtJIz@PhwTSF_2YmvE-Pts&GleXT~k$oj@Y1-1;hH32J9+Ccl{e;qnl&xK(4d z>Nh6shvbjEM@~I-0C{u3M(bM{~h5KdU2yq#7CwaPv9!5r4itdUa{MIsVBdhnnqE91hoI>Dz2wR*#N0sLCCB z&b+>jogJl%hmE0i5?<8DNDbV9F8T)pFXvO~6b*bZ6R)3W0&0*<>bi#0Qi?Ste+ zM+16}`U8Mk+0h{#rMfmVmH|H+P0IlBe;W@UYrhqh=S1UU$@wZ+O^JPux4v56lJGIb zkgzdogY?|&`{rQ?jh~wEfvqR1$HVe7upIxN@Gw45ST|Rm%fRAkd?)1LRXkLWhp!`E z$iw}(8{y%7#4B@+#lt1ut8zB5w5NGk{em}JB(TN%)Mb|y{HEr4!PxD;9dI-Dx}J3V zFI&a!UtC%|EFD1efHU20uY^OICjbw$W=c0Qhne=@?_(Sl(G8OQ(QEfGCX9KT%taex zKjWo*??m6vnEVL9YFX@6&z`_ebD(b%|6}VVpn53NVg1U~Ch6u;9XfM+bIY!n%Om4z zUnK7uKjHB~wf_b3M*I@C|H^j*D=o>BP$sB-RasaYtaxhIui-NOSdU&>_NX6ZH8c(E8V-B^A4|VUmMu46 zqjaQXkL{zbz6{N4Ro^R7T62T4QI^Gfsk^?_#Uu1MB7h6ZiI>WDM7m04UD(dcWL~guw7g;b>qR}rTZ!N@{nW-_4c^^6eps8l%XX#V>*(_ESMkx z%~5EipF(pFj@wVMUMB`MAOkLG{M=p1MWD8yf<8&c2U@jnGv9GYwhes}8S!|t{I!4c z-~$KRm@m!v33K@4{hPDs8DsTb6nWW1>$^DqSO{MnK-dRa#J|eh!A8z1C&I>wx5sre z=ZVDI%0C0+*)(rUM&>ON*y5#mdkgir5#E-psMj8g4dUi7e%TA4GS^tVt$ve6cv~`H z4Bl>N{Nl>X8$U}ybLN1fc-x)NJ6JuRmuT>Kd_J$v-qoIu@!7mOcYEgnjgcz+sIz$q z)4q^nwd=AqPqnjo^-WdY55^zH@oZi?Ku+25hkE@FY2M#S9yiji%f4@f_xD4u5#B#Q zyfW8VyuYnM-hXOL-j4?$#?|qc6F@ER!}Ho;+46^;&qKbG}6vX7S(I#=|i03CrLFl zPH{=0;Fb8X`w;tM6*b}YGgz;py^1=uh7JB*$i5)`P2V}F{fe5p=`ZZiI?ww@uNB|3 zK2YlbqtZj8pTn*FX)?uYhV#<%3CoqP9*(+M8_Rk_^kmjNEB*~5=#iYA_AvL0M=m7p zWY!E9*`|uQRIJ188)@S`Zj5B=qX%>Oe=(}HblQWWGWZy43hy629T_supZ|@FZ=E#Q zUlEP}>h`qZ9p&w;%iTUYiFlo?ztbK(vO_4RpSF;OGocYhTPvCTRl}KX&X+0t0(mt| z{KZ4kNm?SlQEAOT#GHw{hc&0m()$zXEQDpcHIM9u5#pVt_Ymi-c%H@f(d3;a_H^p4 zj6AJ57<|(X)(I<)i{Eh{G^=qZ6aF7HCj0h1R~S!0;1 zkSE-$?{+HRXlo3qj!}U%i}a@q>DfY&wWK_kEwL9xp8Vk1sDt!UCRo3ttd(c}NiD5{ zKR;cx+PK28Cn>k}7dSGh%ro8AACc!A<(p?9z$pZ4<6NusLnYXYRwKwN^xAJ)k?<-WJI~gc{1Ia|?xj=XdYZ_gjwmUuj_PELNdxfr# z{piTn&Y|YoShG85oh4&FVyu&CpHSt6)}*LDWf`mxmcPDP{tLaozRTvwXUR6T2XZeF zCYe3n-7Aa)I`O$W;dl5`Q(WIz=%3nW)V^l?n%oIBH$ZjBz-qS2Mc&rG_B4*L4q3b+ zanv3P3$&M;_`Z!xwO;XBxR!B+^xno{b&#N>4PVNANbkvjp18v3eT93`Gbm=6e{K%2 z;tAGqh4cmq5N{}b@;7>a#6A62s#XqOf?gv!!8^n&k`St>Tc<2~9bBRfy#(eGpfl$U zEbZyO{lmojmPGlD#4^1-Z%j1ki z*9Q>q3$Oj)bA$WbbL_ds-te?Ftc4e@X9K977>K_Ysz3jW%s=G*RIvy2U1krsqBDCy z4#J$gqhc#BB=1gKo*|YUt??616RF=%`DY;B5~S?`@%=0p68~Aev^{Xr+x{ElLsZAK z{V%myPGj2xZ^Z&8u?K8i5509r`Yz%P-CjI>Lp-L(9vS2^dlwC`2g>#0>r9S$%INkw zpYic1iuc@=d=2$TxedCwIaT;u-(vjjipTg{4#LKTza6bplfRXJ2FAB({@zT4yhQ?A zyflCJQ(Nxr)YtNbv>`eB-I~WxzZhu7EyJnWNH(8@l!G=`7fb7S- z_P&x0xqGx-vLW@1UXteduzk-H?(9DnI?=!H+B-cXn9JqH^4XuJMA$@=4bttZV6`vy z(fpy>@JX%?&Pg6H4cg+XMpi-lxoFLwAkQUPB5a`gcCmLTpLE89uz|v5yVWt>yyb?i zR%5v(k!x%?$tj)hFwa39Lp*Ks!@V{=Lbmt==7(NlW$ zPUt0&_EUVc)|hj@-|yIIhdWD4I#j%dgY&UkwAM5?D8Dbp z^S_a!*ixD|MPKRBXKUr6XOOq05$0u1&qa%pbGDREp>8!b_+HuB3nu8fTI#N;g4M9t z=XmQr^i8H?g~w{?BrJXV`(F1kzDH_JsJu*FNS`#6^UbRExx zy#F-rMtJ`q@ycA{bzORIJ>K7rd_HGzqO(*j${~SAPnQSlYwEfPXXQnq5HP_p(K`+K@N3yL+(U4p>0!s0A4lt1rkClvBtODBqm}o7%6(w6ra-=kzbx11aIbteFd3r!6K@xNfaV$)k1LKY=@Ij}j99fAe*$D&pGq3aUgDu_IevCg(&CC5wXEV0(oc6}f4d7pj$0oH;>IGz9 zW?%pC={{Vvqhe|J6Znf(v@fP38&Y)jylCcv_?(?E)WN$#KkdmJm650Ww6Ay6I-s)$ z2Oe_!_v;<(l{}(xSLEl84#sSA>|NZXy*f&a4+pecNwdw=M?Bb3)H$lP&&~+!@oa&1fb=*U99ukBc|z-X+paF>Dh+!7<|1(hDSuB#W5lWh>2$R#U0?q1KmYJ;d;Z&hz4`FZuetecmtJ`6 zr!RhO-_K9`!k+(jwf_d%t-m^tvtAez|Eq!4-%7rt!+(c#)gwp#?(0X6eEsW|J;F(P zNJAfKb^Q#-Nz0UDq@}fiv`kC#l(SA89GxCZTe^*uY%}PEf$NTeceO9f-s{G_KNpXF z$M%dpCz@efI}dkPtfw!2^@aADFzI5hKV;FX6hkeYJnoRrPTXGKzavd&pc>Yvu!-KD ztG!lVS_~%fW0(3_V7LI{eiyYJF<46!yR;9lwg0hCHKyDeQ?I3Wnu}j8Yf1kqXw1Df z{^>4$XA(sgaTS^ft&RU77r$C|wW(`j^sqMm87}_jge09Y0kF4wD*lI4@zoMlfineN zc-7}j*KW$KoXI4;P;rc=8f{7W^;^l_E8+p^Q@>Cxm zm8tOCQtmC@E#6YU*uAOnN4#6SHihyor@}w#-Qu??l<)Ub;Xm~5ybJ%3+s{Z|;<+i5 z*Ryf};GX@AiIaUR$%$h|dA>*cFRl_kKi*%^?KA1!gTfz=_bJuBk}cE+?dRAfOlFFQ zweMh$@F!y(@0@evdX~K~#@f%a0G)GC%EWW>pDPR-<>gPfcq{v<*!GiKydyWHU3_8D z=>v<-HXpuS7&?lt@ZNgiyiet*cvFShl-tp7j^`!FU6Mb{vCM~e3&XaXy?cvr2d$@f zKPpUT?q2VHQka2(LGOM+nEe^wd!K1sC#oH$aoMhN=i>T37_GFcn=>X`Fj`P-e^`%e znx?N5)tC6k!nrcB7j)v6)>QQIGj1kQ->qbxLC)XI0*AIpH+4mIhAlarU88t-xqeGM zZY|Va9FkcEMz4rRNN*nxQ@tELJ!|xqa4&i$Z};Jl+d%Q;{))%;Uac9MXOY16-gVrE z?;Yg5dHnPp^0)Wi!@cMly~8+W;x;gPci|Dzs|4QxyCw9*FCjhIN_qSYjGp)_q<0v4 z;#H*&c1-B~8TTQ*xzH1j8}OI|$@!383ywT~qNi5YzV{jKLwcGMG=QIh(R&(?klsuj zGw~BWwZca4$J~n^WE?ETKs6fju_=^X!!HNWAK%Wcu(*tT#VX#)~lSnagUcV5`bIW_&*lO@JEJFrP3=EdeY`>9(t z?ZXEqV`tfUjI;*4bhMO~$Ei4>9k3Ks3 zBi)<`%|n)bGc_;!@rIG#(maa7-J{fnR)w|6pLxe-lNO*|BuqB%-|}9a5la8xNNYdm zt#J-mhvIj$?_0;>VVxY?E7C%0p`?I;fqVT&9Qs$4Z@NRUh9XD~`4t?bL1;KkS<$dSx{mb1$ z|EFx}VnzL#oY@2YfrmNkj=^LR*Cm)xnT&63pCq?vIP!|6S;VO^wd|9|M;vL8o`ckhR z);V#nah6(^_)Wy$Mf}+QzhUHX_bVCgml1W}F&y>&%`onvpA#O&zYn*{?`xDF>2l@Q zLVA_9ZxN<(_~V@)qj7lI$k_^K)A@cIH;| zX5coM%Z;~x-Kf9hU>L4;%Gh$Mod{`g=of8v+&VfONPe5{BWn>`tRo;;Y%ibz^w~)fS zbpz zwf2s68?dWt4XC~i?vbM{AE%|pCboFUFp=G_bM0Z?lZkx`Iwz{ zv|Hb*c#v@O*ooriNpyMlLSc%k+q+i@qXhMP_cmem^1SDH6#ny*9IGnsL4KwtwA(Xj zOTcByxGC@xNq-kl8sz-VEO4kl6=6Y@zv+OAN6|$ZOOS449IErn^SBL+-gS6{^hyCe zJ!|w0a-I zL;}yyz~7y?s%cN_pD&TVr|QHD#$q(Je$2TcvkNxCc5MAq^KXDe|BQPPOIj1xTA-bd zO0?ybhYzSvo=-j06n#!ey2-z{I?5qO}k&8bw_*j z!e6|)(3}&kO|EU_RAZ`eyg4TNMw?^Ox8cjlm@xOTY^O~y*?vN@y4ub10vXcNhzz;p(#FSgC0Bt&hL{bjxw(aXtWE7lzaNOlb2DX) zRo*|^+6yi|en8`#Hg*}6;&I)Ju!XKco?HlyijOyEf5wH_g%T1G@DZ5GQah+{BC>x}#b+(6cIzPR#sPfUj+c5Och9y_Z-;>;8Ud#0F z6!Vo#i8&~wr%>s_W@P`6V)+4QH{w1U_Z7vi*lzT0XzsYF*fpGsK98NsneEJRf#&&{ zO8L_7f98*e7;9~fO5SFSHYp9Qk!);aCfXJv^bbZ5y`=rd5xR1xNB!Sq&h!0lZE(CU z`42|U>nO8#5iJbo_-b#WT>o{$`Zm@s#dc`%@zLxLu`kQt;0*KoN8P&Kj>kEx_1Tf7 ztd*uNP4DP--!-bdX({g*{+CY9ex7k{mtUDbhweW4?JH}&@=0g&Y2Dv3Y`#MF(O*BC zj|vq)F0r|kPxWlR+W3>)-nFtVVu%^rT(bFURQ%e|dN$v= zRdP-)TA#AKB_}1v1$i#neAmk1LE$&~d&zd$eBItHr0^c^mOfgw`FcWwucyAXxAs`p zUQeAtE@$dN=x95S1Qd9;Y`lKqlhnowGAV7~DL<-yNlv7_#!vg0NOqn0&cJjJ=_qRJ zi$0(mMM8BkZP$GkKRs?-sI_o;+y+KZbv~rm8_?6UiYLxo&K1(r`IGf@o-YtDq}LzN z6CI$c*j^cnO+PqvwX(fc|cA-yM|SHv%E*A3v; z6xek$a5SQmEh1i-gs4o8XV<+&f^H{{fu%jIlVRXQWs3y1c%e?FNp@q6E6l#6@p->H z$vYs?$+WHtortqns&lv6h!EOTavLbGL$~fHnk}WVx++-hh<((bSsOmd?SWBkp^U36 zell zs`6d+NO5$@-Nhvywi+ZEsybj`^on?d^bYcn>V@cqa{2SPO(t;b=ofV3!RRf<9n#ZW z?c($ z58dMIQSO-&9Q8ijtg+0N()Mh2c4frIR<*B`Y*X?J+w`Up=2gR)pV#t%}A)U;NnjD*Dbs;aWE?+SKc9 zT-je9bDK|kWv%Y2)hU zz47uU6p@~)O}vly&Y-tUX-UqawsB9CbLDk1?islCJ;}Hy537!65yXpxahHSq7`YNGd9wfdG#Ut)Ugigl}_i{~%?y^B}$ z^=({x%cj27Vbe-Nj}H^cCRSZFFbT4_ZQ`r(lfGe`xEWe`+y+K(J{}>x zcLI8$?xnu+klv%vGoBGmqbD6Lq}KuwOJAsa$<__&y#~EdS2B9HrRYtAp6Y1YChqt2 zKn~ha9`>38Z1lEpAEvJWy&`^ToA`eGAkhnQun$KlGn96LFiB6KLcB7b`exYin7Uy< z`TV8ishEzOY28p`yHC`K_o>S+FWAY1nr%0hZg`m;Pm~{ftg|itxWp!IVPC=d7mx^l zmT{ij=F65`9Zkx$WKPRW$xY3imH9~1w9MI=>6wp)xe+Ja@=C5;^ot|0Z~Wina)I*IS0!clL$J`gYJr|gBsBxh~nZcdI zS;mxLCv@Kj4jd^o4NJez6b9WM_F5OGd4Kixt!s1S<3D}dMC-Q+(^r*XaeC{GflG!7 z^expf@O8KNoj@Je;2N)SaFKG2@pv@7A5^<5{!%p)p9sWXVLi8Y<1_eMomV_DWL`HO zEZ#rD9kwrxZ@XakiU&25i+PcsJ@V z56#8a?R56=;*sA0zdOJ_$|cqXcV9EyT4cO-A8VNzx6S4M<*4?Wo?M96{kBBa{iZ*` za}0`W?0I%`rF^c&v?=qSY96h|*4vBQDw)E6IFKnkcOc6=9PK9^nhUa(n6Z}#6wC?RNhe$jbC8@S4xkumbaR=%luy0 zob^3DDp%ZkWux0#?y4xgneufHhVRRk%R_%Hn;npR2>Yc&eQXW|S=X-ZYM+~p_jSI_ z*|pcj*6l=-ee{n6kaK#G=77Xt+!niJkA@(7bE@}HK1dekg9zf6ScgD_IVGZVg`1#i z60(l*rFSQ5%wS;gmh7YxQa_S@=(?In&a8Ul#n~j{JWfp$%=-{32GC zy1qv}@7&OppWK?eGdVAJJntxj4tIKmGsUX&j(#E;4IfW`aM0!*J#wHhsCh@r;J+{C^5eEEF(W1ZZ8h&e}FzyEiCJVd{xn{#vsIhtY45#>bj9zEX( z|C;$mnn#6AN8Fo6{w*?_xmhFq`}Vl+Xr}M^-%BprIuzzDHIsK*8^n5&)?EKJ!>s=~ zM1HwGSn_N5M=t&&qxt-E%tKnN_Go$sG;_pJ-kbr=mhO9p&-nAo$bQA;y-)Jq7UC$J zJRNB#?4J_$*kg~KeKPdDN(LCbkvT>iwV=I_eI#y|LLDa0gTGFFu4)5cCy!z5R-f$k-Yul?+1@R^M}4v@yjw`&>%2R*hhSUR zz9V97VSmymt2s*59$K5R6t~iw>h{p$+dvQPrXD3h-#LT6*j{1!Ui*a+Y)az{CRWY> zCw;THk)KhP+2S*OxViP6ipQfL*cug=8`Un@B#Vyft4&4pSwD{2&cr(3SasOII90MP z)KB)JFG`+`)mN+eMtLI!HhS~959w*WgzAv!shL+i=}+mt+F8(3-7zqF>Au>R1A3xk z^wNE`tDslUM!t<_!t}ivd@tOW(Cg1bdPV%k>Z_fHa@L4` z*F(HP5~4hWEnWI_uXl#}-7Ma_2|oi%JNiLQyg3xYG5TsRKM`B{lFJ)km$JFeIKI-^ zi9VzC(Xxv*2Fx@xHtT&q95ZEEF1jt~ zsj35R?f`k`@(^A1F6pX;Yur3}jqg)$q~mk07V|i|w-0MAwDi+6pfBB2?>K{Zboh5j zf87)7qo|}Ohfb>Y)j;bDyV^Uqopw*ly_3H&X?ycGb32;u<2k%u^iY*cmd!?-zKL7;o@IZdv|Hb% zctokuKNop-NtmKqzP)4nQ@N>S&;~QN0R!YR(r>*@SDO zDFz3#_z!icE?93Ge$t`DwYn5n^;vq2apoX=kjHIc9KHaLklr#LP(2boJ!|xqaUasF zKu>8jFnUYz2!7mvLV8=EXWuKSVDz?mdLRc&ptsi?V8s*k zbA|MFL9d9PzPF7_@s!R7xFFFBa_|n0Ms(1b5ZK3uDG!gQgT8@+_GM37NO>Vh>!9lI z`)(ZM{w*HkIageH0^>QS-h2T`j{pBA41AE|nPEMYEFbUr0^!(<)vt6te3kdAtuwHA z)Wa)Jq#j;!`4tWCms~!EEhIZAnb(Xxq<(Jg6UBUFw@;L_ZA!6iqdr^L-<{YtH=_TR zhkg&;`a*Q@s1(~a>@n5MdL2H(|!P+P4M)pjK_a8!U?!f-=diJsQiL&{$1!%K| z+Uf7~6HiZUqe`u9q%&X5wwaX2MyiyD$os^`$rb6-_j^I*>g)wIaC%#1;I?m69)Fg- zprS`AlY9MMP#u3doGU$uopZIbbI3~eg1S1kaSB)a`OdK$xyD{lSG&ESE?_UH#Ksvc zZ;jY{N_#=seCK2@sL~^&Q@suGL+pbnuv-e)H95l1;9HMnQw;LV`?3kiC+s3O_gdr2 zA98uUggMbqG(U{ZGZmZ2%^Pw4vHfNHNMR36!TvdGfO2^d8YW(QdXfOU|->B-oQOYN+A?`%@4R9ZWG=(b2MxqV|Fv-Q2 zE*=97c>uDJYU8)K_>%82n8p{oWFytaKUwyX+LYQyO78kAi_K6vYWlQ$?oC5%n!pjmXdE@9jYg;6ZK zy?d1~3T3}{Zxfc1`F?Drnw&eT(_W!R8%=TcR3j&uHhx|AACzvSvXvfUoTV}nuNoK! zrER8FJfQMZape4^xS!(+>1hsg9zO%c6MTn4$vl%w`gc>b=TOy%Tx~RN%L}6IV<}&a|%jHtBn+ zPP|WDcExNz(W0?AaD~en)>Y@lAC%0?aOVx7bM~^A)Q2~082ZPzI6alm`TR)KT|N_8 zK0QMpd#+d<=CjbBcCl~hy%p&!B)>INx^b9%Xw60Y-5C(tAL{=(a^we5cZKly{2=9h zIA2V4+Mt`8iF{^|(q09Xcopi+|59BObaSacFZ@>36^#Yoxpr0Gnq-G4=VB1}&Xw_9 zETeUHkZT5z?V=$W{@!G=z3|kNqiO@YxeTmyX5kUaffrz8$tU?KjxM>c;xb<6HrmCd zXAO*==HQ0(Ugja=dw3wBSK=PV>9ywvxoJeM946jAF3CJgV~4+oUIJy_dtTzIradiJ zq(gMqiI>dx+I;KAbq%cRy>gDN^cZ{X#%pm#*2op?*+XgG5BW*?J6{>@*LUdKg7qD( z*)dmmRP#WeJ05F1P8XpBtOmp$_4wWTBotHp&UA|eREFYrm)&-*vmEm5S=swlAM>2? z}DjH|H^qYKq>;8=%^So>5b@Pz%V#w>i zPrQ)Vm*Q@O*S8a|5ni9md)fOs0ZV(D*Lw+Ap2VttBRa&TCvqnAm8L>8us-IEI58(Z zucO-pU^O82s>kb&p9xk>@jBz@352|k)fjR+<3_(?ez%dS@mLVU7flp9N$q=BDt4dd z`DN6{dOY97^TszSsAKVbk+4vPtm2`1Jbyj$e$_nRNc-ML`c{w@1N%m6-}^S)qAeuH zT$?$2_T|2TAG>{jD(l`>!}A%=>SK7fRr|$vXl_rDH8J_P|C#wc!|KnT*Rf}GUc|bY zyynIXj8=*djItjD=knb@Jjbm=DUCpSdM^4eqaCbmiT9wdjIa*okmlBC{hWQLbcfK6 z=(GTEFV{8kd1wpTr`^)p-m>8IF1DK0c)&!{F;v&8kaM=_n#99udF)Y74w;RiZT+~OAlxe-UIA~qYg*I4 z@cr5;Bx?MO6w)@4Mp;BJCtK@;%-ED(faHPab>6I(tC|Q^b*iMcwzc1?P=X*5$XG%lc%cRSe0Yz zoFE%(4d9hmnx-?h9Lw=ephk|V&jLALHswGtj`~LM!k~QIXCbEQL@(NGihIO|fLsoCxxPC*F=b7>B z$8f~Q&$O9P@S=!U`VJ`vf(UpM3!?wBXvJ;q7aw7XO?oY{w z579d7j2*3Us#JE5whz)5%9*({620Vl*AIGxbyUa*=Gyk(6Xly!sCHw-$tPi#IjD z@V)iF`qya4%kAaQ;-B#Cr>Hy&%gbtm$|{sUQ{gpbtLYMoCwGxcyl%Cm#J!a_w@&X6 z{sS(P336}Ynx`8N_Fm@3)Vy~F@6F?<_p0XEdvE1FlzUI(Zba@KB;H{z^&PfxiJt1H zzBQD4>NojE_!(H*({fLG+Z`4OZ1EDkXyc0Yw>Qv#J9|#!bC}k|2~G5(GuZizoxV2Q zxq2gbQ*SR=V?-HjJgvDXV%LT1F-YTd=}f)oMl(}kkdD`Q5FQoo8C9IDkE_pAnYR?| z{O*U6bI+BRp}kj?FY(?H3)(xjP@EDxUaTebl0B^vc|;Yz>Uw7w`z_JqbOfPxL}r z{T1AzXRx1}da{2V{vo}mgY?PY()UN)Bd2;n4i59*i0sdkhyoW?GMT5L^on*YQn>+2 zy!VRu*8N-B)3W~!;(e=5JapbGE%R4|vtuFRkqZe`({2-ZkJ@J49%1T)STWy_?pr z6u!N8#md#-SZn0mPXD0v$Effh+UrALL=V<;Z=(y_bF90a-sGQC*qcGv5Mk)kBhrl(_CgTGoc8Ig4@knE3c`Lu81t-> zuw6me%Y;o1!nOoqe?b^~>?F^v3c~&kVVq;-!bP0Uo@*vofomZb`Tm}C{tnv4lS${7dRhgOcCnB4QIyV5g=S}u<`a)NygzV@UWGax z!_hWDExpN(p2{GGqx)DaL|8U~#Z^AbCPqg(d;+8jApT zjX{uyfcAOr^jI|IR+}JP@OX~Ls$=q(t|wgdxXWYJFZnO>xa9E?k5xAnE?ri*+v8Op zukl#&PT{>C_j$b8<1HR<2hYGx+3oS5$8UQ4j>l6eH^q~#D7?tyH6CyCxa{#W9;>`% zA06-*;o#gFW0C)1kKgwA9gpAjIHD{SPvaiKEgrWSCVl6igsS|q6f8eC|9hG+-|zAt zdu)!}ZT!7Qd&|{>`sP+#MQW@q)spekfIg^kK-FQ2p~lt<=juozD4aIOVY7{P;T8`X zD4yVIu24^Ul7M~)s8}f4#Fo*Rn&=w6z0gv*8W=tGpM~^h@__1r=uz|uz4hFSo`Gzr zdFB8cz1z4C>CJ^+9zW5Ozv8uUeT^%$wcdu_Mfe%myM%*mh&p+wgs0@3>?YAudPO_5 zwfYE9eKjz8XATM&fh``kmL0Cy(ERIP$9a+}(<)dEh<)nWS~h1vF=cB>z8I(s zWl~8HR81}C^4@XGakaBz^5Z6CJ}4O@`K)?tysmm5mWJKW!awBAr932FG`>_kxv%0f zKH&D4bEeXBqPuy>cu{FFdL`~dUSEp45nfljx{pgbkEPM*hrB+Q_kN5x2A1|TulEwr zZIQqh&upxCPX5?u9nHREP9g4w8GEjQ`mTV)#?l#YnokfFt80BpM=Scin^TbJ*@eN6o1YWqXkqF7R^?LLOCl%vU8iiRN0@_L*A^=Nkac zO$b5j4y{kTNI*Rqb8hf}>XI&j^2U!L21_%lD>7K;7n``;m@TZg&me>I!d~${hXkuE zw7$;iPc+KPa=8n_YE(~1e_GvRV}`amBvg~)^&;aY!X{KdQIV`NQ27Xymy!iVE`fAh zm7(g1;^LeUbZ+o^)b8FM6R2)1Eq_XRw)@x#j>H?Zw=O^fbPi z$4~S`*V4C=`%otC!`+BXtPt-o7u7ELW_`cj8Op@hNbCjp8CcrWGI0*+WAC&CES{H% z%m`e$W@7{6j8~dSY+&xV>=Yo8iFUREdBpkKj4ckb4=r;okbBItc<6x6S;$0R9LgPj zBG(oz9(srVhX{Fz`#_dB_0Cri?->-ixvo9;t<2)~=vD4dE*U7Tz6#;EUlDJ~xadw_ zOz{M)*g=?+L&zJGLnkD6+&l$O_!P3ktOc1v{wV(pjDNNE!+1bpk{gma1{Uwrc!Yeu zorlDS;_=W9`z-E|&&#+Q;q%vsr?`5DF1@!NpG&6+*Be>d(|oReP>rh@SiFGG*Y!5S z=eGTK1AOl7*Q5BHu8-E-V3GOX^V#bUy+?Bj==*Jgx2dkJx#Ba-wfZ4@Rc~dVk0s*w zR`PHMJzq{o67OsNrRhwK$be;h_@Y=R`l6(EIKjq=c#iLfM;`GZlFvB9*mykK}c^I52^g*r?eQo-{(GT>m^$n;q#ru+s8FlKgT@Y+X$cc5HIXw#_8Zw zm(88+J1!dR)3n%Q_j8;|d>+c7s%01F;qm%4jn5r#`#g8|Qlr;xxWkQ#t#Di~m#a79 z%jb^lxH0-f>d$;Xe0~*WVLYH>IToL%`!kQl=Ot+Ts`)&$UoGuvonCz2tq<~G@!)ei z5bZa7?(?SJS)RWVKJTTitv2X#{R;Tpk^K#yQ?_b*t^NIV_9r^LR#1H4PvoF2EFLEARA1}lSP5Rz6?${n(^fUFV zx3Et`2m3FybPSBPv7fBYJJtNe7WQ7yy2duJc=-(C&&tQ^9;4{NQJvezKDzEX?L%wN zDZZZ5-VJ(A86>_B*X^hd7!&)w{G#@$Jkg;i2A!#Wa>N2=);w?}MDj(K=qbH=XDFMyc(2yF8|X1X+J<_D zc;Rk!nU(CUt9#0AEC?@{~2^~6V98SXtGj$UscGt`F+L2 zL#14WdVMge0|I@gWZ~J)75^zLpK?cc#zpJYHYfVzmf&*%QM`MFmu*zuBF}5?tCMY1 zWRqGIioS3PY`BcX-~_Uw+QIANMMWS<;?9X zSFD!`IJTU*wDI-av*Ls%az;Afv2?l|y5LwkU0Q$CGsn{()AFbge81YFMs&Kc?DhOu zdgI9;*XAbqV6{2+kX);kgJbJ}s*{3P$IC?=k(GeL&QDx%{r!}8D=*{uZgJH!Ie4dY zI`z-pNg}RY*Sl%s>gBzCl8)xf^POCY-iPvP`k<4Me2B@&g~XFSxJXz`{+{N)`IJ?4 zziL{>O^Qye{le<$YvPAcj`pKVsGQUK-+cTeW2^@Ca<4Ksu$q_N4`={-Dx$Rhr~NZb zW{F0bE7Y5e-u3v0>C+zfdHmA)-!1qdo|G&HzY6{DN+S-ow5R2=)-i0X6VK%G>b^~y z7BjY7o@0aJW9xr|DY-2DZ|Uqkqw(6vheov~(wzr`?nm-k=jQQaZ=pHdzng!3C_9%u z7NaR6=Yz@D){YMLV`twoCJQr<_{`yRSbvy}&K#KRvFwx3^ z&m*p$Z^_?1BD#t%y3gca7}8lltsiO{&bF0wUTCY%C(5Cls;@xl&~ti5@%3KTFShc| zQO)0@wHp?#X}r5-aNFqr1+9MG_g{!p8m{2+NOJ}Ctbx&6fJZ3X7eP;T zL4K-nMo)bJ1oeU(ya2sMbndr_cbF$s*L8`W(T83FO!|$kPF&Trr)B#x9$Hx^9^<2P zY_~`akdC#ce)gp{a5A=RpA#oE(YYnt54-gqi-*;J8g-YEx#gx@x6XizTDKJTjArtT zrSu|uW%ox9sbAIYo2zy}GA|dEhG2~gSjRoo?B#DR(wSi;cV@HtUk|Gfpzv4t-7xZ7 z&^NzKv1?e*XzyJ;FM7OxB-j1o-&h=F5%g>N4#M)^OW1<;soR?G$=%!Z4R%_h^R=gy z-q+I?y8lx9)Co7P!yMB9;{9>UiI3Ij*rT4jw6;OtE_q3tntRAisT7WzK%GePRON19wM9G;%D-L6p_$%Kadb(ZewGVSmcSd_6%$t+ zPtI$(LVD_pRNY9+)1~+!R(e4WrZp%}H9n<;j3rMO^4{w_Z6Qm0TAsd4yft;={eNzr BnTh}a literal 0 HcmV?d00001 diff --git a/ports/arm11/gnu/example_build/libgcc.a b/ports/arm11/gnu/example_build/libgcc.a new file mode 100644 index 0000000000000000000000000000000000000000..da2319e054c6692bb3de60fa55da6df1a4688f6b GIT binary patch literal 261004 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 z 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 z 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 nKB9ljYz4g)KRy?58ys@X+V}; z`_^9GC(X{xd*7Rx{buI(zHk1$qo*tNxhrRePXrrj{N$;L$+2grpPLGTF>}lR4T6bj z+%PmVEFzDI6lO(+UJ==I-n#vN5jj{FdE|AGCvZK$^)G%!8zwMHo6(wo(K4bd_} z64vWWH7SSJ!?`y@DPOMD-@tF9S!qi7wXnHdoi~27x)|0j&sT0px!R~SoABSLE-XlS zp}K?z78+p)ueKZ_-FjHTL;STj8?#K)CfT^LXfHCshLo=^+32-O6&YTuSDPqAcpVWj zg)Y@10sE329~&DFg6MZ@auTtLG5nHdhJSkD;`4<<0RpyEkYf_ZM1C<~uJ4*O-Z9xP z``rBj`8uvW3-afb<(47=Z@p2 z5>{rbQg{-A zhP56>D>914X2omUGRrZrPsI4hnrRF$ixL`NvoZ_6S-1Wb4K>5-O)1S+niVO{HX3BH zjFnliNU0t!l*m(ZIhhOd;q2Ad%9rbv#ZXG;UU{j6eo?Q^UTvabcR){om-VAkvu!d? zKW^$Ml#!^YrDi3ce9sQ_}Pf;)2h27>O?`6MW?} z=)CRlj<1Xo@s5EG@Xowya=bHjuPxP9dNJx@8c&0Ft{xQcjCeD_JCjq6cebwhtNk^{ zy9dKNr-w#}*G|8ip0b*B8vX9KwvrS@9QD+h`$fVJlL90T_yj$}V=?gbK0^rPq+%hzo3rJ{c3RZ&+7pXbCXEjSX(Euw}%wl`#Rf zDH3f;jtTg-rMVZ?g;SE9gk9IQ;{l)9xPZ&7i;8kDaX|YV<=x4+0Q-uPrjgW>Z-c?F zJ7O&Ai%w|32P}^w>_A9@8No{hz@3xc6to zpMg`-yyzo|hz4JfLf@->Koz z9_O|^-(w3!pyT{i2S{h8yZT1AWBZD!2lG8z4+?fhycX?okxjq1XIo|AAkI-bj{Yg!)Gvf#fGJ5)2CPp1)q|Z zJ!$hENBNq{1Yh~=TFOqaFasUX6$)5rL+Me_Ee-YY4{IHF@H)q=@z3u&MhA@Q!r`Bj za5g%i%dBgtm+OG}oQ4HKt{sn2Z=1|%m_h;d=%>d#vkbmp^u3!#a98?v%v4Tez17@AA1@D@<;5_TaAV8u?7t#uc*OzG8 z2+DhK0RxV7Jdk@d{Bi2C*^D*KNc!>4F zwMFEiBL;E)mA=kD&LFI5AQ**{*hIbnPD!6hV$)qOU$!F6cLre}n|_9P8f_HF z{qBQfdi-DfulgSl6!z?=7;uEBp(HjD!x2&GpKo#jbxaIb8Rhxz{r%K@w@O?e3VTk-7Ws_MhL^GN0nl60-2iXqkktFmK6ROQaYl6~u9IVb zQPO_0Rr_-{`X%3^Y**AHRVTwS&T$_^_&vA)PKkUZ?#b|VOOE5SoiIJ7tLc>y_I13w zh^NuwUiPF+*X&?XO9^y9EZmYm^k9lI!L2^&?h7_SpLv@KWe{ zsrSHc`7AqEC;*-frAIt>ihuuLUeEV^MRnmo&q+8N`_^UFMc~_sxOZN`4E|=gcN_Q8 z;9kD(%LHz7?SDE@|46o<*tk#2qoe^&q_N>Xci=%hB zJ)7IJRFmd7XS>;K~1)Mo2KIR3ER)`e`u9UURD z^1J_=Ko6O@H{K;D*LB$M;^C-y;D-A|o*n1MWIk<>j@M||51N^e?R8B7LOFV^1NrMQ zd?{;q!~7P?I}I1WDJdVX`(x{;(GEGbPF +#include + + +/* Define ThreadX basic types for this port. */ + +#define VOID void +typedef char CHAR; +typedef unsigned char UCHAR; +typedef int INT; +typedef unsigned int UINT; +typedef long LONG; +typedef unsigned long ULONG; +typedef short SHORT; +typedef unsigned short USHORT; + + +/* Define the priority levels for ThreadX. Legal values range + from 32 to 1024 and MUST be evenly divisible by 32. */ + +#ifndef TX_MAX_PRIORITIES +#define TX_MAX_PRIORITIES 32 +#endif + + +/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during + thread creation is less than this value, the thread create call will return an error. */ + +#ifndef TX_MINIMUM_STACK +#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */ +#endif + + +/* Define the system timer thread's default stack size and priority. These are only applicable + if TX_TIMER_PROCESS_IN_ISR is not defined. */ + +#ifndef TX_TIMER_THREAD_STACK_SIZE +#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ +#endif + +#ifndef TX_TIMER_THREAD_PRIORITY +#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ +#endif + + +/* Define various constants for the ThreadX ARM port. */ + +#ifdef TX_ENABLE_FIQ_SUPPORT +#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */ +#else +#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */ +#endif +#define TX_INT_ENABLE 0x00 /* Enable IRQ interrupts */ + + +/* Define the clock source for trace event entry time stamp. The following two item are port specific. + For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock + source constants would be: + +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) +#define TX_TRACE_TIME_MASK 0x0000FFFFUL + +*/ + +#ifndef TX_TRACE_TIME_SOURCE +#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time +#endif +#ifndef TX_TRACE_TIME_MASK +#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL +#endif + + +/* Define the port specific options for the _tx_build_options variable. This variable indicates + how the ThreadX library was built. */ + +#ifdef TX_ENABLE_FIQ_SUPPORT +#define TX_FIQ_ENABLED 1 +#else +#define TX_FIQ_ENABLED 0 +#endif + +#ifdef TX_ENABLE_IRQ_NESTING +#define TX_IRQ_NESTING_ENABLED 2 +#else +#define TX_IRQ_NESTING_ENABLED 0 +#endif + +#ifdef TX_ENABLE_FIQ_NESTING +#define TX_FIQ_NESTING_ENABLED 4 +#else +#define TX_FIQ_NESTING_ENABLED 0 +#endif + +#define TX_PORT_SPECIFIC_BUILD_OPTIONS TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED + + +/* Define the in-line initialization constant so that modules with in-line + initialization capabilities can prevent their initialization from being + a function call. */ + +#define TX_INLINE_INITIALIZATION + + +/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is + disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack + checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING + define is negated, thereby forcing the stack fill which is necessary for the stack checking + logic. */ + +#ifdef TX_ENABLE_STACK_CHECKING +#undef TX_DISABLE_STACK_FILLING +#endif + + +/* Define the TX_THREAD control block extensions for this port. The main reason + for the multiple macros is so that backward compatibility can be maintained with + existing ThreadX kernel awareness modules. */ + +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#define TX_THREAD_EXTENSION_2 +#define TX_THREAD_EXTENSION_3 + + +/* Define the port extensions of the remaining ThreadX objects. */ + +#define TX_BLOCK_POOL_EXTENSION +#define TX_BYTE_POOL_EXTENSION +#define TX_EVENT_FLAGS_GROUP_EXTENSION +#define TX_MUTEX_EXTENSION +#define TX_QUEUE_EXTENSION +#define TX_SEMAPHORE_EXTENSION +#define TX_TIMER_EXTENSION + + +/* Define the user extension field of the thread control block. Nothing + additional is needed for this port so it is defined as white space. */ + +#ifndef TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION +#endif + + +/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, + tx_thread_shell_entry, and tx_thread_terminate. */ + + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) + + +/* Define the ThreadX object creation extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr) +#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr) +#define TX_QUEUE_CREATE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr) +#define TX_TIMER_CREATE_EXTENSION(timer_ptr) + + +/* Define the ThreadX object deletion extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr) +#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr) +#define TX_QUEUE_DELETE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) +#define TX_TIMER_DELETE_EXTENSION(timer_ptr) + + +/* Determine if the ARM architecture has the CLZ instruction. This is available on + architectures v5 and above. If available, redefine the macro for calculating the + lowest bit set. */ + +#if __TARGET_ARCH_ARM > 4 + +#ifndef __thumb__ + +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \ + asm volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); \ + b = 31 - b; +#endif +#endif + + +/* Define ThreadX interrupt lockout and restore macros for protection on + access of critical kernel information. The restore interrupt macro must + restore the interrupt posture of the running thread prior to the value + present prior to the disable macro. In most cases, the save area macro + is used to define a local function save area for the disable and restore + macros. */ + +#ifdef __thumb__ + +unsigned int _tx_thread_interrupt_disable(void); +unsigned int _tx_thread_interrupt_restore(UINT old_posture); + + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); + +#else + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save, tx_temp; + +#ifdef TX_ENABLE_FIQ_SUPPORT +#define TX_DISABLE asm volatile (" MRS %0,CPSR; ORR %1,%0,#0xC0; MSR CPSR_cxsf,%1 ": "=r" (interrupt_save), "=r" (tx_temp) ); +#else +#define TX_DISABLE asm volatile (" MRS %0,CPSR; ORR %1,%0,#0x80; MSR CPSR_cxsf,%1 ": "=r" (interrupt_save), "=r" (tx_temp) ); +#endif + +#define TX_RESTORE asm volatile (" MSR CPSR_cxsf,%0 "::"r" (interrupt_save) ); + +#endif + + +/* Define the interrupt lockout macros for each ThreadX object. */ + +#define TX_BLOCK_POOL_DISABLE TX_DISABLE +#define TX_BYTE_POOL_DISABLE TX_DISABLE +#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE +#define TX_MUTEX_DISABLE TX_DISABLE +#define TX_QUEUE_DISABLE TX_DISABLE +#define TX_SEMAPHORE_DISABLE TX_DISABLE + + +/* Define the version ID of ThreadX. This may be utilized by the application. */ + +#ifdef TX_THREAD_INIT +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX ARM11/GNU Version 6.0.1 *"; +#else +extern CHAR _tx_version_id[]; +#endif + + +#endif + diff --git a/ports/arm11/gnu/readme_threadx.txt b/ports/arm11/gnu/readme_threadx.txt new file mode 100644 index 000000000..5f36d8ed1 --- /dev/null +++ b/ports/arm11/gnu/readme_threadx.txt @@ -0,0 +1,496 @@ + Microsoft's Azure RTOS ThreadX for ARM11 + + Using the GNU Tools + +1. Building the ThreadX run-time Library + +First make sure you are in the "example_build" directory. Also, make sure that +you have setup your path and other environment variables necessary for the GNU +development environment. + +At this point you may run the build_threadx.bat batch file. This will build the +ThreadX run-time environment in the "example_build" directory. + +You should observe assembly and compilation of a series of ThreadX source +files. At the end of the batch file, they are all combined into the +run-time library file: tx.a. This file must be linked with your +application in order to use ThreadX. + + +2. Demonstration System + +Building the demonstration is easy; simply execute the build_threadx_sample.bat +batch file while inside the "example_build" directory. + +You should observe the compilation of sample_threadx.c (which is the demonstration +application) and linking with TX.A. The resulting file DEMO is a binary file +that can be downloaded and executed. + + +3. System Initialization + +The entry point in ThreadX for the ARM11 using GNU tools is at label _start. +This is defined within the modified version of the GNU startup code - crt0.S. + +The ThreadX tx_initialize_low_level.S file is responsible for setting up various +system data structures, the interrupt vectors, and a periodic timer interrupt source. +By default, the vector area is defined to be located at the "__vectors" label, +which is defined in reset.S. This area is typically located at 0. In situations +where this is impossible, the vectors at the "__vectors" label should be copied +to address 0. + +This is also where initialization of a periodic timer interrupt source should take +place. + +In addition, _tx_initialize_low_level defines the first available address +for use by the application, which is supplied as the sole input parameter +to your application definition function, tx_application_define. + + +4. Assembler / Compiler Switches + +The following are compiler switches used in building the demonstration +system: + +Compiler/Assembler Meaning + Switches + + -g Specifies debug information + -c Specifies object code generation + -mcpu=arm1136j-s Specifies target cpu + +Linker Switch Meaning + + -o sample_threadx.out Specifies output file + -M > sample_threadx.map Specifies demo map file + -A arm1136j-s Specifies target architecture + -T sample_threadx.ld Specifies the loader control file + +Application Defines ( -D option) + + TX_ENABLE_FIQ_SUPPORT This assembler define enables FIQ + interrupt handling support in the + ThreadX assembly files. If used, + it should be used on all assembly + files and the generic C source of + ThreadX should be compiled with + TX_ENABLE_FIQ_SUPPORT defined as well. + + TX_ENABLE_IRQ_NESTING This assembler define enables IRQ + nested support. If IRQ nested + interrupt support is needed, this + define should be applied to + tx_initialize_low_level.S. + + TX_ENABLE_FIQ_NESTING This assembler define enables FIQ + nested support. If FIQ nested + interrupt support is needed, this + define should be applied to + tx_initialize_low_level.S. In addition, + IRQ nesting should also be enabled. + + TX_ENABLE_FIQ_SUPPORT This compiler define enables FIQ + interrupt handling in the ThreadX + generic C source. This define + should also be used in conjunction + with the corresponding assembler + define. + + TX_DISABLE_ERROR_CHECKING If defined before tx_api.h is included, + this define causes basic ThreadX error + checking to be disabled. Please see + Chapter 2 in the "ThreadX User Guide" + for more details. + + TX_MAX_PRIORITIES Defines the priority levels for ThreadX. + Legal values range from 32 through + 1024 (inclusive) and MUST be evenly divisible + by 32. Increasing the number of priority levels + supported increases the RAM usage by 128 bytes + for every group of 32 priorities. However, there + is only a negligible effect on performance. By + default, this value is set to 32 priority levels. + + TX_MINIMUM_STACK Defines the minimum stack size (in bytes). It is + used for error checking when threads are created. + The default value is port-specific and is found + in tx_port.h. + + TX_TIMER_THREAD_STACK_SIZE Defines the stack size (in bytes) of the internal + ThreadX timer thread. This thread processes all + thread sleep requests as well as all service call + timeouts. In addition, all application timer callback + routines are invoked from this context. The default + value is port-specific and is found in tx_port.h. + + TX_TIMER_THREAD_PRIORITY Defines the priority of the internal ThreadX timer + thread. The default value is priority 0 - the highest + priority in ThreadX. The default value is defined + in tx_port.h. + + TX_TIMER_PROCESS_IN_ISR Defined, this option eliminates the internal system + timer thread for ThreadX. This results in improved + performance on timer events and smaller RAM requirements + because the timer stack and control block are no + longer needed. However, using this option moves all + the timer expiration processing to the timer ISR level. + By default, this option is not defined. + + TX_REACTIVATE_INLINE Defined, this option performs reactivation of ThreadX + timers in-line instead of using a function call. This + improves performance but slightly increases code size. + By default, this option is not defined. + + TX_DISABLE_STACK_FILLING Defined, placing the 0xEF value in each byte of each + thread's stack is disabled. By default, this option is + not defined. + + TX_ENABLE_STACK_CHECKING Defined, this option enables ThreadX run-time stack checking, + which includes analysis of how much stack has been used and + examination of data pattern "fences" before and after the + stack area. If a stack error is detected, the registered + application stack error handler is called. This option does + result in slightly increased overhead and code size. Please + review the tx_thread_stack_error_notify API for more information. + By default, this option is not defined. + + TX_DISABLE_PREEMPTION_THRESHOLD Defined, this option disables the preemption-threshold feature + and slightly reduces code size and improves performance. Of course, + the preemption-threshold capabilities are no longer available. + By default, this option is not defined. + + TX_DISABLE_REDUNDANT_CLEARING Defined, this option removes the logic for initializing ThreadX + global C data structures to zero. This should only be used if + the compiler's initialization code sets all un-initialized + C global data to zero. Using this option slightly reduces + code size and improves performance during initialization. + By default, this option is not defined. + + TX_DISABLE_NOTIFY_CALLBACKS Defined, this option disables the notify callbacks for various + ThreadX objects. Using this option slightly reduces code size + and improves performance. + + TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on block pools. By default, this option is + not defined. + + TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on byte pools. By default, this option is + not defined. + + TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on event flags groups. By default, this option + is not defined. + + TX_MUTEX_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on mutexes. By default, this option is + not defined. + + TX_QUEUE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on queues. By default, this option is + not defined. + + TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on semaphores. By default, this option is + not defined. + + TX_THREAD_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on threads. By default, this option is + not defined. + + TX_TIMER_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on timers. By default, this option is + not defined. + + TX_ENABLE_EVENT_TRACE Defined, this option enables the internal ThreadX trace + feature. The trace buffer is supplied at a later time + via an application call to tx_trace_enable. + + TX_TRACE_TIME_SOURCE This defines the time-stamp source for event tracing. + This define is only pertinent if the ThreadX library is + built with TX_ENABLE_EVENT_TRACE defined. + + TX_TRACE_TIME_MASK This defines the number of valid bits in the event trace + time-stamp source defined previously. If the time-stamp + source is 16-bits, this value should be 0xFFFF. Alternatively, + if the time-stamp source is 32-bits, this value should be + 0xFFFFFFFF. This define is only pertinent if the ThreadX + library is built with TX_ENABLE_EVENT_TRACE defined. + + +5. Register Usage and Stack Frames + +The GNU compiler assumes that registers r0-r3 (a1-a4) and r12 (ip) are scratch +registers for each function. All other registers used by a C function must +be preserved by the function. ThreadX takes advantage of this in situations +where a context switch happens as a result of making a ThreadX service call +(which is itself a C function). In such cases, the saved context of a thread +is only the non-scratch registers. + +The following defines the saved context stack frames for context switches +that occur as a result of interrupt handling or from thread-level API calls. +All suspended threads have one of these two types of stack frames. The top +of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the +associated thread control block TX_THREAD. + + + + Offset Interrupted Stack Frame Non-Interrupt Stack Frame + + 0x00 1 0 + 0x04 CPSR CPSR + 0x08 r0 (a1) r4 (v1) + 0x0C r1 (a2) r5 (v2) + 0x10 r2 (a3) r6 (v3) + 0x14 r3 (a4) r7 (v4) + 0x18 r4 (v1) r8 (v5) + 0x1C r5 (v2) r9 (v6) + 0x20 r6 (v3) r10 (v7) + 0x24 r7 (v4) r11 (fp) + 0x28 r8 (v5) r14 (lr) + 0x2C r9 (v6) + 0x30 r10 (v7) + 0x34 r11 (fp) + 0x38 r12 (ip) + 0x3C r14 (lr) + 0x40 PC + + +6. Improving Performance + +The distribution version of ThreadX is built without any compiler +optimizations. This makes it easy to debug because you can trace or set + +In addition, you can eliminate the ThreadX basic API error checking by +compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING +defined. + + +7. Interrupt Handling + +ThreadX provides complete and high-performance interrupt handling for ARM11 +targets. There are a certain set of requirements that are defined in the +following sub-sections: + + +7.1 Vector Area + +The ARM11 vectors start at address zero. The demonstration system startup +reset.S file contains the vectors and is loaded at address zero. On actual +hardware platforms, this area might have to be copied to address 0. + + +7.2 IRQ ISRs + +ThreadX fully manages standard and vectored IRQ interrupts. ThreadX also supports +nested IRQ interrupts. The following sub-sections define the IRQ capabilities. + + +7.2.1 Standard IRQ ISRs + +The standard ARM IRQ mechanism has a single interrupt vector at address 0x18. This IRQ +interrupt is managed by the __tx_irq_handler code in tx_initialize_low_level. The following +is the default IRQ handler defined in tx_initialize_low_level.S: + + .global __tx_irq_handler + .global __tx_irq_processing_return +__tx_irq_handler: +@ +@ /* Jump to context save to save system context. */ + B _tx_thread_context_save @ Jump to the context save +__tx_irq_processing_return: +@ +@ /* At this point execution is still in the IRQ mode. The CPSR, point of +@ interrupt, and all C scratch registers are available for use. Note +@ that IRQ interrupts are still disabled upon return from the context +@ save function. */ +@ +@ /* Application ISR call(s) go here! */ +@ +@ /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore + + +7.2.2 Vectored IRQ ISRs + +The vectored ARM IRQ mechanism has multiple interrupt vectors at addresses specified +by the particular implementation. The following is an example IRQ handler defined in +tx_initialize_low_level.S: + + .global __tx_irq_example_handler +__tx_irq_example_handler: +@ +@ /* Call context save to save system context. */ + + STMDB sp!, {r0-r3} @ Save some scratch registers + MRS r0, SPSR @ Pickup saved SPSR + SUB lr, lr, #4 @ Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} @ Store other scratch registers + BL _tx_thread_vectored_context_save @ Call the vectored IRQ context save +@ +@ /* At this point execution is still in the IRQ mode. The CPSR, point of +@ interrupt, and all C scratch registers are available for use. Note +@ that IRQ interrupts are still disabled upon return from the context +@ save function. */ +@ +@ /* Application ISR call goes here! */ +@ +@ /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore + + +7.2.3 Nested IRQ Support + +By default, nested IRQ interrupt support is not enabled. To enable nested +IRQ support, the entire library should be built with TX_ENABLE_IRQ_NESTING +defined. With this defined, two new IRQ interrupt management services are +available, namely _tx_thread_irq_nesting_start and _tx_thread_irq_nesting_end. +These function should be called between the IRQ context save and restore +calls. + +Execution between the calls to _tx_thread_irq_nesting_start and +_tx_thread_irq_nesting_end is enabled for IRQ nesting. This is achieved +by switching from IRQ mode to SYS mode and enabling IRQ interrupts. +The SYS mode stack is used during the SYS mode operation, which was +setup in tx_initialize_low_level.S. When nested IRQ interrupts are no +longer required, calling the _tx_thread_irq_nesting_end service disables +nesting by disabling IRQ interrupts and switching back to IRQ mode in +preparation for the IRQ context restore service. + +The following is an example of enabling IRQ nested interrupts in a standard +IRQ handler: + + .global __tx_irq_handler + .global __tx_irq_processing_return +__tx_irq_handler: +@ +@ /* Jump to context save to save system context. */ + B _tx_thread_context_save +__tx_irq_processing_return: +@ +@ /* Enable nested IRQ interrupts. NOTE: Since this service returns +@ with IRQ interrupts enabled, all IRQ interrupt sources must be +@ cleared prior to calling this service. */ + BL _tx_thread_irq_nesting_start +@ +@ /* Application ISR call(s) go here! */ +@ +@ /* Disable nested IRQ interrupts. The mode is switched back to +@ IRQ mode and IRQ interrupts are disable upon return. */ + BL _tx_thread_irq_nesting_end +@ +@ /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore + + +7.3 FIQ Interrupts + +By default, ARM7 FIQ interrupts are left alone by ThreadX. Of course, this +means that the application is fully responsible for enabling the FIQ interrupt +and saving/restoring any registers used in the FIQ ISR processing. To globally +enable FIQ interrupts, the application should enable FIQ interrupts at the +beginning of each thread or before any threads are created in tx_application_define. +In addition, the application must ensure that no ThreadX service calls are made +from default FIQ ISRs, which is located in tx_initialize_low_level.S. + + +7.3.1 Managed FIQ Interrupts + +Full ThreadX management of FIQ interrupts is provided if the ThreadX sources +are built with the TX_ENABLE_FIQ_SUPPORT defined. If the library is built +this way, the FIQ interrupt handlers are very similar to the IRQ interrupt +handlers defined previously. The following is default FIQ handler +defined in tx_initialize_low_level.S: + + + .global __tx_fiq_handler + .global __tx_fiq_processing_return +__tx_fiq_handler: +@ +@ /* Jump to fiq context save to save system context. */ + B _tx_thread_fiq_context_save +__tx_fiq_processing_return: +@ +@ /* At this point execution is still in the FIQ mode. The CPSR, point of +@ interrupt, and all C scratch registers are available for use. */ +@ +@ /* Application FIQ handlers can be called here! */ +@ +@ /* Jump to fiq context restore to restore system context. */ + B _tx_thread_fiq_context_restore + + +7.3.1.1 Nested FIQ Support + +By default, nested FIQ interrupt support is not enabled. To enable nested +FIQ support, the entire library should be built with TX_ENABLE_FIQ_NESTING +defined. With this defined, two new FIQ interrupt management services are +available, namely _tx_thread_fiq_nesting_start and _tx_thread_fiq_nesting_end. +These function should be called between the FIQ context save and restore +calls. + +Execution between the calls to _tx_thread_fiq_nesting_start and +_tx_thread_fiq_nesting_end is enabled for FIQ nesting. This is achieved +by switching from FIQ mode to SYS mode and enabling FIQ interrupts. +The SYS mode stack is used during the SYS mode operation, which was +setup in tx_initialize_low_level.S. When nested FIQ interrupts are no longer required, +calling the _tx_thread_fiq_nesting_end service disables nesting by disabling +FIQ interrupts and switching back to FIQ mode in preparation for the FIQ +context restore service. + +The following is an example of enabling FIQ nested interrupts in the +typical FIQ handler: + + + .global __tx_fiq_handler + .global __tx_fiq_processing_return +__tx_fiq_handler: +@ +@ /* Jump to fiq context save to save system context. */ + B _tx_thread_fiq_context_save +__tx_fiq_processing_return: +@ +@ /* At this point execution is still in the FIQ mode. The CPSR, point of +@ interrupt, and all C scratch registers are available for use. */ +@ +@ /* Enable nested FIQ interrupts. NOTE: Since this service returns +@ with FIQ interrupts enabled, all FIQ interrupt sources must be +@ cleared prior to calling this service. */ + BL _tx_thread_fiq_nesting_start +@ +@ /* Application FIQ handlers can be called here! */ +@ +@ /* Disable nested FIQ interrupts. The mode is switched back to +@ FIQ mode and FIQ interrupts are disable upon return. */ + BL _tx_thread_fiq_nesting_end +@ +@ /* Jump to fiq context restore to restore system context. */ + B _tx_thread_fiq_context_restore + + +8. ThreadX Timer Interrupt + +ThreadX requires a periodic interrupt source to manage all time-slicing, +thread sleeps, timeouts, and application timers. Without such a timer +interrupt source, these services are not functional but the remainder of +ThreadX will still run. + +To add the timer interrupt processing, simply make a call to +_tx_timer_interrupt in the IRQ processing. An example of this can be +found in the file tx_initialize_low_level.S for the demonstration system. + + +9. Revision History + +For generic code revision information, please refer to the readme_threadx_generic.txt +file, which is included in your distribution. The following details the revision +information associated with this specific port of ThreadX: + +06/30/2020 Initial ThreadX 6.0.1 version for ARM11 using GNU tools. + + +Copyright(c) 1996-2020 Microsoft Corporation + + +https://azure.com/rtos + diff --git a/ports/arm11/gnu/src/tx_thread_context_restore.S b/ports/arm11/gnu/src/tx_thread_context_restore.S new file mode 100644 index 000000000..9e116197e --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_context_restore.S @@ -0,0 +1,241 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@#include "tx_timer.h" +@ + .arm + +#ifdef TX_ENABLE_FIQ_SUPPORT +SVC_MODE = 0xD3 @ Disable IRQ/FIQ, SVC mode +IRQ_MODE = 0xD2 @ Disable IRQ/FIQ, IRQ mode +#else +SVC_MODE = 0x93 @ Disable IRQ, SVC mode +IRQ_MODE = 0x92 @ Disable IRQ, IRQ mode +#endif +@ + .global _tx_thread_system_state + .global _tx_thread_current_ptr + .global _tx_thread_execute_ptr + .global _tx_timer_time_slice + .global _tx_thread_schedule + .global _tx_thread_preempt_disable + .global _tx_execution_isr_exit +@ +@ +@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_restore +@ since it will never be called 16-bit mode. */ +@ + .arm + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_context_restore ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function restores the interrupt context if it is processing a */ +@/* nested interrupt. If not, it returns to the interrupt thread if no */ +@/* preemption is necessary. Otherwise, if preemption is necessary or */ +@/* if no thread was running, the function returns to the scheduler. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* _tx_thread_schedule Thread scheduling routine */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* ISRs Interrupt Service Routines */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_context_restore(VOID) +@{ + .global _tx_thread_context_restore + .type _tx_thread_context_restore,function +_tx_thread_context_restore: +@ +@ /* Lockout interrupts. */ +@ + MOV r0, #IRQ_MODE @ Build disable interrupts CPSR + MSR CPSR, r0 @ Lockout interrupts + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR exit function to indicate an ISR is complete. */ +@ + BL _tx_execution_isr_exit @ Call the ISR exit function +#endif +@ +@ /* Determine if interrupts are nested. */ +@ if (--_tx_thread_system_state) +@ { +@ + LDR r3, =_tx_thread_system_state @ Pickup address of system state variable + LDR r2, [r3] @ Pickup system state + SUB r2, r2, #1 @ Decrement the counter + STR r2, [r3] @ Store the counter + CMP r2, #0 @ Was this the first interrupt? + BEQ __tx_thread_not_nested_restore @ If so, not a nested restore +@ +@ /* Interrupts are nested. */ +@ +@ /* Just recover the saved registers and return to the point of +@ interrupt. */ +@ + LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs + MSR SPSR, r0 @ Put SPSR back + LDMIA sp!, {r0-r3} @ Recover r0-r3 + MOVS pc, lr @ Return to point of interrupt +@ +@ } +__tx_thread_not_nested_restore: +@ +@ /* Determine if a thread was interrupted and no preemption is required. */ +@ else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +@ || (_tx_thread_preempt_disable)) +@ { +@ + LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr + LDR r0, [r1] @ Pickup actual current thread pointer + CMP r0, #0 @ Is it NULL? + BEQ __tx_thread_idle_system_restore @ Yes, idle system was interrupted +@ + LDR r3, =_tx_thread_preempt_disable @ Pickup preempt disable address + LDR r2, [r3] @ Pickup actual preempt disable flag + CMP r2, #0 @ Is it set? + BNE __tx_thread_no_preempt_restore @ Yes, don't preempt this thread + LDR r3, =_tx_thread_execute_ptr @ Pickup address of execute thread ptr + LDR r2, [r3] @ Pickup actual execute thread pointer + CMP r0, r2 @ Is the same thread highest priority? + BNE __tx_thread_preempt_restore @ No, preemption needs to happen +@ +@ +__tx_thread_no_preempt_restore: +@ +@ /* Restore interrupted thread or ISR. */ +@ +@ /* Pickup the saved stack pointer. */ +@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; +@ +@ /* Recover the saved context and return to the point of interrupt. */ +@ + LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs + MSR SPSR, r0 @ Put SPSR back + LDMIA sp!, {r0-r3} @ Recover r0-r3 + MOVS pc, lr @ Return to point of interrupt +@ +@ } +@ else +@ { +__tx_thread_preempt_restore: +@ + LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers + MOV r1, lr @ Save lr (point of interrupt) + MOV r2, #SVC_MODE @ Build SVC mode CPSR + MSR CPSR, r2 @ Enter SVC mode + STR r1, [sp, #-4]! @ Save point of interrupt + STMDB sp!, {r4-r12, lr} @ Save upper half of registers + MOV r4, r3 @ Save SPSR in r4 + MOV r2, #IRQ_MODE @ Build IRQ mode CPSR + MSR CPSR, r2 @ Enter IRQ mode + LDMIA sp!, {r0-r3} @ Recover r0-r3 + MOV r5, #SVC_MODE @ Build SVC mode CPSR + MSR CPSR, r5 @ Enter SVC mode + STMDB sp!, {r0-r3} @ Save r0-r3 on thread's stack + MOV r3, #1 @ Build interrupt stack type + STMDB sp!, {r3, r4} @ Save interrupt stack type and SPSR + LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr + LDR r0, [r1] @ Pickup current thread pointer + STR sp, [r0, #8] @ Save stack pointer in thread control + @ block +@ +@ /* Save the remaining time-slice and disable it. */ +@ if (_tx_timer_time_slice) +@ { +@ + LDR r3, =_tx_timer_time_slice @ Pickup time-slice variable address + LDR r2, [r3] @ Pickup time-slice + CMP r2, #0 @ Is it active? + BEQ __tx_thread_dont_save_ts @ No, don't save it +@ +@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +@ _tx_timer_time_slice = 0; +@ + STR r2, [r0, #24] @ Save thread's time-slice + MOV r2, #0 @ Clear value + STR r2, [r3] @ Disable global time-slice flag +@ +@ } +__tx_thread_dont_save_ts: +@ +@ +@ /* Clear the current task pointer. */ +@ _tx_thread_current_ptr = TX_NULL; +@ + MOV r0, #0 @ NULL value + STR r0, [r1] @ Clear current thread pointer +@ +@ /* Return to the scheduler. */ +@ _tx_thread_schedule(); +@ + B _tx_thread_schedule @ Return to scheduler +@ } +@ +__tx_thread_idle_system_restore: +@ +@ /* Just return back to the scheduler! */ +@ + MOV r0, #SVC_MODE @ Build SVC mode CPSR + MSR CPSR, r0 @ Enter SVC mode + B _tx_thread_schedule @ Return to scheduler +@} + + + diff --git a/ports/arm11/gnu/src/tx_thread_context_save.S b/ports/arm11/gnu/src/tx_thread_context_save.S new file mode 100644 index 000000000..8a072cf51 --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_context_save.S @@ -0,0 +1,210 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@#include "tx_timer.h" +@ +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled +#else +DISABLE_INTS = 0x80 @ IRQ interrupts disabled +#endif +@ + .global _tx_thread_system_state + .global _tx_thread_current_ptr + .global _tx_irq_processing_return + .global _tx_execution_isr_enter +@ +@ +@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_save +@ since it will never be called 16-bit mode. */ +@ + .arm + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_context_save ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function saves the context of an executing thread in the */ +@/* beginning of interrupt processing. The function also ensures that */ +@/* the system stack is used upon return to the calling ISR. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* ISRs */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_context_save(VOID) +@{ + .global _tx_thread_context_save + .type _tx_thread_context_save,function +_tx_thread_context_save: +@ +@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +@ out, we are in IRQ mode, and all registers are intact. */ +@ +@ /* Check for a nested interrupt condition. */ +@ if (_tx_thread_system_state++) +@ { +@ + STMDB sp!, {r0-r3} @ Save some working registers +#ifdef TX_ENABLE_FIQ_SUPPORT + MRS r0, CPSR @ Pickup the CPSR + ORR r0, r0, #DISABLE_INTS @ Build disable interrupt CPSR + MSR CPSR_cxsf, r0 @ Disable interrupts +#endif + LDR r3, =_tx_thread_system_state @ Pickup address of system state variable + LDR r2, [r3] @ Pickup system state + CMP r2, #0 @ Is this the first interrupt? + BEQ __tx_thread_not_nested_save @ Yes, not a nested context save +@ +@ /* Nested interrupt condition. */ +@ + ADD r2, r2, #1 @ Increment the interrupt counter + STR r2, [r3] @ Store it back in the variable +@ +@ /* Save the rest of the scratch registers on the stack and return to the +@ calling ISR. */ +@ + MRS r0, SPSR @ Pickup saved SPSR + SUB lr, lr, #4 @ Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} @ Store other registers +@ +@ /* Return to the ISR. */ +@ + MOV r10, #0 @ Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR enter function to indicate an ISR is executing. */ +@ + PUSH {lr} @ Save ISR lr + BL _tx_execution_isr_enter @ Call the ISR enter function + POP {lr} @ Recover ISR lr +#endif + + B __tx_irq_processing_return @ Continue IRQ processing +@ +__tx_thread_not_nested_save: +@ } +@ +@ /* Otherwise, not nested, check to see if a thread was running. */ +@ else if (_tx_thread_current_ptr) +@ { +@ + ADD r2, r2, #1 @ Increment the interrupt counter + STR r2, [r3] @ Store it back in the variable + LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr + LDR r0, [r1] @ Pickup current thread pointer + CMP r0, #0 @ Is it NULL? + BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in + @ scheduling loop - nothing needs saving! +@ +@ /* Save minimal context of interrupted thread. */ +@ + MRS r2, SPSR @ Pickup saved SPSR + SUB lr, lr, #4 @ Adjust point of interrupt + STMDB sp!, {r2, r10, r12, lr} @ Store other registers +@ +@ /* Save the current stack pointer in the thread's control block. */ +@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +@ +@ /* Switch to the system stack. */ +@ sp = _tx_thread_system_stack_ptr@ +@ + MOV r10, #0 @ Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR enter function to indicate an ISR is executing. */ +@ + PUSH {lr} @ Save ISR lr + BL _tx_execution_isr_enter @ Call the ISR enter function + POP {lr} @ Recover ISR lr +#endif + + B __tx_irq_processing_return @ Continue IRQ processing +@ +@ } +@ else +@ { +@ +__tx_thread_idle_system_save: +@ +@ /* Interrupt occurred in the scheduling loop. */ +@ +@ /* Not much to do here, just adjust the stack pointer, and return to IRQ +@ processing. */ +@ + MOV r10, #0 @ Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR enter function to indicate an ISR is executing. */ +@ + PUSH {lr} @ Save ISR lr + BL _tx_execution_isr_enter @ Call the ISR enter function + POP {lr} @ Recover ISR lr +#endif + + ADD sp, sp, #16 @ Recover saved registers + B __tx_irq_processing_return @ Continue IRQ processing +@ +@ } +@} + + + diff --git a/ports/arm11/gnu/src/tx_thread_fiq_context_restore.S b/ports/arm11/gnu/src/tx_thread_fiq_context_restore.S new file mode 100644 index 000000000..44acd526b --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_fiq_context_restore.S @@ -0,0 +1,256 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@#include "tx_timer.h" +@ +@ +SVC_MODE = 0xD3 @ SVC mode +FIQ_MODE = 0xD1 @ FIQ mode +DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts +MODE_MASK = 0x1F @ Mode mask +THUMB_MASK = 0x20 @ Thumb bit mask +IRQ_MODE_BITS = 0x12 @ IRQ mode bits +SVC_MODE_BITS = 0x13 @ SVC mode value +@ +@ + .global _tx_thread_system_state + .global _tx_thread_current_ptr + .global _tx_thread_system_stack_ptr + .global _tx_thread_execute_ptr + .global _tx_timer_time_slice + .global _tx_thread_schedule + .global _tx_thread_preempt_disable + .global _tx_execution_isr_exit +@ +@ +@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_restore +@ since it will never be called 16-bit mode. */ +@ + .arm + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_fiq_context_restore ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function restores the fiq interrupt context when processing a */ +@/* nested interrupt. If not, it returns to the interrupt thread if no */ +@/* preemption is necessary. Otherwise, if preemption is necessary or */ +@/* if no thread was running, the function returns to the scheduler. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* _tx_thread_schedule Thread scheduling routine */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* FIQ ISR Interrupt Service Routines */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_fiq_context_restore(VOID) +@{ + .global _tx_thread_fiq_context_restore + .type _tx_thread_fiq_context_restore,function +_tx_thread_fiq_context_restore: +@ +@ /* Lockout interrupts. */ +@ + MRS r3, CPSR @ Pickup current CPSR + ORR r0, r3, #DISABLE_INTS @ Build interrupt disable value + MSR CPSR_cxsf, r0 @ Lockout interrupts + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR exit function to indicate an ISR is complete. */ +@ + BL _tx_execution_isr_exit @ Call the ISR exit function +#endif +@ +@ /* Determine if interrupts are nested. */ +@ if (--_tx_thread_system_state) +@ { +@ + LDR r3, =_tx_thread_system_state @ Pickup address of system state variable + LDR r2, [r3] @ Pickup system state + SUB r2, r2, #1 @ Decrement the counter + STR r2, [r3] @ Store the counter + CMP r2, #0 @ Was this the first interrupt? + BEQ __tx_thread_fiq_not_nested_restore @ If so, not a nested restore +@ +@ /* Interrupts are nested. */ +@ +@ /* Just recover the saved registers and return to the point of +@ interrupt. */ +@ + LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 @ Put SPSR back + LDMIA sp!, {r0-r3} @ Recover r0-r3 + MOVS pc, lr @ Return to point of interrupt +@ +@ } +__tx_thread_fiq_not_nested_restore: +@ +@ /* Determine if a thread was interrupted and no preemption is required. */ +@ else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +@ || (_tx_thread_preempt_disable)) +@ { +@ + LDR r1, [sp] @ Pickup the saved SPSR + MOV r2, #MODE_MASK @ Build mask to isolate the interrupted mode + AND r1, r1, r2 @ Isolate mode bits + CMP r1, #IRQ_MODE_BITS @ Was an interrupt taken in IRQ mode before we + @ got to context save? */ + BEQ __tx_thread_fiq_no_preempt_restore @ Yes, just go back to point of interrupt + + + LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr + LDR r0, [r1] @ Pickup actual current thread pointer + CMP r0, #0 @ Is it NULL? + BEQ __tx_thread_fiq_idle_system_restore @ Yes, idle system was interrupted + + LDR r3, =_tx_thread_preempt_disable @ Pickup preempt disable address + LDR r2, [r3] @ Pickup actual preempt disable flag + CMP r2, #0 @ Is it set? + BNE __tx_thread_fiq_no_preempt_restore @ Yes, don't preempt this thread + LDR r3, =_tx_thread_execute_ptr @ Pickup address of execute thread ptr + LDR r2, [r3] @ Pickup actual execute thread pointer + CMP r0, r2 @ Is the same thread highest priority? + BNE __tx_thread_fiq_preempt_restore @ No, preemption needs to happen + + +__tx_thread_fiq_no_preempt_restore: +@ +@ /* Restore interrupted thread or ISR. */ +@ +@ /* Pickup the saved stack pointer. */ +@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; +@ +@ /* Recover the saved context and return to the point of interrupt. */ +@ + LDMIA sp!, {r0, lr} @ Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 @ Put SPSR back + LDMIA sp!, {r0-r3} @ Recover r0-r3 + MOVS pc, lr @ Return to point of interrupt +@ +@ } +@ else +@ { +__tx_thread_fiq_preempt_restore: +@ + LDMIA sp!, {r3, lr} @ Recover temporarily saved registers + MOV r1, lr @ Save lr (point of interrupt) + MOV r2, #SVC_MODE @ Build SVC mode CPSR + MSR CPSR_cxsf, r2 @ Enter SVC mode + STR r1, [sp, #-4]! @ Save point of interrupt + STMDB sp!, {r4-r12, lr} @ Save upper half of registers + MOV r4, r3 @ Save SPSR in r4 + MOV r2, #FIQ_MODE @ Build FIQ mode CPSR + MSR CPSR_cxsf, r2 @ Reenter FIQ mode + LDMIA sp!, {r0-r3} @ Recover r0-r3 + MOV r5, #SVC_MODE @ Build SVC mode CPSR + MSR CPSR_cxsf, r5 @ Enter SVC mode + STMDB sp!, {r0-r3} @ Save r0-r3 on thread's stack + MOV r3, #1 @ Build interrupt stack type + STMDB sp!, {r3, r4} @ Save interrupt stack type and SPSR + LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr + LDR r0, [r1] @ Pickup current thread pointer + STR sp, [r0, #8] @ Save stack pointer in thread control + @ block */ + BIC r4, r4, #THUMB_MASK @ Clear the Thumb bit of CPSR + ORR r3, r4, #DISABLE_INTS @ Or-in interrupt lockout bit(s) + MSR CPSR_cxsf, r3 @ Lockout interrupts +@ +@ /* Save the remaining time-slice and disable it. */ +@ if (_tx_timer_time_slice) +@ { +@ + LDR r3, =_tx_timer_time_slice @ Pickup time-slice variable address + LDR r2, [r3] @ Pickup time-slice + CMP r2, #0 @ Is it active? + BEQ __tx_thread_fiq_dont_save_ts @ No, don't save it +@ +@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +@ _tx_timer_time_slice = 0; +@ + STR r2, [r0, #24] @ Save thread's time-slice + MOV r2, #0 @ Clear value + STR r2, [r3] @ Disable global time-slice flag +@ +@ } +__tx_thread_fiq_dont_save_ts: +@ +@ +@ /* Clear the current task pointer. */ +@ _tx_thread_current_ptr = TX_NULL; +@ + MOV r0, #0 @ NULL value + STR r0, [r1] @ Clear current thread pointer +@ +@ /* Return to the scheduler. */ +@ _tx_thread_schedule(); +@ + B _tx_thread_schedule @ Return to scheduler +@ } +@ +__tx_thread_fiq_idle_system_restore: +@ +@ /* Just return back to the scheduler! */ +@ + ADD sp, sp, #24 @ Recover FIQ stack space + MRS r3, CPSR @ Pickup current CPSR + BIC r3, r3, #MODE_MASK @ Clear the mode portion of the CPSR + ORR r3, r3, #SVC_MODE_BITS @ Or-in new interrupt lockout bit + MSR CPSR_cxsf, r3 @ Lockout interrupts + B _tx_thread_schedule @ Return to scheduler +@ +@} + diff --git a/ports/arm11/gnu/src/tx_thread_fiq_context_save.S b/ports/arm11/gnu/src/tx_thread_fiq_context_save.S new file mode 100644 index 000000000..53b12f9bb --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_fiq_context_save.S @@ -0,0 +1,204 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@ +@ + .global _tx_thread_system_state + .global _tx_thread_current_ptr + .global __tx_fiq_processing_return + .global _tx_execution_isr_enter +@ +@ +@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_save +@ since it will never be called 16-bit mode. */ +@ + .arm + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_fiq_context_save ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function saves the context of an executing thread in the */ +@/* beginning of interrupt processing. The function also ensures that */ +@/* the system stack is used upon return to the calling ISR. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* ISRs */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@ VOID _tx_thread_fiq_context_save(VOID) +@{ + .global _tx_thread_fiq_context_save + .type _tx_thread_fiq_context_save,function +_tx_thread_fiq_context_save: +@ +@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +@ out, we are in IRQ mode, and all registers are intact. */ +@ +@ /* Check for a nested interrupt condition. */ +@ if (_tx_thread_system_state++) +@ { +@ + STMDB sp!, {r0-r3} @ Save some working registers + LDR r3, =_tx_thread_system_state @ Pickup address of system state variable + LDR r2, [r3] @ Pickup system state + CMP r2, #0 @ Is this the first interrupt? + BEQ __tx_thread_fiq_not_nested_save @ Yes, not a nested context save +@ +@ /* Nested interrupt condition. */ +@ + ADD r2, r2, #1 @ Increment the interrupt counter + STR r2, [r3] @ Store it back in the variable +@ +@ /* Save the rest of the scratch registers on the stack and return to the +@ calling ISR. */ +@ + MRS r0, SPSR @ Pickup saved SPSR + SUB lr, lr, #4 @ Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} @ Store other registers +@ +@ /* Return to the ISR. */ +@ + MOV r10, #0 @ Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR enter function to indicate an ISR is executing. */ +@ + PUSH {lr} @ Save ISR lr + BL _tx_execution_isr_enter @ Call the ISR enter function + POP {lr} @ Recover ISR lr +#endif + + B __tx_fiq_processing_return @ Continue FIQ processing +@ +__tx_thread_fiq_not_nested_save: +@ } +@ +@ /* Otherwise, not nested, check to see if a thread was running. */ +@ else if (_tx_thread_current_ptr) +@ { +@ + ADD r2, r2, #1 @ Increment the interrupt counter + STR r2, [r3] @ Store it back in the variable + LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr + LDR r0, [r1] @ Pickup current thread pointer + CMP r0, #0 @ Is it NULL? + BEQ __tx_thread_fiq_idle_system_save @ If so, interrupt occurred in +@ @ scheduling loop - nothing needs saving! +@ +@ /* Save minimal context of interrupted thread. */ +@ + MRS r2, SPSR @ Pickup saved SPSR + SUB lr, lr, #4 @ Adjust point of interrupt + STMDB sp!, {r2, lr} @ Store other registers, Note that we don't +@ @ need to save sl and ip since FIQ has +@ @ copies of these registers. Nested +@ @ interrupt processing does need to save +@ @ these registers. +@ +@ /* Save the current stack pointer in the thread's control block. */ +@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +@ +@ /* Switch to the system stack. */ +@ sp = _tx_thread_system_stack_ptr; +@ + MOV r10, #0 @ Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR enter function to indicate an ISR is executing. */ +@ + PUSH {lr} @ Save ISR lr + BL _tx_execution_isr_enter @ Call the ISR enter function + POP {lr} @ Recover ISR lr +#endif + + B __tx_fiq_processing_return @ Continue FIQ processing +@ +@ } +@ else +@ { +@ +__tx_thread_fiq_idle_system_save: +@ +@ /* Interrupt occurred in the scheduling loop. */ +@ +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR enter function to indicate an ISR is executing. */ +@ + PUSH {lr} @ Save ISR lr + BL _tx_execution_isr_enter @ Call the ISR enter function + POP {lr} @ Recover ISR lr +#endif +@ +@ /* Not much to do here, save the current SPSR and LR for possible +@ use in IRQ interrupted in idle system conditions, and return to +@ FIQ interrupt processing. */ +@ + MRS r0, SPSR @ Pickup saved SPSR + SUB lr, lr, #4 @ Adjust point of interrupt + STMDB sp!, {r0, lr} @ Store other registers that will get used +@ @ or stripped off the stack in context +@ @ restore + B __tx_fiq_processing_return @ Continue FIQ processing +@ +@ } +@} + diff --git a/ports/arm11/gnu/src/tx_thread_fiq_nesting_end.S b/ports/arm11/gnu/src/tx_thread_fiq_nesting_end.S new file mode 100644 index 000000000..cc0d49916 --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_fiq_nesting_end.S @@ -0,0 +1,111 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@ +@ +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts +#else +DISABLE_INTS = 0x80 @ Disable IRQ interrupts +#endif +MODE_MASK = 0x1F @ Mode mask +FIQ_MODE_BITS = 0x11 @ FIQ mode bits +@ +@ +@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_end +@ since it will never be called 16-bit mode. */ +@ + .arm + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_fiq_nesting_end ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is called by the application from FIQ mode after */ +@/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */ +@/* processing from system mode back to FIQ mode prior to the ISR */ +@/* calling _tx_thread_fiq_context_restore. Note that this function */ +@/* assumes the system stack pointer is in the same position after */ +@/* nesting start function was called. */ +@/* */ +@/* This function assumes that the system mode stack pointer was setup */ +@/* during low-level initialization (tx_initialize_low_level.s). */ +@/* */ +@/* This function returns with FIQ interrupts disabled. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* ISRs */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_fiq_nesting_end(VOID) +@{ + .global _tx_thread_fiq_nesting_end + .type _tx_thread_fiq_nesting_end,function +_tx_thread_fiq_nesting_end: + MOV r3,lr @ Save ISR return address + MRS r0, CPSR @ Pickup the CPSR + ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value + MSR CPSR_cxsf, r0 @ Disable interrupts + LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for + @ 8-byte alignment logic) + BIC r0, r0, #MODE_MASK @ Clear mode bits + ORR r0, r0, #FIQ_MODE_BITS @ Build IRQ mode CPSR + MSR CPSR_cxsf, r0 @ Reenter IRQ mode + MOV pc, r3 @ Return to caller +@} + diff --git a/ports/arm11/gnu/src/tx_thread_fiq_nesting_start.S b/ports/arm11/gnu/src/tx_thread_fiq_nesting_start.S new file mode 100644 index 000000000..b9dda19e8 --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_fiq_nesting_start.S @@ -0,0 +1,104 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@ +@ +FIQ_DISABLE = 0x40 @ FIQ disable bit +MODE_MASK = 0x1F @ Mode mask +SYS_MODE_BITS = 0x1F @ System mode bits +@ +@ +@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_start +@ since it will never be called 16-bit mode. */ +@ + .arm + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_fiq_nesting_start ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is called by the application from FIQ mode after */ +@/* _tx_thread_fiq_context_save has been called and switches the FIQ */ +@/* processing to the system mode so nested FIQ interrupt processing */ +@/* is possible (system mode has its own "lr" register). Note that */ +@/* this function assumes that the system mode stack pointer was setup */ +@/* during low-level initialization (tx_initialize_low_level.s). */ +@/* */ +@/* This function returns with FIQ interrupts enabled. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* ISRs */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_fiq_nesting_start(VOID) +@{ + .global _tx_thread_fiq_nesting_start + .type _tx_thread_fiq_nesting_start,function +_tx_thread_fiq_nesting_start: + MOV r3,lr @ Save ISR return address + MRS r0, CPSR @ Pickup the CPSR + BIC r0, r0, #MODE_MASK @ Clear the mode bits + ORR r0, r0, #SYS_MODE_BITS @ Build system mode CPSR + MSR CPSR_cxsf, r0 @ Enter system mode + STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack + @ and push r1 just to keep 8-byte alignment + BIC r0, r0, #FIQ_DISABLE @ Build enable FIQ CPSR + MSR CPSR_cxsf, r0 @ Enter system mode + MOV pc, r3 @ Return to caller +@} + diff --git a/ports/arm11/gnu/src/tx_thread_interrupt_control.S b/ports/arm11/gnu/src/tx_thread_interrupt_control.S new file mode 100644 index 000000000..4cf397c98 --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_interrupt_control.S @@ -0,0 +1,115 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" */ +@ + +INT_MASK = 0x03F + +@ +@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_control for +@ applications calling this function from to 16-bit Thumb mode. */ +@ + .text + .align 2 + .global $_tx_thread_interrupt_control +$_tx_thread_interrupt_control: + .thumb + BX pc @ Switch to 32-bit mode + NOP @ + .arm + STMFD sp!, {lr} @ Save return address + BL _tx_thread_interrupt_control @ Call _tx_thread_interrupt_control function + LDMFD sp!, {lr} @ Recover saved return address + BX lr @ Return to 16-bit caller +@ +@ + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_interrupt_control ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is responsible for changing the interrupt lockout */ +@/* posture of the system. */ +@/* */ +@/* INPUT */ +@/* */ +@/* new_posture New interrupt lockout posture */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* old_posture Old interrupt lockout posture */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* Application Code */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@UINT _tx_thread_interrupt_control(UINT new_posture) +@{ + .global _tx_thread_interrupt_control + .type _tx_thread_interrupt_control,function +_tx_thread_interrupt_control: +@ +@ /* Pickup current interrupt lockout posture. */ +@ + MRS r3, CPSR @ Pickup current CPSR + MOV r2, #INT_MASK @ Build interrupt mask + AND r1, r3, r2 @ Clear interrupt lockout bits + ORR r1, r1, r0 @ Or-in new interrupt lockout bits +@ +@ /* Apply the new interrupt posture. */ +@ + MSR CPSR, r1 @ Setup new CPSR + BIC r0, r3, r2 @ Return previous interrupt mask +#ifdef __THUMB_INTERWORK + BX lr @ Return to caller +#else + MOV pc, lr @ Return to caller +#endif +@} + diff --git a/ports/arm11/gnu/src/tx_thread_interrupt_disable.S b/ports/arm11/gnu/src/tx_thread_interrupt_disable.S new file mode 100644 index 000000000..9d460e24b --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_interrupt_disable.S @@ -0,0 +1,116 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@ +@ +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled +#else +DISABLE_INTS = 0x80 @ IRQ interrupts disabled +#endif +@ +@ +@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_disable for +@ applications calling this function from to 16-bit Thumb mode. */ +@ + .text + .align 2 + .global $_tx_thread_interrupt_disable +$_tx_thread_interrupt_disable: + .thumb + BX pc @ Switch to 32-bit mode + NOP @ + .arm + STMFD sp!, {lr} @ Save return address + BL _tx_thread_interrupt_disable @ Call _tx_thread_interrupt_disable function + LDMFD sp!, {lr} @ Recover saved return address + BX lr @ Return to 16-bit caller +@ +@ + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_interrupt_disable ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is responsible for disabling interrupts */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* old_posture Old interrupt lockout posture */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* Application Code */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@UINT _tx_thread_interrupt_disable(void) +@{ + .global _tx_thread_interrupt_disable + .type _tx_thread_interrupt_disable,function +_tx_thread_interrupt_disable: +@ +@ /* Pickup current interrupt lockout posture. */ +@ + MRS r0, CPSR @ Pickup current CPSR +@ +@ /* Mask interrupts. */ +@ + ORR r1, r0, #DISABLE_INTS @ Mask interrupts + MSR CPSR_cxsf, r1 @ Setup new CPSR +#ifdef __THUMB_INTERWORK + BX lr @ Return to caller +#else + MOV pc, lr @ Return to caller +#endif +@} + + diff --git a/ports/arm11/gnu/src/tx_thread_interrupt_restore.S b/ports/arm11/gnu/src/tx_thread_interrupt_restore.S new file mode 100644 index 000000000..0a06d5ea0 --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_interrupt_restore.S @@ -0,0 +1,104 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@ +@ +@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_restore for +@ applications calling this function from to 16-bit Thumb mode. */ +@ + .text + .align 2 + .global $_tx_thread_interrupt_restore +$_tx_thread_interrupt_restore: + .thumb + BX pc @ Switch to 32-bit mode + NOP @ + .arm + STMFD sp!, {lr} @ Save return address + BL _tx_thread_interrupt_restore @ Call _tx_thread_interrupt_restore function + LDMFD sp!, {lr} @ Recover saved return address + BX lr @ Return to 16-bit caller +@ +@ + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_interrupt_restore ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is responsible for restoring interrupts to the state */ +@/* returned by a previous _tx_thread_interrupt_disable call. */ +@/* */ +@/* INPUT */ +@/* */ +@/* old_posture Old interrupt lockout posture */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* Application Code */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@UINT _tx_thread_interrupt_restore(UINT old_posture) +@{ + .global _tx_thread_interrupt_restore + .type _tx_thread_interrupt_restore,function +_tx_thread_interrupt_restore: +@ +@ /* Apply the new interrupt posture. */ +@ + MSR CPSR_cxsf, r0 @ Setup new CPSR +#ifdef __THUMB_INTERWORK + BX lr @ Return to caller +#else + MOV pc, lr @ Return to caller +#endif +@} + diff --git a/ports/arm11/gnu/src/tx_thread_irq_nesting_end.S b/ports/arm11/gnu/src/tx_thread_irq_nesting_end.S new file mode 100644 index 000000000..3fda4dae1 --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_irq_nesting_end.S @@ -0,0 +1,111 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@ +@ +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts +#else +DISABLE_INTS = 0x80 @ Disable IRQ interrupts +#endif +MODE_MASK = 0x1F @ Mode mask +IRQ_MODE_BITS = 0x12 @ IRQ mode bits +@ +@ +@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_end +@ since it will never be called 16-bit mode. */ +@ + .arm + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_irq_nesting_end ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is called by the application from IRQ mode after */ +@/* _tx_thread_irq_nesting_start has been called and switches the IRQ */ +@/* processing from system mode back to IRQ mode prior to the ISR */ +@/* calling _tx_thread_context_restore. Note that this function */ +@/* assumes the system stack pointer is in the same position after */ +@/* nesting start function was called. */ +@/* */ +@/* This function assumes that the system mode stack pointer was setup */ +@/* during low-level initialization (tx_initialize_low_level.s). */ +@/* */ +@/* This function returns with IRQ interrupts disabled. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* ISRs */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_irq_nesting_end(VOID) +@{ + .global _tx_thread_irq_nesting_end + .type _tx_thread_irq_nesting_end,function +_tx_thread_irq_nesting_end: + MOV r3,lr @ Save ISR return address + MRS r0, CPSR @ Pickup the CPSR + ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value + MSR CPSR_cxsf, r0 @ Disable interrupts + LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for + @ 8-byte alignment logic) + BIC r0, r0, #MODE_MASK @ Clear mode bits + ORR r0, r0, #IRQ_MODE_BITS @ Build IRQ mode CPSR + MSR CPSR_cxsf, r0 @ Reenter IRQ mode + MOV pc, r3 @ Return to caller +@} + diff --git a/ports/arm11/gnu/src/tx_thread_irq_nesting_start.S b/ports/arm11/gnu/src/tx_thread_irq_nesting_start.S new file mode 100644 index 000000000..f8e4a134d --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_irq_nesting_start.S @@ -0,0 +1,104 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@ +@ +IRQ_DISABLE = 0x80 @ IRQ disable bit +MODE_MASK = 0x1F @ Mode mask +SYS_MODE_BITS = 0x1F @ System mode bits +@ +@ +@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_start +@ since it will never be called 16-bit mode. */ +@ + .arm + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_irq_nesting_start ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is called by the application from IRQ mode after */ +@/* _tx_thread_context_save has been called and switches the IRQ */ +@/* processing to the system mode so nested IRQ interrupt processing */ +@/* is possible (system mode has its own "lr" register). Note that */ +@/* this function assumes that the system mode stack pointer was setup */ +@/* during low-level initialization (tx_initialize_low_level.s). */ +@/* */ +@/* This function returns with IRQ interrupts enabled. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* ISRs */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_irq_nesting_start(VOID) +@{ + .global _tx_thread_irq_nesting_start + .type _tx_thread_irq_nesting_start,function +_tx_thread_irq_nesting_start: + MOV r3,lr @ Save ISR return address + MRS r0, CPSR @ Pickup the CPSR + BIC r0, r0, #MODE_MASK @ Clear the mode bits + ORR r0, r0, #SYS_MODE_BITS @ Build system mode CPSR + MSR CPSR_cxsf, r0 @ Enter system mode + STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack + @ and push r1 just to keep 8-byte alignment + BIC r0, r0, #IRQ_DISABLE @ Build enable IRQ CPSR + MSR CPSR_cxsf, r0 @ Enter system mode + MOV pc, r3 @ Return to caller +@} + diff --git a/ports/arm11/gnu/src/tx_thread_schedule.S b/ports/arm11/gnu/src/tx_thread_schedule.S new file mode 100644 index 000000000..09692e98a --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_schedule.S @@ -0,0 +1,187 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@#include "tx_timer.h" +@ +#ifdef TX_ENABLE_FIQ_SUPPORT +ENABLE_INTS = 0xC0 @ IRQ & FIQ Interrupts enabled mask +#else +ENABLE_INTS = 0x80 @ IRQ Interrupts enabled mask +#endif +@ +@ + .global _tx_thread_execute_ptr + .global _tx_thread_current_ptr + .global _tx_timer_time_slice + .global _tx_execution_thread_enter +@ +@ +@/* Define the 16-bit Thumb mode veneer for _tx_thread_schedule for +@ applications calling this function from to 16-bit Thumb mode. */ +@ + .text + .align 2 + .global $_tx_thread_schedule + .type $_tx_thread_schedule,function +$_tx_thread_schedule: + .thumb + BX pc @ Switch to 32-bit mode + NOP @ + .arm + STMFD sp!, {lr} @ Save return address + BL _tx_thread_schedule @ Call _tx_thread_schedule function + LDMFD sp!, {lr} @ Recover saved return address + BX lr @ Return to 16-bit caller +@ +@ + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_schedule ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function waits for a thread control block pointer to appear in */ +@/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */ +@/* in the variable, the corresponding thread is resumed. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* _tx_initialize_kernel_enter ThreadX entry function */ +@/* _tx_thread_system_return Return to system from thread */ +@/* _tx_thread_context_restore Restore thread's context */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_schedule(VOID) +@{ + .global _tx_thread_schedule + .type _tx_thread_schedule,function +_tx_thread_schedule: +@ +@ /* Enable interrupts. */ +@ + MRS r2, CPSR @ Pickup CPSR + BIC r0, r2, #ENABLE_INTS @ Clear the disable bit(s) + MSR CPSR_cxsf, r0 @ Enable interrupts +@ +@ /* Wait for a thread to execute. */ +@ do +@ { + LDR r1, =_tx_thread_execute_ptr @ Address of thread execute ptr +@ +__tx_thread_schedule_loop: +@ + LDR r0, [r1] @ Pickup next thread to execute + CMP r0, #0 @ Is it NULL? + BEQ __tx_thread_schedule_loop @ If so, keep looking for a thread +@ +@ } +@ while(_tx_thread_execute_ptr == TX_NULL); +@ +@ /* Yes! We have a thread to execute. Lockout interrupts and +@ transfer control to it. */ +@ + MSR CPSR_cxsf, r2 @ Disable interrupts +@ +@ /* Setup the current thread pointer. */ +@ _tx_thread_current_ptr = _tx_thread_execute_ptr; +@ + LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread + STR r0, [r1] @ Setup current thread pointer +@ +@ /* Increment the run count for this thread. */ +@ _tx_thread_current_ptr -> tx_thread_run_count++; +@ + LDR r2, [r0, #4] @ Pickup run counter + LDR r3, [r0, #24] @ Pickup time-slice for this thread + ADD r2, r2, #1 @ Increment thread run-counter + STR r2, [r0, #4] @ Store the new run counter +@ +@ /* Setup time-slice, if present. */ +@ _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; +@ + LDR r2, =_tx_timer_time_slice @ Pickup address of time-slice + @ variable + LDR sp, [r0, #8] @ Switch stack pointers + STR r3, [r2] @ Setup time-slice +@ +@ /* Switch to the thread's stack. */ +@ sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr; +@ +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the thread entry function to indicate the thread is executing. */ +@ + BL _tx_execution_thread_enter @ Call the thread execution enter function +#endif +@ +@ /* Determine if an interrupt frame or a synchronous task suspension frame +@ is present. */ +@ + LDMIA sp!, {r0, r1} @ Pickup the stack type and saved CPSR + CMP r0, #0 @ Check for synchronous context switch + MSRNE SPSR_cxsf, r1 @ Setup SPSR for return + LDMNEIA sp!, {r0-r12, lr, pc}^ @ Return to point of thread interrupt + LDMIA sp!, {r4-r11, lr} @ Return to thread synchronously + MSR CPSR_cxsf, r1 @ Recover CPSR +#ifdef __THUMB_INTERWORK + BX lr @ Return to caller +#else + MOV pc, lr @ Return to caller +#endif +@ +@} +@ + diff --git a/ports/arm11/gnu/src/tx_thread_stack_build.S b/ports/arm11/gnu/src/tx_thread_stack_build.S new file mode 100644 index 000000000..ea34e6c2a --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_stack_build.S @@ -0,0 +1,178 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@ + .arm + +SVC_MODE = 0x13 @ SVC mode +#ifdef TX_ENABLE_FIQ_SUPPORT +CPSR_MASK = 0xDF @ Mask initial CPSR, IRQ & FIQ interrupts enabled +#else +CPSR_MASK = 0x9F @ Mask initial CPSR, IRQ interrupts enabled +#endif +@ +@ +@/* Define the 16-bit Thumb mode veneer for _tx_thread_stack_build for +@ applications calling this function from to 16-bit Thumb mode. */ +@ + .text + .align 2 + .thumb + .global $_tx_thread_stack_build + .type $_tx_thread_stack_build,function +$_tx_thread_stack_build: + BX pc @ Switch to 32-bit mode + NOP @ + .arm + STMFD sp!, {lr} @ Save return address + BL _tx_thread_stack_build @ Call _tx_thread_stack_build function + LDMFD sp!, {lr} @ Recover saved return address + BX lr @ Return to 16-bit caller +@ +@ + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_stack_build ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function builds a stack frame on the supplied thread's stack. */ +@/* The stack frame results in a fake interrupt return to the supplied */ +@/* function pointer. */ +@/* */ +@/* INPUT */ +@/* */ +@/* thread_ptr Pointer to thread control blk */ +@/* function_ptr Pointer to return function */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* _tx_thread_create Create thread service */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +@{ + .global _tx_thread_stack_build + .type _tx_thread_stack_build,function +_tx_thread_stack_build: +@ +@ +@ /* Build a fake interrupt frame. The form of the fake interrupt stack +@ on theARM11 should look like the following after it is built: +@ +@ Stack Top: 1 Interrupt stack frame type +@ CPSR Initial value for CPSR +@ a1 (r0) Initial value for a1 +@ a2 (r1) Initial value for a2 +@ a3 (r2) Initial value for a3 +@ a4 (r3) Initial value for a4 +@ v1 (r4) Initial value for v1 +@ v2 (r5) Initial value for v2 +@ v3 (r6) Initial value for v3 +@ v4 (r7) Initial value for v4 +@ v5 (r8) Initial value for v5 +@ sb (r9) Initial value for sb +@ sl (r10) Initial value for sl +@ fp (r11) Initial value for fp +@ ip (r12) Initial value for ip +@ lr (r14) Initial value for lr +@ pc (r15) Initial value for pc +@ 0 For stack backtracing +@ +@ Stack Bottom: (higher memory address) */ +@ + LDR r2, [r0, #16] @ Pickup end of stack area + BIC r2, r2, #7 @ Ensure 8-byte alignment + SUB r2, r2, #76 @ Allocate space for the stack frame +@ +@ /* Actually build the stack frame. */ +@ + MOV r3, #1 @ Build interrupt stack type + STR r3, [r2, #0] @ Store stack type + MOV r3, #0 @ Build initial register value + STR r3, [r2, #8] @ Store initial r0 + STR r3, [r2, #12] @ Store initial r1 + STR r3, [r2, #16] @ Store initial r2 + STR r3, [r2, #20] @ Store initial r3 + STR r3, [r2, #24] @ Store initial r4 + STR r3, [r2, #28] @ Store initial r5 + STR r3, [r2, #32] @ Store initial r6 + STR r3, [r2, #36] @ Store initial r7 + STR r3, [r2, #40] @ Store initial r8 + STR r3, [r2, #44] @ Store initial r9 + LDR r3, [r0, #12] @ Pickup stack starting address + STR r3, [r2, #48] @ Store initial r10 (sl) + LDR r3,=_tx_thread_schedule @ Pickup address of _tx_thread_schedule for GDB backtrace + STR r3, [r2, #60] @ Store initial r14 (lr) + MOV r3, #0 @ Build initial register value + STR r3, [r2, #52] @ Store initial r11 + STR r3, [r2, #56] @ Store initial r12 + STR r1, [r2, #64] @ Store initial pc + STR r3, [r2, #68] @ 0 for back-trace + MRS r1, CPSR @ Pickup CPSR + BIC r1, r1, #CPSR_MASK @ Mask mode bits of CPSR + ORR r3, r1, #SVC_MODE @ Build CPSR, SVC mode, interrupts enabled + STR r3, [r2, #4] @ Store initial CPSR +@ +@ /* Setup stack pointer. */ +@ thread_ptr -> tx_thread_stack_ptr = r2; +@ + STR r2, [r0, #8] @ Save stack pointer in thread's + @ control block +#ifdef __THUMB_INTERWORK + BX lr @ Return to caller +#else + MOV pc, lr @ Return to caller +#endif +@} + + diff --git a/ports/arm11/gnu/src/tx_thread_system_return.S b/ports/arm11/gnu/src/tx_thread_system_return.S new file mode 100644 index 000000000..87bef5aa6 --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_system_return.S @@ -0,0 +1,167 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@#include "tx_timer.h" +@ + .arm + +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled +#else +DISABLE_INTS = 0x80 @ IRQ interrupts disabled +#endif +@ +@ + .global _tx_thread_current_ptr + .global _tx_timer_time_slice + .global _tx_thread_schedule + .global _tx_execution_thread_exit +@ +@ +@ +@/* Define the 16-bit Thumb mode veneer for _tx_thread_system_return for +@ applications calling this function from to 16-bit Thumb mode. */ +@ + .text + .align 2 + .global $_tx_thread_system_return + .type $_tx_thread_system_return,function +$_tx_thread_system_return: + .thumb + BX pc @ Switch to 32-bit mode + NOP @ + .arm + STMFD sp!, {lr} @ Save return address + BL _tx_thread_system_return @ Call _tx_thread_system_return function + LDMFD sp!, {lr} @ Recover saved return address + BX lr @ Return to 16-bit caller +@ +@ + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_system_return ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function is target processor specific. It is used to transfer */ +@/* control from a thread back to the ThreadX system. Only a */ +@/* minimal context is saved since the compiler assumes temp registers */ +@/* are going to get slicked by a function call anyway. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* _tx_thread_schedule Thread scheduling loop */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* ThreadX components */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_system_return(VOID) +@{ + .global _tx_thread_system_return + .type _tx_thread_system_return,function +_tx_thread_system_return: +@ +@ /* Save minimal context on the stack. */ +@ + MOV r0, #0 @ Build a solicited stack type + MRS r1, CPSR @ Pickup the CPSR + STMDB sp!, {r0-r1, r4-r11, lr} @ Save minimal context +@ +@ /* Lockout interrupts. */ +@ + ORR r2, r1, #DISABLE_INTS @ Build disable interrupt CPSR + MSR CPSR_cxsf, r2 @ Disable interrupts + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the thread exit function to indicate the thread is no longer executing. */ +@ + BL _tx_execution_thread_exit @ Call the thread exit function +#endif + LDR r3, =_tx_thread_current_ptr @ Pickup address of current ptr + LDR r0, [r3] @ Pickup current thread pointer + LDR r2, =_tx_timer_time_slice @ Pickup address of time slice + LDR r1, [r2] @ Pickup current time slice +@ +@ /* Save current stack and switch to system stack. */ +@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +@ sp = _tx_thread_system_stack_ptr; +@ + STR sp, [r0, #8] @ Save thread stack pointer +@ +@ /* Determine if the time-slice is active. */ +@ if (_tx_timer_time_slice) +@ { +@ + MOV r4, #0 @ Build clear value + CMP r1, #0 @ Is a time-slice active? + BEQ __tx_thread_dont_save_ts @ No, don't save the time-slice +@ +@ /* Save time-slice for the thread and clear the current time-slice. */ +@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +@ _tx_timer_time_slice = 0; +@ + STR r4, [r2] @ Clear time-slice + STR r1, [r0, #24] @ Save current time-slice +@ +@ } +__tx_thread_dont_save_ts: +@ +@ /* Clear the current thread pointer. */ +@ _tx_thread_current_ptr = TX_NULL; +@ + STR r4, [r3] @ Clear current thread pointer + B _tx_thread_schedule @ Jump to scheduler! +@ +@} + diff --git a/ports/arm11/gnu/src/tx_thread_vectored_context_save.S b/ports/arm11/gnu/src/tx_thread_vectored_context_save.S new file mode 100644 index 000000000..3ac517acd --- /dev/null +++ b/ports/arm11/gnu/src/tx_thread_vectored_context_save.S @@ -0,0 +1,199 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Thread */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_thread.h" +@ +@ +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS = 0xC0 @ IRQ & FIQ interrupts disabled +#else +DISABLE_INTS = 0x80 @ IRQ interrupts disabled +#endif +@ +@ + .global _tx_thread_system_state + .global _tx_thread_current_ptr + .global _tx_execution_isr_enter +@ +@ +@ +@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save +@ since it will never be called 16-bit mode. */ +@ + .arm + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_thread_vectored_context_save ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function saves the context of an executing thread in the */ +@/* beginning of interrupt processing. The function also ensures that */ +@/* the system stack is used upon return to the calling ISR. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* None */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* ISRs */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_thread_vectored_context_save(VOID) +@{ + .global _tx_thread_vectored_context_save + .type _tx_thread_vectored_context_save,function +_tx_thread_vectored_context_save: +@ +@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +@ out, we are in IRQ mode, and all registers are intact. */ +@ +@ /* Check for a nested interrupt condition. */ +@ if (_tx_thread_system_state++) +@ { +@ +#ifdef TX_ENABLE_FIQ_SUPPORT + MRS r0, CPSR @ Pickup the CPSR + ORR r0, r0, #DISABLE_INTS @ Build disable interrupt CPSR + MSR CPSR_cxsf, r0 @ Disable interrupts +#endif + LDR r3, =_tx_thread_system_state @ Pickup address of system state variable + LDR r2, [r3, #0] @ Pickup system state + CMP r2, #0 @ Is this the first interrupt? + BEQ __tx_thread_not_nested_save @ Yes, not a nested context save +@ +@ /* Nested interrupt condition. */ +@ + ADD r2, r2, #1 @ Increment the interrupt counter + STR r2, [r3, #0] @ Store it back in the variable +@ +@ /* Note: Minimal context of interrupted thread is already saved. */ +@ +@ /* Return to the ISR. */ +@ + MOV r10, #0 @ Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR enter function to indicate an ISR is executing. */ +@ + PUSH {lr} @ Save ISR lr + BL _tx_execution_isr_enter @ Call the ISR enter function + POP {lr} @ Recover ISR lr +#endif + + MOV pc, lr @ Return to caller +@ +__tx_thread_not_nested_save: +@ } +@ +@ /* Otherwise, not nested, check to see if a thread was running. */ +@ else if (_tx_thread_current_ptr) +@ { +@ + ADD r2, r2, #1 @ Increment the interrupt counter + STR r2, [r3, #0] @ Store it back in the variable + LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr + LDR r0, [r1, #0] @ Pickup current thread pointer + CMP r0, #0 @ Is it NULL? + BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in + @ scheduling loop - nothing needs saving! +@ +@ /* Note: Minimal context of interrupted thread is already saved. */ +@ +@ /* Save the current stack pointer in the thread's control block. */ +@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +@ +@ /* Switch to the system stack. */ +@ sp = _tx_thread_system_stack_ptr; +@ + MOV r10, #0 @ Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR enter function to indicate an ISR is executing. */ +@ + PUSH {lr} @ Save ISR lr + BL _tx_execution_isr_enter @ Call the ISR enter function + POP {lr} @ Recover ISR lr +#endif + + MOV pc, lr @ Return to caller +@ +@ } +@ else +@ { +@ +__tx_thread_idle_system_save: +@ +@ /* Interrupt occurred in the scheduling loop. */ +@ +@ /* Not much to do here, just adjust the stack pointer, and return to IRQ +@ processing. */ +@ + MOV r10, #0 @ Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +@ +@ /* Call the ISR enter function to indicate an ISR is executing. */ +@ + PUSH {lr} @ Save ISR lr + BL _tx_execution_isr_enter @ Call the ISR enter function + POP {lr} @ Recover ISR lr +#endif + + ADD sp, sp, #32 @ Recover saved registers + MOV pc, lr @ Return to caller +@ +@ } +@} + diff --git a/ports/arm11/gnu/src/tx_timer_interrupt.S b/ports/arm11/gnu/src/tx_timer_interrupt.S new file mode 100644 index 000000000..60632a321 --- /dev/null +++ b/ports/arm11/gnu/src/tx_timer_interrupt.S @@ -0,0 +1,279 @@ +@/**************************************************************************/ +@/* */ +@/* Copyright (c) Microsoft Corporation. All rights reserved. */ +@/* */ +@/* This software is licensed under the Microsoft Software License */ +@/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +@/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +@/* and in the root directory of this software. */ +@/* */ +@/**************************************************************************/ +@ +@ +@/**************************************************************************/ +@/**************************************************************************/ +@/** */ +@/** ThreadX Component */ +@/** */ +@/** Timer */ +@/** */ +@/**************************************************************************/ +@/**************************************************************************/ +@ +@#define TX_SOURCE_CODE +@ +@ +@/* Include necessary system files. */ +@ +@#include "tx_api.h" +@#include "tx_timer.h" +@#include "tx_thread.h" +@ +@ + .arm + +@ +@/* Define Assembly language external references... */ +@ + .global _tx_timer_time_slice + .global _tx_timer_system_clock + .global _tx_timer_current_ptr + .global _tx_timer_list_start + .global _tx_timer_list_end + .global _tx_timer_expired_time_slice + .global _tx_timer_expired + .global _tx_thread_time_slice +@ +@ +@ +@/* Define the 16-bit Thumb mode veneer for _tx_timer_interrupt for +@ applications calling this function from to 16-bit Thumb mode. */ +@ + .text + .align 2 + .thumb + .global $_tx_timer_interrupt + .type $_tx_timer_interrupt,function +$_tx_timer_interrupt: + BX pc @ Switch to 32-bit mode + NOP @ + .arm + STMFD sp!, {lr} @ Save return address + BL _tx_timer_interrupt @ Call _tx_timer_interrupt function + LDMFD sp!, {lr} @ Recover saved return address + BX lr @ Return to 16-bit caller +@ +@ + .text + .align 2 +@/**************************************************************************/ +@/* */ +@/* FUNCTION RELEASE */ +@/* */ +@/* _tx_timer_interrupt ARM11/GNU */ +@/* 6.0.1 */ +@/* AUTHOR */ +@/* */ +@/* William E. Lamie, Microsoft Corporation */ +@/* */ +@/* DESCRIPTION */ +@/* */ +@/* This function processes the hardware timer interrupt. This */ +@/* processing includes incrementing the system clock and checking for */ +@/* time slice and/or timer expiration. If either is found, the */ +@/* interrupt context save/restore functions are called along with the */ +@/* expiration functions. */ +@/* */ +@/* INPUT */ +@/* */ +@/* None */ +@/* */ +@/* OUTPUT */ +@/* */ +@/* None */ +@/* */ +@/* CALLS */ +@/* */ +@/* _tx_thread_time_slice Time slice interrupted thread */ +@/* _tx_timer_expiration_process Timer expiration processing */ +@/* */ +@/* CALLED BY */ +@/* */ +@/* interrupt vector */ +@/* */ +@/* RELEASE HISTORY */ +@/* */ +@/* DATE NAME DESCRIPTION */ +@/* */ +@/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +@/* */ +@/**************************************************************************/ +@VOID _tx_timer_interrupt(VOID) +@{ + .global _tx_timer_interrupt + .type _tx_timer_interrupt,function +_tx_timer_interrupt: +@ +@ /* Upon entry to this routine, it is assumed that context save has already +@ been called, and therefore the compiler scratch registers are available +@ for use. */ +@ +@ /* Increment the system clock. */ +@ _tx_timer_system_clock++; +@ + LDR r1, =_tx_timer_system_clock @ Pickup address of system clock + LDR r0, [r1] @ Pickup system clock + ADD r0, r0, #1 @ Increment system clock + STR r0, [r1] @ Store new system clock +@ +@ /* Test for time-slice expiration. */ +@ if (_tx_timer_time_slice) +@ { +@ + LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice + LDR r2, [r3] @ Pickup time-slice + CMP r2, #0 @ Is it non-active? + BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing +@ +@ /* Decrement the time_slice. */ +@ _tx_timer_time_slice--; +@ + SUB r2, r2, #1 @ Decrement the time-slice + STR r2, [r3] @ Store new time-slice value +@ +@ /* Check for expiration. */ +@ if (__tx_timer_time_slice == 0) +@ + CMP r2, #0 @ Has it expired? + BNE __tx_timer_no_time_slice @ No, skip expiration processing +@ +@ /* Set the time-slice expired flag. */ +@ _tx_timer_expired_time_slice = TX_TRUE; +@ + LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag + MOV r0, #1 @ Build expired value + STR r0, [r3] @ Set time-slice expiration flag +@ +@ } +@ +__tx_timer_no_time_slice: +@ +@ /* Test for timer expiration. */ +@ if (*_tx_timer_current_ptr) +@ { +@ + LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address + LDR r0, [r1] @ Pickup current timer + LDR r2, [r0] @ Pickup timer list entry + CMP r2, #0 @ Is there anything in the list? + BEQ __tx_timer_no_timer @ No, just increment the timer +@ +@ /* Set expiration flag. */ +@ _tx_timer_expired = TX_TRUE; +@ + LDR r3, =_tx_timer_expired @ Pickup expiration flag address + MOV r2, #1 @ Build expired value + STR r2, [r3] @ Set expired flag + B __tx_timer_done @ Finished timer processing +@ +@ } +@ else +@ { +__tx_timer_no_timer: +@ +@ /* No timer expired, increment the timer pointer. */ +@ _tx_timer_current_ptr++; +@ + ADD r0, r0, #4 @ Move to next timer +@ +@ /* Check for wraparound. */ +@ if (_tx_timer_current_ptr == _tx_timer_list_end) +@ + LDR r3, =_tx_timer_list_end @ Pickup address of timer list end + LDR r2, [r3] @ Pickup list end + CMP r0, r2 @ Are we at list end? + BNE __tx_timer_skip_wrap @ No, skip wraparound logic +@ +@ /* Wrap to beginning of list. */ +@ _tx_timer_current_ptr = _tx_timer_list_start; +@ + LDR r3, =_tx_timer_list_start @ Pickup address of timer list start + LDR r0, [r3] @ Set current pointer to list start +@ +__tx_timer_skip_wrap: +@ + STR r0, [r1] @ Store new current timer pointer +@ } +@ +__tx_timer_done: +@ +@ +@ /* See if anything has expired. */ +@ if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) +@ { +@ + LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag + LDR r2, [r3] @ Pickup time-slice expired flag + CMP r2, #0 @ Did a time-slice expire? + BNE __tx_something_expired @ If non-zero, time-slice expired + LDR r1, =_tx_timer_expired @ Pickup address of other expired flag + LDR r0, [r1] @ Pickup timer expired flag + CMP r0, #0 @ Did a timer expire? + BEQ __tx_timer_nothing_expired @ No, nothing expired +@ +__tx_something_expired: +@ +@ + STMDB sp!, {r0, lr} @ Save the lr register on the stack + @ and save r0 just to keep 8-byte alignment +@ +@ /* Did a timer expire? */ +@ if (_tx_timer_expired) +@ { +@ + LDR r1, =_tx_timer_expired @ Pickup address of expired flag + LDR r0, [r1] @ Pickup timer expired flag + CMP r0, #0 @ Check for timer expiration + BEQ __tx_timer_dont_activate @ If not set, skip timer activation +@ +@ /* Process timer expiration. */ +@ _tx_timer_expiration_process(); +@ + BL _tx_timer_expiration_process @ Call the timer expiration handling routine +@ +@ } +__tx_timer_dont_activate: +@ +@ /* Did time slice expire? */ +@ if (_tx_timer_expired_time_slice) +@ { +@ + LDR r3, =_tx_timer_expired_time_slice @ Pickup address of time-slice expired + LDR r2, [r3] @ Pickup the actual flag + CMP r2, #0 @ See if the flag is set + BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing +@ +@ /* Time slice interrupted thread. */ +@ _tx_thread_time_slice(); +@ + BL _tx_thread_time_slice @ Call time-slice processing +@ +@ } +@ +__tx_timer_not_ts_expiration: +@ + LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for + @ the 8-byte stack alignment +@ +@ } +@ +__tx_timer_nothing_expired: +@ +#ifdef __THUMB_INTERWORK + BX lr @ Return to caller +#else + MOV pc, lr @ Return to caller +#endif +@ +@} + diff --git a/ports/arm11/iar/example_build/azure_rtos.eww b/ports/arm11/iar/example_build/azure_rtos.eww new file mode 100644 index 000000000..17e0d3292 --- /dev/null +++ b/ports/arm11/iar/example_build/azure_rtos.eww @@ -0,0 +1,13 @@ + + + + + $WS_DIR$\sample_threadx.ewp + + + $WS_DIR$\tx.ewp + + + + + diff --git a/ports/arm11/iar/example_build/cstartup.s b/ports/arm11/iar/example_build/cstartup.s new file mode 100644 index 000000000..b95efc0e9 --- /dev/null +++ b/ports/arm11/iar/example_build/cstartup.s @@ -0,0 +1,161 @@ + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Part one of the system initialization code, +;; contains low-level +;; initialization. +;; +;; Copyright 2007 IAR Systems. All rights reserved. +;; +;; $Revision: 14520 $ +;; + + MODULE ?cstartup + + ;; Forward declaration of sections. + SECTION IRQ_STACK:DATA:NOROOT(3) + SECTION FIQ_STACK:DATA:NOROOT(3) + SECTION CSTACK:DATA:NOROOT(3) + +; +; The module in this file are included in the libraries, and may be +; replaced by any user-defined modules that define the PUBLIC symbol +; __iar_program_start or a user defined start symbol. +; +; To override the cstartup defined in the library, simply add your +; modified version to the workbench project. + + SECTION .intvec:CODE:NOROOT(2) + + PUBLIC __vector + PUBLIC __vector_0x14 + PUBLIC __iar_program_start + EXTERN __tx_undefined + EXTERN __tx_swi_interrupt + EXTERN __tx_prefetch_handler + EXTERN __tx_abort_handler + EXTERN __tx_irq_handler + EXTERN __tx_fiq_handler + + ARM +__vector: + ; All default exception handlers (except reset) are + ; defined as weak symbol definitions. + ; If a handler is defined by the application it will take precedence. + LDR PC,Reset_Addr ; Reset + LDR PC,Undefined_Addr ; Undefined instructions + LDR PC,SWI_Addr ; Software interrupt (SWI/SVC) + LDR PC,Prefetch_Addr ; Prefetch abort + LDR PC,Abort_Addr ; Data abort +__vector_0x14: + DCD 0 ; RESERVED + LDR PC,IRQ_Addr ; IRQ + LDR PC,FIQ_Addr ; FIQ + +Reset_Addr: DCD __iar_program_start +Undefined_Addr: DCD __tx_undefined +SWI_Addr: DCD __tx_swi_interrupt +Prefetch_Addr: DCD __tx_prefetch_handler +Abort_Addr: DCD __tx_abort_handler +IRQ_Addr: DCD __tx_irq_handler +FIQ_Addr: DCD __tx_fiq_handler + +; -------------------------------------------------- +; ?cstartup -- low-level system initialization code. +; +; After a reser execution starts here, the mode is ARM, supervisor +; with interrupts disabled. +; + + + + SECTION .text:CODE:NOROOT(2) + +; PUBLIC ?cstartup + EXTERN ?main + REQUIRE __vector + + ARM + +__iar_program_start: +?cstartup: + +; +; Add initialization needed before setup of stackpointers here. +; + +; +; Initialize the stack pointers. +; The pattern below can be used for any of the exception stacks: +; FIQ, IRQ, SVC, ABT, UND, SYS. +; The USR mode uses the same stack as SYS. +; The stack segments must be defined in the linker command file, +; and be declared above. +; + + +; -------------------- +; Mode, correspords to bits 0-5 in CPSR + +MODE_MSK DEFINE 0x1F ; Bit mask for mode bits in CPSR + +USR_MODE DEFINE 0x10 ; User mode +FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode +IRQ_MODE DEFINE 0x12 ; Interrupt Request mode +SVC_MODE DEFINE 0x13 ; Supervisor mode +ABT_MODE DEFINE 0x17 ; Abort mode +UND_MODE DEFINE 0x1B ; Undefined Instruction mode +SYS_MODE DEFINE 0x1F ; System mode + + + MRS r0, cpsr ; Original PSR value + + ;; Set up the interrupt stack pointer. + + BIC r0, r0, #MODE_MSK ; Clear the mode bits + ORR r0, r0, #IRQ_MODE ; Set IRQ mode bits + MSR cpsr_c, r0 ; Change the mode + LDR sp, =SFE(IRQ_STACK) ; End of IRQ_STACK + + ;; Set up the fast interrupt stack pointer. + + BIC r0, r0, #MODE_MSK ; Clear the mode bits + ORR r0, r0, #FIQ_MODE ; Set FIR mode bits + MSR cpsr_c, r0 ; Change the mode + LDR sp, =SFE(FIQ_STACK) ; End of FIQ_STACK + + ;; Set up the normal stack pointer. + + BIC r0 ,r0, #MODE_MSK ; Clear the mode bits + ORR r0 ,r0, #SYS_MODE ; Set System mode bits + MSR cpsr_c, r0 ; Change the mode + LDR sp, =SFE(CSTACK) ; End of CSTACK + +#ifdef __ARMVFP__ + ;; Enable the VFP coprocessor. + + MOV r0, #0x40000000 ; Set EN bit in VFP + FMXR fpexc, r0 ; FPEXC, clear others. + +; +; Disable underflow exceptions by setting flush to zero mode. +; For full IEEE 754 underflow compliance this code should be removed +; and the appropriate exception handler installed. +; + + MOV r0, #0x01000000 ; Set FZ bit in VFP + FMXR fpscr, r0 ; FPSCR, clear others. +#endif + +; +; Add more initialization here +; + +; Continue to ?main for C-level initialization. + + B ?main + + END + + + diff --git a/ports/arm11/iar/example_build/sample_threadx.c b/ports/arm11/iar/example_build/sample_threadx.c new file mode 100644 index 000000000..a57d908d8 --- /dev/null +++ b/ports/arm11/iar/example_build/sample_threadx.c @@ -0,0 +1,374 @@ +/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight + threads of different priorities, using a message queue, semaphore, mutex, event flags group, + byte pool, and block pool. */ + +#include "tx_api.h" + +#define DEMO_STACK_SIZE 1024 +#define DEMO_BYTE_POOL_SIZE 9120 +#define DEMO_BLOCK_POOL_SIZE 100 +#define DEMO_QUEUE_SIZE 100 + + +/* Define the ThreadX object control blocks... */ + +TX_THREAD thread_0; +TX_THREAD thread_1; +TX_THREAD thread_2; +TX_THREAD thread_3; +TX_THREAD thread_4; +TX_THREAD thread_5; +TX_THREAD thread_6; +TX_THREAD thread_7; +TX_QUEUE queue_0; +TX_SEMAPHORE semaphore_0; +TX_MUTEX mutex_0; +TX_EVENT_FLAGS_GROUP event_flags_0; +TX_BYTE_POOL byte_pool_0; +TX_BLOCK_POOL block_pool_0; + + +/* Define byte pool memory. */ + +UCHAR byte_pool_memory[DEMO_BYTE_POOL_SIZE]; + + +/* Define the counters used in the demo application... */ + +ULONG thread_0_counter; +ULONG thread_1_counter; +ULONG thread_1_messages_sent; +ULONG thread_2_counter; +ULONG thread_2_messages_received; +ULONG thread_3_counter; +ULONG thread_4_counter; +ULONG thread_5_counter; +ULONG thread_6_counter; +ULONG thread_7_counter; + + +/* Define thread prototypes. */ + +void thread_0_entry(ULONG thread_input); +void thread_1_entry(ULONG thread_input); +void thread_2_entry(ULONG thread_input); +void thread_3_and_4_entry(ULONG thread_input); +void thread_5_entry(ULONG thread_input); +void thread_6_and_7_entry(ULONG thread_input); + + +/* Define main entry point. */ + +int main() +{ + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ + +void tx_application_define(void *first_unused_memory) +{ + +CHAR *pointer; + + + /* Create a byte memory pool from which to allocate the thread stacks. */ + tx_byte_pool_create(&byte_pool_0, "byte pool 0", byte_pool_memory, DEMO_BYTE_POOL_SIZE); + + /* Put system definition stuff in here, e.g. thread creates and other assorted + create information. */ + + /* Allocate the stack for thread 0. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + + + /* Allocate the stack for thread 1. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 1 and 2. These threads pass information through a ThreadX + message queue. It is also interesting to note that these threads have a time + slice. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, DEMO_STACK_SIZE, + 16, 16, 4, TX_AUTO_START); + + /* Allocate the stack for thread 2. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, DEMO_STACK_SIZE, + 16, 16, 4, TX_AUTO_START); + + /* Allocate the stack for thread 3. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore. + An interesting thing here is that both threads share the same instruction area. */ + tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 4. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 5. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create thread 5. This thread simply pends on an event flag which will be set + by thread_0. */ + tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 6. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 6 and 7. These threads compete for a ThreadX mutex. */ + tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 7. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the message queue. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT); + + /* Create the message queue shared by threads 1 and 2. */ + tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG)); + + /* Create the semaphore used by threads 3 and 4. */ + tx_semaphore_create(&semaphore_0, "semaphore 0", 1); + + /* Create the event flags group used by threads 1 and 5. */ + tx_event_flags_create(&event_flags_0, "event flags 0"); + + /* Create the mutex used by thread 6 and 7 without priority inheritance. */ + tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Allocate the memory for a small block pool. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT); + + /* Create a block memory pool to allocate a message buffer from. */ + tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE); + + /* Allocate a block and release the block memory. */ + tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT); + + /* Release the block back to the pool. */ + tx_block_release(pointer); +} + + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* This thread simply sits in while-forever-sleep loop. */ + while(1) + { + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Sleep for 10 ticks. */ + tx_thread_sleep(10); + + /* Set event flag 0 to wakeup thread 5. */ + status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* This thread simply sends messages to a queue shared by thread 2. */ + while(1) + { + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Send message to queue 0. */ + status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER); + + /* Check completion status. */ + if (status != TX_SUCCESS) + break; + + /* Increment the message sent. */ + thread_1_messages_sent++; + } +} + + +void thread_2_entry(ULONG thread_input) +{ + +ULONG received_message; +UINT status; + + /* This thread retrieves messages placed on the queue by thread 1. */ + while(1) + { + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Retrieve a message from the queue. */ + status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER); + + /* Check completion status and make sure the message is what we + expected. */ + if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received)) + break; + + /* Otherwise, all is okay. Increment the received message count. */ + thread_2_messages_received++; + } +} + + +void thread_3_and_4_entry(ULONG thread_input) +{ + +UINT status; + + + /* This function is executed from thread 3 and thread 4. As the loop + below shows, these function compete for ownership of semaphore_0. */ + while(1) + { + + /* Increment the thread counter. */ + if (thread_input == 3) + thread_3_counter++; + else + thread_4_counter++; + + /* Get the semaphore with suspension. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Sleep for 2 ticks to hold the semaphore. */ + tx_thread_sleep(2); + + /* Release the semaphore. */ + status = tx_semaphore_put(&semaphore_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +void thread_5_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_flags; + + + /* This thread simply waits for an event in a forever loop. */ + while(1) + { + + /* Increment the thread counter. */ + thread_5_counter++; + + /* Wait for event flag 0. */ + status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR, + &actual_flags, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_flags != 0x1)) + break; + } +} + + +void thread_6_and_7_entry(ULONG thread_input) +{ + +UINT status; + + + /* This function is executed from thread 6 and thread 7. As the loop + below shows, these function compete for ownership of mutex_0. */ + while(1) + { + + /* Increment the thread counter. */ + if (thread_input == 6) + thread_6_counter++; + else + thread_7_counter++; + + /* Get the mutex with suspension. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Get the mutex again with suspension. This shows + that an owning thread may retrieve the mutex it + owns multiple times. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Sleep for 2 ticks to hold the mutex. */ + tx_thread_sleep(2); + + /* Release the mutex. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Release the mutex again. This will actually + release ownership since it was obtained twice. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} diff --git a/ports/arm11/iar/example_build/sample_threadx.ewd b/ports/arm11/iar/example_build/sample_threadx.ewd new file mode 100644 index 000000000..572d1f457 --- /dev/null +++ b/ports/arm11/iar/example_build/sample_threadx.ewd @@ -0,0 +1,2974 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\HWRTOSplugin\HWRTOSplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\RemedyRtosViewer\RemedyRtosViewer.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8b.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8bBE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 1 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 7 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\HWRTOSplugin\HWRTOSplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\RemedyRtosViewer\RemedyRtosViewer.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8b.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8bBE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/ports/arm11/iar/example_build/sample_threadx.ewp b/ports/arm11/iar/example_build/sample_threadx.ewp new file mode 100644 index 000000000..40280bd59 --- /dev/null +++ b/ports/arm11/iar/example_build/sample_threadx.ewp @@ -0,0 +1,2136 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 36 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 31 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 36 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + Common sources + + $PROJ_DIR$\cstartup.s + + + $PROJ_DIR$\sample_threadx.c + + + $PROJ_DIR$\Debug\Exe\tx.a + + + $PROJ_DIR$\tx_api.h + + + $PROJ_DIR$\tx_initialize_low_level.s + + + $PROJ_DIR$\tx_port.h + + + diff --git a/ports/arm11/iar/example_build/sample_threadx.ewt b/ports/arm11/iar/example_build/sample_threadx.ewt new file mode 100644 index 000000000..a30fa4d35 --- /dev/null +++ b/ports/arm11/iar/example_build/sample_threadx.ewt @@ -0,0 +1,2797 @@ + + + 3 + + Debug + + ARM + + 1 + + C-STAT + 263 + + 263 + + 0 + + 1 + 600 + 0 + 2 + 0 + 1 + 100 + + + 1.7.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuntimeChecking + 0 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + Release + + ARM + + 0 + + C-STAT + 263 + + 263 + + 0 + + 1 + 600 + 0 + 2 + 0 + 1 + 100 + + + 1.7.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuntimeChecking + 0 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + Common sources + + $PROJ_DIR$\cstartup.s + + + $PROJ_DIR$\sample_threadx.c + + + $PROJ_DIR$\Debug\Exe\tx.a + + + $PROJ_DIR$\tx_api.h + + + $PROJ_DIR$\tx_initialize_low_level.s + + + $PROJ_DIR$\tx_port.h + + + diff --git a/ports/arm11/iar/example_build/sample_threadx.icf b/ports/arm11/iar/example_build/sample_threadx.icf new file mode 100644 index 000000000..9c95e1d1c --- /dev/null +++ b/ports/arm11/iar/example_build/sample_threadx.icf @@ -0,0 +1,49 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x0; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x80; +define symbol __ICFEDIT_region_ROM_end__ = 0x1FFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x100000; +define symbol __ICFEDIT_region_RAM_end__ = 0x1FFFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x2000; +define symbol __ICFEDIT_size_svcstack__ = 0x100; +define symbol __ICFEDIT_size_irqstack__ = 0x100; +define symbol __ICFEDIT_size_fiqstack__ = 0x100; +define symbol __ICFEDIT_size_undstack__ = 0x100; +define symbol __ICFEDIT_size_abtstack__ = 0x100; +define symbol __ICFEDIT_size_heap__ = 0x8000; +/**** End of ICF editor section. ###ICF###*/ + +define symbol __ICFEDIT_size_freemem__ = 0x100000; + + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region RAM_freemem = mem:[from 0x200000 to 0x300000]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { }; +define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { }; +define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { }; +define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { }; +define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + + +initialize by copy { readwrite }; +initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK, + block UND_STACK, block ABT_STACK, block HEAP}; + +place in RAM_region { last section FREE_MEM}; \ No newline at end of file diff --git a/ports/arm11/iar/example_build/settings/azure_rtos.wsdt b/ports/arm11/iar/example_build/settings/azure_rtos.wsdt new file mode 100644 index 000000000..378e45844 --- /dev/null +++ b/ports/arm11/iar/example_build/settings/azure_rtos.wsdt @@ -0,0 +1,535 @@ + + + + + sample_threadx/Debug + tx/Debug + + sample_threadx + 1 + + + + + 21 + 2518 + 2 + + 0 + -1 + + + + 34001 + 0 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33038 + 33039 + 0 + + + + + 359 + 30 + 30 + 30 + + + <ws> + + + + 14 + 26 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 010000000D002596000001000000108600000B0000000C8100000300000004860000010000001781000002000000148100000100000003E10000010000000E81000001000000E980000001000000118600000A00000046810000020000000D81000001000000E880000001000000 + + + 0F000D8400000F84000008840000FFFFFFFF54840000328100001C81000009840000818400007D8400008284000083840000848400000E84000030840000 + 0400048400004C000000068400004E0000000B8100001B0000000D8100001D000000 + + + 0 + 0A0000000A0000006E0000006E000000 + 000000004E050000000A000061050000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34051 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 4294967295 + 0000000082040000000A000065050000 + 000000006B040000000A00004E050000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34052 + 000000001700000022010000C8000000 + 0400000083040000FC09000034050000 + 32768 + 0 + 0 + 32767 + 0 + + + 1 + + + 24 + 1880 + 501 + 125 + 2 + C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\BuildLog.log + 0 + -1 + + + 34048 + 000000001700000022010000C8000000 + 0400000083040000FC09000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34056 + 000000001700000022010000C8000000 + 0400000083040000FC09000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 891 + 127 + 1528 + 2 + + 0 + -1 + + + 34057 + 000000001700000022010000C8000000 + 0400000083040000FC09000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 891 + 127 + 1528 + 2 + + 0 + -1 + + + 34058 + 000000001700000022010000C8000000 + 0400000083040000FC09000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 764 + 127 + 1146 + 509 + 2 + + 0 + -1 + + + 34059 + 000000001700000022010000C8000000 + 0400000083040000FC09000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 891 + 127 + 1528 + 2 + + 0 + -1 + + + 34062 + 000000001700000022010000C8000000 + 0400000083040000FC09000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 2 + + 0 + -1 + + + 34053 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + + + + + + + <Right-click on a symbol in the editor to show a call graph> + + + + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + File + Function + Line + + + 200 + 700 + 100 + + + + 34054 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34055 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + Check + File + Line + Message + Severity + + + 200 + 200 + 100 + 500 + 100 + + + + 34060 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 2 + $WS_DIR/SourceBrowseLog.log + 0 + -1 + + + 34061 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 2 + + + 0 + + + C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\Debug\Obj\sample_threadx.pbw + + + File + Name + Scope + Symbol type + + + 300 + 300 + 300 + 300 + + + + 34063 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34064 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34065 + 00000000170000000601000078010000 + 0000000032000000AF01000067040000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 0000000014000000000000000010000001000000FFFFFFFFFFFFFFFFAF01000032000000B301000067040000010000000200001004000000010000005DFFFFFFBD080000118500000000000000000000000000000000000001000000118500000100000011850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000108500000000000000000000000000000000000001000000108500000100000010850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000C85000000000000000000000000000000000000010000000C850000010000000C850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000078500000000000000000000000000000000000001000000078500000100000007850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000058500000000000000000000000000000000000001000000058500000100000005850000000000000080000001000000FFFFFFFFFFFFFFFF0000000067040000000A00006B040000010000000100001004000000010000009EFBFFFF6F000000FFFFFFFF07000000048500000085000008850000098500000A8500000B8500000E850000FFFF02000B004354616262656450616E6500800000010000000000000082040000000A000065050000000000006B040000000A00004E050000000000004080005607000000FFFEFF054200750069006C006400010000000485000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000000085000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300000000000885000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000000985000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000000A85000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000000B85000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000000E85000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF0485000001000000FFFFFFFF04850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000038500000000000000000000000000000000000001000000038500000100000003850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000100FFFF01001100434D4643546F6F6C426172427574746F6ED1840000000000000C000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B0018000000 + + + 34049 + 0A0000000A0000006E0000006E000000 + FE020000000000002C0300001A000000 + 8192 + 0 + 0 + 24 + 0 + + + 1 + + + Main + 00200000010000002000FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000035000000FFFEFF000000000000000000000000000100000001000000018001E100000000000036000000FFFEFF000000000000000000000000000100000001000000018003E100000000040038000000FFFEFF0000000000000000000000000001000000010000000180008100000000000019000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000004003B000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E10000000004003D000000FFFEFF000000000000000000000000000100000001000000018022E10000000004003C000000FFFEFF000000000000000000000000000100000001000000018025E10000000004003F000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000040042000000FFFEFF00000000000000000000000000010000000100000001802CE100000000040043000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000400FFFFFFFFFFFEFF0000000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF0096000000000000000000018021810000000004002C000000FFFEFF000000000000000000000000000100000001000000018024E10000000004003E000000FFFEFF000000000000000000000000000100000001000000018028E100000000040040000000FFFEFF000000000000000000000000000100000001000000018029E100000000040041000000FFFEFF000000000000000000000000000100000001000000018002810000000004001B000000FFFEFF0000000000000000000000000001000000010000000180298100000000040030000000FFFEFF000000000000000000000000000100000001000000018027810000000004002E000000FFFEFF000000000000000000000000000100000001000000018028810000000004002F000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040028000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040029000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000000004001F000000FFFEFF00000000000000000000000000010000000100000001800C8100000000000020000000FFFEFF00000000000000000000000000010000000100000001805F8600000000000034000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800E8100000000000022000000FFFEFF00000000000000000000000000010000000100000001800F8100000000000023000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00E8020000 + + + 34050 + 0A0000000A0000006E0000006E000000 + 0000000000000000FE0200001A000000 + 8192 + 0 + 0 + 744 + 0 + + + 1 + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + 34064 + 34065 + + + + 01000000030000000100000000000000000000000100000001000000FFFFFFFF00000000010000000100000000000000280000002800000000000000 + + + + diff --git a/ports/arm11/iar/example_build/settings/sample_threadx.Debug.cspy.bat b/ports/arm11/iar/example_build/settings/sample_threadx.Debug.cspy.bat new file mode 100644 index 000000000..da603fdb8 --- /dev/null +++ b/ports/arm11/iar/example_build/settings/sample_threadx.Debug.cspy.bat @@ -0,0 +1,40 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM +@REM Read about available command line parameters in the C-SPY Debugging +@REM Guide. Hints about additional command line parameters that may be +@REM useful in specific cases: +@REM --download_only Downloads a code image without starting a debug +@REM session afterwards. +@REM --silent Omits the sign-on message. +@REM --timeout Limits the maximum allowed execution time. +@REM + + +@echo off + +if not "%~1" == "" goto debugFile + +@echo on + +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.driver.xcl" + +@echo off +goto end + +:debugFile + +@echo on + +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.driver.xcl" + +@echo off +:end \ No newline at end of file diff --git a/ports/arm11/iar/example_build/settings/sample_threadx.Debug.cspy.ps1 b/ports/arm11/iar/example_build/settings/sample_threadx.Debug.cspy.ps1 new file mode 100644 index 000000000..af990a9b0 --- /dev/null +++ b/ports/arm11/iar/example_build/settings/sample_threadx.Debug.cspy.ps1 @@ -0,0 +1,31 @@ +param([String]$debugfile = ""); + +# This powershell file has been generated by the IAR Embedded Workbench +# C - SPY Debugger, as an aid to preparing a command line for running +# the cspybat command line utility using the appropriate settings. +# +# Note that this file is generated every time a new debug session +# is initialized, so you may want to move or rename the file before +# making changes. +# +# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed +# by the name of the debug file (usually an ELF / DWARF or UBROF file). +# +# Read about available command line parameters in the C - SPY Debugging +# Guide. Hints about additional command line parameters that may be +# useful in specific cases : +# --download_only Downloads a code image without starting a debug +# session afterwards. +# --silent Omits the sign - on message. +# --timeout Limits the maximum allowed execution time. +# + + +if ($debugfile -eq "") +{ +& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.general.xcl" --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.driver.xcl" +} +else +{ +& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\common\bin\cspybat" -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\settings\sample_threadx.Debug.driver.xcl" +} diff --git a/ports/arm11/iar/example_build/settings/sample_threadx.Debug.driver.xcl b/ports/arm11/iar/example_build/settings/sample_threadx.Debug.driver.xcl new file mode 100644 index 000000000..06e18c00f --- /dev/null +++ b/ports/arm11/iar/example_build/settings/sample_threadx.Debug.driver.xcl @@ -0,0 +1,13 @@ +"--endian=little" + +"--cpu=ARM1136J-S" + +"--fpu=None" + +"--semihosting" + +"--multicore_nr_of_cores=1" + + + + diff --git a/ports/arm11/iar/example_build/settings/sample_threadx.Debug.general.xcl b/ports/arm11/iar/example_build/settings/sample_threadx.Debug.general.xcl new file mode 100644 index 000000000..dcf7704ac --- /dev/null +++ b/ports/arm11/iar/example_build/settings/sample_threadx.Debug.general.xcl @@ -0,0 +1,11 @@ +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armproc.dll" + +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armsim2.dll" + +"C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\arm11\iar\example_build\Debug\Exe\sample_threadx.out" + +--plugin="C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.4\arm\bin\armbat.dll" + + + + diff --git a/ports/arm11/iar/example_build/settings/sample_threadx.crun b/ports/arm11/iar/example_build/settings/sample_threadx.crun new file mode 100644 index 000000000..d71ea555a --- /dev/null +++ b/ports/arm11/iar/example_build/settings/sample_threadx.crun @@ -0,0 +1,13 @@ + + + 1 + + + * + * + * + 0 + 1 + + + diff --git a/ports/arm11/iar/example_build/settings/sample_threadx.dbgdt b/ports/arm11/iar/example_build/settings/sample_threadx.dbgdt new file mode 100644 index 000000000..9f3dbd0a3 --- /dev/null +++ b/ports/arm11/iar/example_build/settings/sample_threadx.dbgdt @@ -0,0 +1,1685 @@ + + + + + + + 395 + 27 + 27 + 2010398909 + + + + + 2 + 0 + 0 + + + 1 + 0 + 0 + + + 47 + 1666 + + + 20 + 915 + 244 + 61 + + + + 2 + 0 + 0 + + + + + + 3 + 0 + 0 + + + 0 + 1 + 0 + + + + + + + + 2 + 0 + 0 + + + 187 + 100 + 100 + 100 + + + 21 + 50 + 142 + 120 + 170 + 80 + 100 + 100 + 100 + 80 + 95 + + + + + + + + + + + + + TabID-32281-8114 + Workspace + Workspace + + + <ws> + <ws>/sample_threadx + <ws>/sample_threadx/Common sources + <ws>/sample_threadx/Common sources/tx_cstartup.s79 + sample_threadx + sample_threadx/Output + sample_threadx/Output/sample_threadx.out + sample_threadx/Output/sample_threadx.out/Output + + + + + 0 + + + + + TabID-31758-8124 + Debug Log + Debug-Log + + + + TabID-9738-8128 + Build + Build + + + + TabID-20156-25745 + Breakpoints + Breakpoints + + + 0 + + + + + + TabID-19697-5905 + Thread List + TX-THREAD + + 1 + + + + TabID-19175-5914 + Message Queues + TX-MESSAGEQUEUE + + + TabID-29400-5927 + Semaphores + TX-SEMAPHORE + + + TabID-6858-5940 + Mutexes + TX-MUTEX + + + TabID-6335-5950 + Byte Pools + TX-BYTEPOOL + + + TabID-16561-5963 + Block Pools + TX-BLOCKPOOL + + + TabID-26786-5976 + Timers + TX-TIMER + + + TabID-26264-5986 + Event Flag Groups + TX-EVENTFLAG + + + 0 + + + + + + TextEditor + $WS_DIR$\sample_threadx.c + 0 + 34 + 1720 + 1720 + + 0 + + 0 + + + 1000000 + 1000000 + + + 1 + + + + + + + iaridepm.enu1 + + + + + + + debuggergui.enu1 + + + + + + + threadxarmplugin.enu1 + + + + + + + + + + -2 + -2 + 570 + 469 + -2 + -2 + 135 + 169 + 88933 + 182505 + 310277 + 617711 + + + + + + + + + + + + + + + + -2 + -2 + 66 + 1520 + -2 + -2 + 1522 + 68 + 1002635 + 73434 + 88933 + 182505 + + + + + + + + + 64 + -2 + 263 + 1520 + -2 + 64 + 1522 + 199 + 1002635 + 214903 + 127800 + 214903 + + + + + + + + + + + + + 34048 + 34049 + 34050 + 34051 + 34052 + 34053 + 34054 + 34055 + 34056 + 34057 + 34058 + 34059 + 34060 + 34061 + 34062 + 34063 + 34064 + 34065 + 34066 + 34067 + 34068 + 34069 + 34070 + 34071 + 34072 + 34073 + 34074 + 34075 + 34076 + 34077 + 34078 + 34079 + 34080 + 34081 + 34082 + 34083 + 34084 + 34085 + 34086 + 34087 + 34088 + 34089 + 34090 + 34091 + 34092 + 34093 + 34094 + 34095 + 34096 + 34097 + 34098 + 34099 + 34100 + 34101 + 34102 + 34103 + 34104 + 34105 + 34106 + 34107 + 34108 + 34109 + 34110 + 34111 + 34112 + 34113 + 34114 + 34115 + 34116 + 34117 + 34118 + 34119 + 34120 + 34121 + 34122 + 34123 + 34124 + 34125 + 34126 + 34127 + 34128 + + + + + 34000 + 34001 + 0 + + + + + 34390 + 34323 + 34398 + 34400 + 34397 + 34320 + 34321 + 34324 + 0 + + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33055 + 33056 + 33094 + 0 + + + + 14 + 26 + + + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 210000000D002596000001000000108600000B0000000C8100000300000004860000010000001781000002000000148100000100000003E10000010000000E81000001000000E980000001000000118600000A00000046810000020000000D81000001000000E880000001000000 + + + 1000FFFFFFFF8386000058860000439200001E920000289200002992000024960000259600001F960000008800000188000002880000038800000488000005880000 + 2800578600001800000059920000240000001581000055000000239200000000000007E100006B00000004E1000069000000008D00001E00000007860000280000001D920000110000000D8000004700000001E100006600000004860000250000009A860000160000001781000057000000008400007800000025920000190000001481000054000000449200002200000000810000490000001A860000320000001F9200001F00000003E10000680000008E8600003B00000006860000270000002D9200002100000000E1000065000000698600003800000041E10000750000005586000006000000239600008900000016810000560000000E86000017000000518400008600000005E100006A000000A18600003C000000C38600000300000002E1000067000000C08600000A00000005860000260000002C92000020000000 + + + 0 + 0A0000000A0000006E0000006E000000 + 000000004E050000000A000061050000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34051 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34052 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 4294967295 + 000000004900000006010000DB020000 + 000000004C000000060100009A040000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34053 + 6D080000210000008F090000D1000000 + 04000000B6040000DB05000034050000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34056 + 6D080000210000008F090000D1000000 + 04000000E0020000DB0500005E030000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34064 + 6D080000210000008F090000D1000000 + 04000000B6040000FC09000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34066 + 6D080000210000008F090000D1000000 + 04000000B6040000FC09000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34067 + 6D080000210000008F090000D1000000 + 04000000B6040000DB05000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34068 + 6D080000210000008F090000D1000000 + 04000000B6040000DB05000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34102 + 6D080000210000008F090000D1000000 + 04000000B6040000DB05000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34114 + 6D080000210000008F090000D1000000 + 04000000B6040000DB05000034050000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34054 + 6D08000021000000ED0A0000B1000000 + 00000000000000008002000090000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34055 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34057 + 6D080000210000001B0A0000B1000000 + 040000004C020000DB050000AA020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34081 + 6D080000210000008F090000D1000000 + 0000000048020000DF050000C4020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34058 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 8192 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34059 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34060 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34061 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34062 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34063 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34065 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34069 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 8192 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34070 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 8192 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34071 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34072 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34073 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34074 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34075 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34076 + 6D080000210000008F090000E1000000 + 040000001C020000DB050000AA020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34077 + 6D080000210000008F090000E1000000 + 040000001C020000DB050000AA020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34078 + 6D080000210000008F090000E1000000 + 040000001C020000DB050000AA020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34079 + 6D080000210000008F090000E1000000 + 040000001C020000DB050000AA020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34080 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34082 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34083 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34084 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34085 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34086 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34087 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34088 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34089 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34090 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34091 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34092 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34093 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34094 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34095 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34096 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34097 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34098 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34099 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34100 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34101 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34103 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 8192 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34104 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 8192 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34105 + 6D080000210000007309000081010000 + 040000004A00000002010000AA020000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + 34123 + 6D080000210000007309000081010000 + 0000000060000000060100009A040000 + 4096 + 0 + 0 + 32767 + 0 + + + 1 + + + 34106 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34107 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 4096 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34108 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34109 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34110 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 8192 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34111 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34112 + 6D080000210000001B0A0000E1000000 + 0000000000000000AE010000C0000000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34113 + 6D080000210000001B0A0000E1000000 + 0000000000000000AE010000C0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34115 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34116 + 6D080000210000008F090000D1000000 + 0A01000014020000DF050000C4020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34117 + 6D080000210000008F090000D1000000 + 0A01000014020000DF050000C4020000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34118 + 6D080000210000008F090000D1000000 + 000000000000000022010000B0000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34119 + 6D080000210000007309000081010000 + C00800004C000000000A00009A040000 + 16384 + 0 + 0 + 32767 + 0 + + + 1 + + + + thread_0_counter + thread_1_counter + thread_2_counter + thread_3_counter + thread_4_counter + thread_5_counter + thread_6_counter + thread_7_counter + + + + Expression + Location + Type + Value + + + 145 + 150 + 100 + 100 + + + + 34120 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34121 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34122 + 6D080000210000007309000081010000 + 00000000000000000601000060010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 0000000080000000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000004A85000000000000000000000000000000000000010000004A850000010000004A850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000498500000000000000000000000000000000000001000000498500000100000049850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000488500000000000000000000000000000000000001000000488500000100000048850000000000000040000001000000FFFFFFFFFFFFFFFFBC0800004C000000C00800009A040000010000000200001004000000010000003AFCFFFFB5000000478500000000000000000000000000000000000001000000478500000100000047850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000468500000000000000000000000000000000000001000000468500000100000046850000000000000080000000000000FFFFFFFFFFFFFFFF0A01000010020000DF05000014020000000000000100000004000000010000000000000000000000458500000000000000000000000000000000000001000000458500000100000045850000000000000080000000000000FFFFFFFFFFFFFFFF0A01000010020000DF05000014020000000000000100000004000000010000000000000000000000448500000000000000000000000000000000000001000000448500000100000044850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000418500000000000000000000000000000000000001000000418500000100000041850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000408500000000000000000000000000000000000001000000408500000100000040850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000003F85000000000000000000000000000000000000010000003F850000010000003F850000000000000020000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000003E85000000000000000000000000000000000000010000003E850000010000003E850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000003D85000000000000000000000000000000000000010000003D850000010000003D850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000003C85000000000000000000000000000000000000010000003C850000010000003C850000000000000010000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000003B85000000000000000000000000000000000000010000003B850000010000003B850000000000000010000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000003A85000000000000000000000000000000000000010000003A850000010000003A850000000000000010000001000000FFFFFFFFFFFFFFFF060100004C0000000A0100009A040000010000000200001004000000010000000000000000000000FFFFFFFF010000004B850000FFFF02000B004354616262656450616E650010000001000000000000004900000006010000DB020000000000004C000000060100009A040000000000004010005601000000FFFEFF0957006F0072006B0073007000610063006500010000004B85000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFF4B85000001000000FFFFFFFF4B850000000000000020000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000388500000000000000000000000000000000000001000000388500000100000038850000000000000020000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000378500000000000000000000000000000000000001000000378500000100000037850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000358500000000000000000000000000000000000001000000358500000100000035850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000348500000000000000000000000000000000000001000000348500000100000034850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000338500000000000000000000000000000000000001000000338500000100000033850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000328500000000000000000000000000000000000001000000328500000100000032850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000318500000000000000000000000000000000000001000000318500000100000031850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000308500000000000000000000000000000000000001000000308500000100000030850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002F85000000000000000000000000000000000000010000002F850000010000002F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002E85000000000000000000000000000000000000010000002E850000010000002E850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002D85000000000000000000000000000000000000010000002D850000010000002D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002C85000000000000000000000000000000000000010000002C850000010000002C850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002B85000000000000000000000000000000000000010000002B850000010000002B850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000002A85000000000000000000000000000000000000010000002A850000010000002A850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000298500000000000000000000000000000000000001000000298500000100000029850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000288500000000000000000000000000000000000001000000288500000100000028850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000278500000000000000000000000000000000000001000000278500000100000027850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000268500000000000000000000000000000000000001000000268500000100000026850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000258500000000000000000000000000000000000001000000258500000100000025850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000248500000000000000000000000000000000000001000000248500000100000024850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000238500000000000000000000000000000000000001000000238500000100000023850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000228500000000000000000000000000000000000001000000228500000100000022850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000208500000000000000000000000000000000000001000000208500000100000020850000000000000080000000000000FFFFFFFFFFFFFFFF0000000000020000DF05000004020000000000000100000004000000010000000000000000000000FFFFFFFF040000001C8500001D8500001E8500001F85000001800080000000000000000000001B020000DF050000DB0200000000000004020000DF050000C4020000000000004080004604000000FFFEFF084D0065006D006F007200790020003100000000001C85000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003200000000001D85000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003300000000001E85000001000000FFFFFFFFFFFFFFFFFFFEFF084D0065006D006F007200790020003400000000001F85000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF1C85000001000000FFFFFFFF1C850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000001B85000000000000000000000000000000000000010000001B850000010000001B850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000001A85000000000000000000000000000000000000010000001A850000010000001A850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000198500000000000000000000000000000000000001000000198500000100000019850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000188500000000000000000000000000000000000001000000188500000100000018850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000178500000000000000000000000000000000000001000000178500000100000017850000000000000020000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000168500000000000000000000000000000000000001000000168500000100000016850000000000000020000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000158500000000000000000000000000000000000001000000158500000100000015850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000118500000000000000000000000000000000000001000000118500000100000011850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000000040000000100000000000000000000000F85000000000000000000000000000000000000010000000F850000010000000F850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000E85000000000000000000000000000000000000010000000E850000010000000E850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000D85000000000000000000000000000000000000010000000D850000010000000D850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000C85000000000000000000000000000000000000010000000C850000010000000C850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000B85000000000000000000000000000000000000010000000B850000010000000B850000000000000020000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000000040000000100000000000000000000000A85000000000000000000000000000000000000010000000A850000010000000A850000000000000080000000000000FFFFFFFFFFFFFFFF0000000030020000DF05000034020000000000000100000004000000010000000000000000000000FFFFFFFF010000002185000001800080000000000000000000004B020000DF050000DB0200000000000034020000DF050000C4020000000000004080004601000000FFFEFF11460075006E006300740069006F006E002000500072006F00660069006C0065007200000000002185000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFF2185000001000000FFFFFFFF21850000000000000010000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000078500000000000000000000000000000000000001000000078500000100000007850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000068500000000000000000000000000000000000001000000068500000100000006850000000000000080000001000000FFFFFFFFFFFFFFFF000000009A040000000A00009E040000010000000100001004000000010000000000000000000000FFFFFFFF07000000058500001085000012850000138500001485000036850000428500000180008000000100000000000000DF020000DF0500008F030000000000009E040000000A00004E050000000000004080005607000000FFFEFF054200750069006C006400000000000585000001000000FFFFFFFFFFFFFFFFFFFEFF094400650062007500670020004C006F006700010000001085000001000000FFFFFFFFFFFFFFFFFFFEFF0C4400650063006C00610072006100740069006F006E007300010000001285000001000000FFFFFFFFFFFFFFFFFFFEFF0A5200650066006500720065006E00630065007300000000001385000001000000FFFFFFFFFFFFFFFFFFFEFF0D460069006E006400200069006E002000460069006C0065007300000000001485000001000000FFFFFFFFFFFFFFFFFFFEFF1541006D0062006900670075006F0075007300200044006500660069006E006900740069006F006E007300000000003685000001000000FFFFFFFFFFFFFFFFFFFEFF0B54006F006F006C0020004F0075007400700075007400000000004285000001000000FFFFFFFFFFFFFFFF02000000000000000000000000000000000000000000000001000000FFFFFFFF0585000001000000FFFFFFFF05850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100000004000000010000000000000000000000048500000000000000000000000000000000000001000000048500000100000004850000000000000040000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000200000004000000010000000000000000000000038500000000000000000000000000000000000001000000038500000100000003850000000000000080000000000000FFFFFFFFFFFFFFFF00000000000000000400000004000000000000000100001004000000010000000000000000000000508500000000000000000000000000000000000001000000508500000100000050850000000000000080000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000001000010040000000100000000000000000000004F85000000000000000000000000000000000000010000004F850000010000004F850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000010040000000100000000000000000000004E85000000000000000000000000000000000000010000004E850000010000004E850000000000000040000000000000FFFFFFFFFFFFFFFF000000000000000004000000040000000000000002000010040000000100000000000000000000004D85000000000000000000000000000000000000010000004D850000010000004D850000000000000000000000000000 + + + CMSIS-Pack + 00200000010000000200FFFF01001100434D4643546F6F6C426172427574746F6ED0840000000004001C000000FFFEFF0000000000000000000000000001000000010000000180D1840000000000001E000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF0A43004D005300490053002D005000610063006B002F000000 + + + 34048 + 0A0000000A0000006E0000006E000000 + F10300001A0000003604000034000000 + 8192 + 1 + 0 + 47 + 0 + + + 1 + + + Debug + 00200000010000000800FFFF01001100434D4643546F6F6C426172427574746F6E568600000000000033000000FFFEFF000000000000000000000000000100000001000000018013860000000000002F000000FFFEFF00000000000000000000000000010000000100000001805E8600000000000035000000FFFEFF0000000000000000000000000001000000010000000180608600000000000037000000FFFEFF00000000000000000000000000010000000100000001805D8600000000000034000000FFFEFF000000000000000000000000000100000001000000018010860000000000002D000000FFFEFF000000000000000000000000000100000001000000018011860000000004002E000000FFFEFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E148600000000000030000000FFFEFF205200650073006500740020007400680065002000640065006200750067006700650064002000700072006F006700720061006D000A00520065007300650074000000000000000000000000000100000001000000000000000000000001000000020009800000000000000400FFFFFFFFFFFEFF000000000000000000000000000100000001000000000000000000000001000000000009801986000000000000FFFFFFFFFFFEFF000100000000000000000000000100000001000000000000000000000001000000000000000000FFFEFF0544006500620075006700C6000000 + + + 34049 + 0A0000000A0000006E0000006E000000 + 150300001A000000F103000034000000 + 8192 + 1 + 0 + 198 + 0 + + + 1 + + + Main + 00200000010000002100FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000065000000FFFEFF000000000000000000000000000100000001000000018001E100000000000066000000FFFEFF000000000000000000000000000100000001000000018003E100000000040068000000FFFEFF0000000000000000000000000001000000010000000180008100000000000049000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000004006B000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E10000000004006D000000FFFEFF000000000000000000000000000100000001000000018022E10000000004006C000000FFFEFF000000000000000000000000000100000001000000018025E10000000004006F000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000040072000000FFFEFF00000000000000000000000000010000000100000001802CE100000000040073000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6E4281000000000400FFFFFFFFFFFEFF0001000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF0096000000000000000000018021810000000004005C000000FFFEFF000000000000000000000000000100000001000000018024E10000000004006E000000FFFEFF000000000000000000000000000100000001000000018028E100000000040070000000FFFEFF000000000000000000000000000100000001000000018029E100000000040071000000FFFEFF000000000000000000000000000100000001000000018002810000000004004B000000FFFEFF0000000000000000000000000001000000010000000180298100000000040060000000FFFEFF000000000000000000000000000100000001000000018027810000000004005E000000FFFEFF000000000000000000000000000100000001000000018028810000000004005F000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040058000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040059000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000000004004F000000FFFEFF00000000000000000000000000010000000100000001800C8100000000000050000000FFFEFF00000000000000000000000000010000000100000001805F8600000000000064000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001801F810000000000005A000000FFFEFF000000000000000000000000000100000001000000018020810000000000005B000000FFFEFF0000000000000000000000000001000000010000000180468100000000000062000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00FF020000 + + + 34050 + 0A0000000A0000006E0000006E000000 + 00000000180000001503000032000000 + 8192 + 1 + 0 + 767 + 0 + + + 1 + + + + 57600 + 57601 + 57603 + 33024 + 0 + 57607 + 0 + 57635 + 57634 + 57637 + 0 + 57643 + 57644 + 0 + 33090 + 33057 + 57636 + 57640 + 57641 + 33026 + 33065 + 33063 + 33064 + 33053 + 33054 + 0 + 33035 + 33036 + 34399 + 0 + 33055 + 33056 + 33094 + 0 + + + + 34125 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34126 + 00000000170000000601000078010000 + 00000000000000000601000061010000 + 16384 + 0 + 0 + 32767 + 0 + + + 0 + + + + 34127 + 000000001700000022010000C8000000 + 000000000000000022010000B1000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + 34128 + 000000001700000080020000A8000000 + 00000000000000008002000091000000 + 32768 + 0 + 0 + 32767 + 0 + + + 0 + + + Main + 00200000010000002100FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000064000000FFFEFF000000000000000000000000000100000001000000018001E100000000000065000000FFFEFF000000000000000000000000000100000001000000018003E100000000000067000000FFFEFF0000000000000000000000000001000000010000000180008100000000000048000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018007E10000000000006A000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000018023E10000000004006C000000FFFEFF000000000000000000000000000100000001000000018022E10000000004006B000000FFFEFF000000000000000000000000000100000001000000018025E10000000000006E000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001802BE100000000040071000000FFFEFF00000000000000000000000000010000000100000001802CE100000000040072000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF000000000000000000000000000100000001000000FFFF01000D005061737465436F6D626F426F784281000000000000FFFFFFFFFFFEFF0000000000000000000100000000000000010000007800000002002050FFFFFFFFFFFEFF0096000000000000000000018021810000000004005B000000FFFEFF000000000000000000000000000100000001000000018024E10000000000006D000000FFFEFF000000000000000000000000000100000001000000018028E10000000004006F000000FFFEFF000000000000000000000000000100000001000000018029E100000000000070000000FFFEFF000000000000000000000000000100000001000000018002810000000000004A000000FFFEFF000000000000000000000000000100000001000000018029810000000000005F000000FFFEFF000000000000000000000000000100000001000000018027810000000000005D000000FFFEFF000000000000000000000000000100000001000000018028810000000000005E000000FFFEFF00000000000000000000000000010000000100000001801D8100000000040057000000FFFEFF00000000000000000000000000010000000100000001801E8100000000040058000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001800B810000000004004E000000FFFEFF00000000000000000000000000010000000100000001800C810000000000004F000000FFFEFF00000000000000000000000000010000000100000001805F8600000000000063000000FFFEFF00000000000000000000000000010000000100000001800000000001000000FFFFFFFFFFFEFF00000000000000000000000000010000000100000001801F8100000000000059000000FFFEFF000000000000000000000000000100000001000000018020810000000000005A000000FFFEFF0000000000000000000000000001000000010000000180468100000000020061000000FFFEFF00000000000000000000000000010000000100000000000000FFFEFF044D00610069006E00FF7F0000 + + + 34124 + 0A0000000A0000006E0000006E000000 + 0000000000000000150300001A000000 + 8192 + 0 + 0 + 32767 + 0 + + + 1 + + + + diff --git a/ports/arm11/iar/example_build/settings/sample_threadx.dnx b/ports/arm11/iar/example_build/settings/sample_threadx.dnx new file mode 100644 index 000000000..1e3115dfa --- /dev/null +++ b/ports/arm11/iar/example_build/settings/sample_threadx.dnx @@ -0,0 +1,99 @@ + + + + 0 + 1 + 90 + 1 + 1 + 1 + main + 0 + 50 + + + 0 + 1 + + + 1018058853 + + + 0 + 0 + 0 + + + 0 + + + _ 0 + _ 0 + + + 0 + + + 0 + 1 + 0 + 0 + + + 0 + + + 1 + + + _ 0 + _ "" + + + _ 0 + _ "" + _ 0 + + + 0 + 0 + 1 + 0 + 1 + 0 + + + 0 + 0 + 1 + 0 + 1 + + + 0 + + + 0 + + + 1 + _ 0 9999 0 9999 1 0 0 100 0 1 "IRQ 1 0x18 CPSR.I" + 1 + + + 1 + 0 + 1 + 0 + 1 + + + 0 + 0 + + + 10000000 + 0 + 1 + + diff --git a/ports/arm11/iar/example_build/settings/tx.Debug.cspy.bat b/ports/arm11/iar/example_build/settings/tx.Debug.cspy.bat new file mode 100644 index 000000000..256ebf4d7 --- /dev/null +++ b/ports/arm11/iar/example_build/settings/tx.Debug.cspy.bat @@ -0,0 +1,40 @@ +@REM This batch file has been generated by the IAR Embedded Workbench +@REM C-SPY Debugger, as an aid to preparing a command line for running +@REM the cspybat command line utility using the appropriate settings. +@REM +@REM Note that this file is generated every time a new debug session +@REM is initialized, so you may want to move or rename the file before +@REM making changes. +@REM +@REM You can launch cspybat by typing the name of this batch file followed +@REM by the name of the debug file (usually an ELF/DWARF or UBROF file). +@REM +@REM Read about available command line parameters in the C-SPY Debugging +@REM Guide. Hints about additional command line parameters that may be +@REM useful in specific cases: +@REM --download_only Downloads a code image without starting a debug +@REM session afterwards. +@REM --silent Omits the sign-on message. +@REM --timeout Limits the maximum allowed execution time. +@REM + + +@echo off + +if not "%~1" == "" goto debugFile + +@echo on + +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl" + +@echo off +goto end + +:debugFile + +@echo on + +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" "--debug_file=%~1" --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl" + +@echo off +:end \ No newline at end of file diff --git a/ports/arm11/iar/example_build/settings/tx.Debug.cspy.ps1 b/ports/arm11/iar/example_build/settings/tx.Debug.cspy.ps1 new file mode 100644 index 000000000..6a1889c02 --- /dev/null +++ b/ports/arm11/iar/example_build/settings/tx.Debug.cspy.ps1 @@ -0,0 +1,31 @@ +param([String]$debugfile = ""); + +# This powershell file has been generated by the IAR Embedded Workbench +# C - SPY Debugger, as an aid to preparing a command line for running +# the cspybat command line utility using the appropriate settings. +# +# Note that this file is generated every time a new debug session +# is initialized, so you may want to move or rename the file before +# making changes. +# +# You can launch cspybat by typing Powershell.exe -File followed by the name of this batch file, followed +# by the name of the debug file (usually an ELF / DWARF or UBROF file). +# +# Read about available command line parameters in the C - SPY Debugging +# Guide. Hints about additional command line parameters that may be +# useful in specific cases : +# --download_only Downloads a code image without starting a debug +# session afterwards. +# --silent Omits the sign - on message. +# --timeout Limits the maximum allowed execution time. +# + + +if ($debugfile -eq "") +{ +& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl" +} +else +{ +& "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\common\bin\cspybat" -f "C:\release\threadx\settings\tx.Debug.general.xcl" --debug_file=$debugfile --backend -f "C:\release\threadx\settings\tx.Debug.driver.xcl" +} diff --git a/ports/arm11/iar/example_build/settings/tx.Debug.driver.xcl b/ports/arm11/iar/example_build/settings/tx.Debug.driver.xcl new file mode 100644 index 000000000..06e18c00f --- /dev/null +++ b/ports/arm11/iar/example_build/settings/tx.Debug.driver.xcl @@ -0,0 +1,13 @@ +"--endian=little" + +"--cpu=ARM1136J-S" + +"--fpu=None" + +"--semihosting" + +"--multicore_nr_of_cores=1" + + + + diff --git a/ports/arm11/iar/example_build/settings/tx.Debug.general.xcl b/ports/arm11/iar/example_build/settings/tx.Debug.general.xcl new file mode 100644 index 000000000..deeeb2f9b --- /dev/null +++ b/ports/arm11/iar/example_build/settings/tx.Debug.general.xcl @@ -0,0 +1,11 @@ +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\arm\bin\armproc.dll" + +"C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\arm\bin\armsim2.dll" + +"C:\release\threadx\Debug\Exe\tx.out" + +--plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.0_2\arm\bin\armbat.dll" + + + + diff --git a/ports/arm11/iar/example_build/settings/tx.crun b/ports/arm11/iar/example_build/settings/tx.crun new file mode 100644 index 000000000..d71ea555a --- /dev/null +++ b/ports/arm11/iar/example_build/settings/tx.crun @@ -0,0 +1,13 @@ + + + 1 + + + * + * + * + 0 + 1 + + + diff --git a/ports/arm11/iar/example_build/settings/tx.dbgdt b/ports/arm11/iar/example_build/settings/tx.dbgdt new file mode 100644 index 000000000..73e71f6e4 --- /dev/null +++ b/ports/arm11/iar/example_build/settings/tx.dbgdt @@ -0,0 +1,4 @@ + + + + diff --git a/ports/arm11/iar/example_build/settings/tx.dnx b/ports/arm11/iar/example_build/settings/tx.dnx new file mode 100644 index 000000000..1872e83f7 --- /dev/null +++ b/ports/arm11/iar/example_build/settings/tx.dnx @@ -0,0 +1,58 @@ + + + + 0 + 0 + 1 + 0 + 1 + 0 + + + 0 + 0 + 1 + 0 + 1 + + + 0 + 1 + 90 + 1 + 1 + 1 + main + 0 + 50 + + + 0 + + + 0 + + + 1 + + + 1 + 0 + 1 + 0 + 1 + + + 0 + 1 + + + 0 + 0 + + + 10000000 + 0 + 1 + + diff --git a/ports/arm11/iar/example_build/tx.ewd b/ports/arm11/iar/example_build/tx.ewd new file mode 100644 index 000000000..c9ab09582 --- /dev/null +++ b/ports/arm11/iar/example_build/tx.ewd @@ -0,0 +1,2974 @@ + + + 3 + + Debug + + ARM + + 1 + + C-SPY + 2 + + 32 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 1 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 1 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 1 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 1 + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 1 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 1 + + + + + + + + STLINK_ID + 2 + + 7 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 1 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 8 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\HWRTOSplugin\HWRTOSplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\RemedyRtosViewer\RemedyRtosViewer.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8b.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8bBE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + + Release + + ARM + + 0 + + C-SPY + 2 + + 32 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ARMSIM_ID + 2 + + 1 + 1 + 0 + + + + + + + + CADI_ID + 2 + + 0 + 1 + 0 + + + + + + + + + CMSISDAP_ID + 2 + + 4 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GDBSERVER_ID + 2 + + 0 + 1 + 0 + + + + + + + + + + + IJET_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JLINK_ID + 2 + + 16 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LMIFTDI_ID + 2 + + 2 + 1 + 0 + + + + + + + + + + NULINK_ID + 2 + + 0 + 1 + 0 + + + + + + + PEMICRO_ID + 2 + + 3 + 1 + 0 + + + + + + + + STLINK_ID + 2 + + 7 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIRDPARTY_ID + 2 + + 0 + 1 + 0 + + + + + + + + TIFET_ID + 2 + + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + XDS100_ID + 2 + + 8 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\CMX\CmxTinyArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\FreeRtos\FreeRtosArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\HWRTOSplugin\HWRTOSplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\Mbed\MbedArmPlugin2.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\OpenRTOS\OpenRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\RemedyRtosViewer\RemedyRtosViewer.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SafeRTOS\SafeRTOSPlugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8b.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\SMX\smxAwareIarArm8bBE.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\ThreadX\ThreadXArmPlugin.ENU.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\TI-RTOS\tirtosplugin.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-286-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-II\uCOS-II-KA-CSpy.ewplugin + 0 + + + $TOOLKIT_DIR$\plugins\rtos\uCOS-III\uCOS-III-KA-CSpy.ewplugin + 0 + + + $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\TargetAccessServer\TargetAccessServer.ENU.ewplugin + 0 + + + $EW_DIR$\common\plugins\uCProbe\uCProbePlugin.ENU.ewplugin + 0 + + + + diff --git a/ports/arm11/iar/example_build/tx.ewp b/ports/arm11/iar/example_build/tx.ewp new file mode 100644 index 000000000..70a97e4f7 --- /dev/null +++ b/ports/arm11/iar/example_build/tx.ewp @@ -0,0 +1,2766 @@ + + + 3 + + Debug + + ARM + + 1 + + General + 3 + + 31 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 36 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 1 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 1 + + + + + + + BILINK + 0 + + + + + Release + + ARM + + 0 + + General + 3 + + 31 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ICCARM + 2 + + 36 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AARM + 2 + + 10 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OBJCOPY + 0 + + 1 + 1 + 0 + + + + + + + + + CUSTOM + 3 + + + + 0 + + + + BICOMP + 0 + + + + BUILDACTION + 1 + + + + + + + ILINK + 0 + + 23 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IARCHIVE + 0 + + 0 + 1 + 0 + + + + + + + BILINK + 0 + + + + + inc + + $PROJ_DIR$\..\..\..\..\common\inc\tx_api.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_block_pool.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_byte_pool.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_event_flags.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_initialize.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_mutex.h + + + $PROJ_DIR$\..\inc\tx_port.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_queue.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_semaphore.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_thread.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_timer.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_trace.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_user_sample.h + + + + src + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_allocate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_release.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_allocate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_search.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_release.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_set.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_set_notify.c + + + $PROJ_DIR$\..\src\tx_iar.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_initialize_high_level.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_initialize_kernel_enter.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_initialize_kernel_setup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_misra.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_priority_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_flush.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_front_send.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_receive.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_send.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_send_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_ceiling_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_put_notify.c + + + $PROJ_DIR$\..\src\tx_thread_context_restore.s + + + $PROJ_DIR$\..\src\tx_thread_context_save.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_entry_exit_notify.c + + + $PROJ_DIR$\..\src\tx_thread_fiq_context_restore.s + + + $PROJ_DIR$\..\src\tx_thread_fiq_context_save.s + + + $PROJ_DIR$\..\src\tx_thread_fiq_nesting_end.s + + + $PROJ_DIR$\..\src\tx_thread_fiq_nesting_start.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_identify.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_initialize.c + + + $PROJ_DIR$\..\src\tx_thread_interrupt_control.s + + + $PROJ_DIR$\..\src\tx_thread_interrupt_disable.s + + + $PROJ_DIR$\..\src\tx_thread_interrupt_restore.s + + + $PROJ_DIR$\..\src\tx_thread_irq_nesting_end.s + + + $PROJ_DIR$\..\src\tx_thread_irq_nesting_start.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_preemption_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_priority_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_relinquish.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_reset.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_resume.c + + + $PROJ_DIR$\..\src\tx_thread_schedule.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_shell_entry.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_sleep.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_stack_analyze.c + + + $PROJ_DIR$\..\src\tx_thread_stack_build.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_stack_error_handler.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_stack_error_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_suspend.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_system_preempt_check.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_system_resume.c + + + $PROJ_DIR$\..\src\tx_thread_system_return.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_system_suspend.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_terminate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_time_slice.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_time_slice_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_timeout.c + + + $PROJ_DIR$\..\src\tx_thread_vectored_context_save.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_wait_abort.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_time_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_time_set.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_activate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_deactivate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_expiration_process.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_initialize.c + + + $PROJ_DIR$\..\src\tx_timer_interrupt.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_system_activate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_system_deactivate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_thread_entry.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_buffer_full_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_disable.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_enable.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_event_filter.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_event_unfilter.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_interrupt_control.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_isr_enter_insert.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_isr_exit_insert.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_object_register.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_object_unregister.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_user_event_insert.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_allocate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_pool_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_pool_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_pool_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_pool_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_release.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_allocate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_pool_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_pool_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_pool_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_pool_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_release.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_set.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_set_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_flush.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_front_send.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_receive.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_send.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_send_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_ceiling_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_put_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_entry_exit_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_preemption_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_priority_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_relinquish.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_reset.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_resume.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_suspend.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_terminate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_time_slice_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_wait_abort.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_activate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_deactivate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_info_get.c + + + diff --git a/ports/arm11/iar/example_build/tx.ewt b/ports/arm11/iar/example_build/tx.ewt new file mode 100644 index 000000000..6a5e1f91c --- /dev/null +++ b/ports/arm11/iar/example_build/tx.ewt @@ -0,0 +1,3427 @@ + + + 3 + + Debug + + ARM + + 1 + + C-STAT + 263 + + 263 + + 0 + + 1 + 600 + 0 + 2 + 0 + 1 + 100 + + + 1.7.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuntimeChecking + 0 + + 2 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + Release + + ARM + + 0 + + C-STAT + 263 + + 263 + + 0 + + 1 + 600 + 0 + 2 + 0 + 1 + 100 + + + 1.7.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuntimeChecking + 0 + + 2 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + inc + + $PROJ_DIR$\..\..\..\..\common\inc\tx_api.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_block_pool.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_byte_pool.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_event_flags.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_initialize.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_mutex.h + + + $PROJ_DIR$\..\inc\tx_port.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_queue.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_semaphore.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_thread.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_timer.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_trace.h + + + $PROJ_DIR$\..\..\..\..\common\inc\tx_user_sample.h + + + + src + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_allocate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_pool_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_block_release.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_allocate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_pool_search.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_byte_release.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_set.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_event_flags_set_notify.c + + + $PROJ_DIR$\..\src\tx_iar.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_initialize_high_level.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_initialize_kernel_enter.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_initialize_kernel_setup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_misra.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_priority_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_mutex_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_flush.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_front_send.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_receive.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_send.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_queue_send_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_ceiling_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_cleanup.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_semaphore_put_notify.c + + + $PROJ_DIR$\..\src\tx_thread_context_restore.s + + + $PROJ_DIR$\..\src\tx_thread_context_save.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_entry_exit_notify.c + + + $PROJ_DIR$\..\src\tx_thread_fiq_context_restore.s + + + $PROJ_DIR$\..\src\tx_thread_fiq_context_save.s + + + $PROJ_DIR$\..\src\tx_thread_fiq_nesting_end.s + + + $PROJ_DIR$\..\src\tx_thread_fiq_nesting_start.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_identify.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_initialize.c + + + $PROJ_DIR$\..\src\tx_thread_interrupt_control.s + + + $PROJ_DIR$\..\src\tx_thread_interrupt_disable.s + + + $PROJ_DIR$\..\src\tx_thread_interrupt_restore.s + + + $PROJ_DIR$\..\src\tx_thread_irq_nesting_end.s + + + $PROJ_DIR$\..\src\tx_thread_irq_nesting_start.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_preemption_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_priority_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_relinquish.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_reset.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_resume.c + + + $PROJ_DIR$\..\src\tx_thread_schedule.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_shell_entry.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_sleep.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_stack_analyze.c + + + $PROJ_DIR$\..\src\tx_thread_stack_build.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_stack_error_handler.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_stack_error_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_suspend.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_system_preempt_check.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_system_resume.c + + + $PROJ_DIR$\..\src\tx_thread_system_return.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_system_suspend.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_terminate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_time_slice.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_time_slice_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_timeout.c + + + $PROJ_DIR$\..\src\tx_thread_vectored_context_save.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_thread_wait_abort.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_time_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_time_set.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_activate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_deactivate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_expiration_process.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_initialize.c + + + $PROJ_DIR$\..\src\tx_timer_interrupt.s + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_performance_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_performance_system_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_system_activate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_system_deactivate.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_timer_thread_entry.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_buffer_full_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_disable.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_enable.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_event_filter.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_event_unfilter.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_initialize.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_interrupt_control.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_isr_enter_insert.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_isr_exit_insert.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_object_register.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_object_unregister.c + + + $PROJ_DIR$\..\..\..\..\common\src\tx_trace_user_event_insert.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_allocate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_pool_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_pool_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_pool_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_pool_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_block_release.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_allocate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_pool_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_pool_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_pool_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_pool_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_byte_release.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_set.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_event_flags_set_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_mutex_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_flush.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_front_send.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_receive.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_send.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_queue_send_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_ceiling_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_prioritize.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_put.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_semaphore_put_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_entry_exit_notify.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_info_get.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_preemption_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_priority_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_relinquish.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_reset.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_resume.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_suspend.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_terminate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_time_slice_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_thread_wait_abort.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_activate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_change.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_create.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_deactivate.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_delete.c + + + $PROJ_DIR$\..\..\..\..\common\src\txe_timer_info_get.c + + + diff --git a/ports/arm11/iar/example_build/tx_initialize_low_level.s b/ports/arm11/iar/example_build/tx_initialize_low_level.s new file mode 100644 index 000000000..1ff234c92 --- /dev/null +++ b/ports/arm11/iar/example_build/tx_initialize_low_level.s @@ -0,0 +1,339 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Initialize */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_initialize.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +SVC_MODE DEFINE 0xD3 ; Disable irq,fiq SVC mode +IRQ_MODE DEFINE 0xD2 ; Disable irq,fiq IRQ mode +FIQ_MODE DEFINE 0xD1 ; Disable irq,fiq FIQ mode +SYS_MODE DEFINE 0xDF ; Disable irq,fiq SYS mode +; +; + + EXTERN _tx_thread_system_stack_ptr + EXTERN _tx_initialize_unused_memory + EXTERN _tx_thread_context_save +; EXTERN _tx_thread_vectored_context_save + EXTERN _tx_thread_context_restore +#ifdef TX_ENABLE_FIQ_SUPPORT + EXTERN _tx_thread_fiq_context_save + EXTERN _tx_thread_fiq_context_restore +#endif +#ifdef TX_ENABLE_IRQ_NESTING + EXTERN _tx_thread_irq_nesting_start + EXTERN _tx_thread_irq_nesting_end +#endif +#ifdef TX_ENABLE_FIQ_NESTING + EXTERN _tx_thread_fiq_nesting_start + EXTERN _tx_thread_fiq_nesting_end +#endif + EXTERN _tx_timer_interrupt + EXTERN ?cstartup + EXTERN _tx_build_options + EXTERN _tx_version_id +; +; +; +;/* Define the FREE_MEM segment that will specify where free memory is +; defined. This must also be located in at the end of other RAM segments +; in the linker control file. The value of this segment is what is passed +; to tx_application_define. */ +; + RSEG FREE_MEM:DATA + PUBLIC __tx_free_memory_start +__tx_free_memory_start + DS32 4 +; +; +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_initialize_low_level ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for any low-level processor */ +;/* initialization, including setting up interrupt vectors, setting */ +;/* up a periodic timer interrupt source, saving the system stack */ +;/* pointer for use in ISR processing later, and finding the first */ +;/* available RAM memory address for tx_application_define. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* _tx_initialize_kernel_enter ThreadX entry function */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_initialize_low_level(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + CODE32 + PUBLIC _tx_initialize_low_level +_tx_initialize_low_level +; +; /****** NOTE ****** The IAR 4.11a and above releases call main in SYS mode. */ +; +; /* Remember the stack pointer, link register, and switch to SVC mode. */ +; + MOV r0, sp ; Remember the SP + MOV r1, lr ; Remember the LR + MOV r3, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_cxsf, r3 ; Switch to SVC mode + MOV sp, r0 ; Inherit the stack pointer setup by cstartup + MOV lr, r1 ; Inherit the link register +; +; /* Pickup the start of free memory. */ +; + LDR r0, =__tx_free_memory_start ; Get end of non-initialized RAM area +; +; /* Save the system stack pointer. */ +; _tx_thread_system_stack_ptr = (VOID_PTR) (sp); +; +; /* Save the first available memory address. */ +; _tx_initialize_unused_memory = (VOID_PTR) FREE_MEM; +; + LDR r2, =_tx_initialize_unused_memory ; Pickup unused memory ptr address + STR r0, [r2, #0] ; Save first free memory address +; +; /* Setup Timer for periodic interrupts. */ +; +; /* Done, return to caller. */ +; +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +;} +; +;/* Define shells for each of the interrupt vectors. */ +; + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_undefined +__tx_undefined + B __tx_undefined ; Undefined handler +; + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_swi_interrupt +__tx_swi_interrupt + B __tx_swi_interrupt ; Software interrupt handler +; + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_prefetch_handler +__tx_prefetch_handler + B __tx_prefetch_handler ; Prefetch exception handler +; + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_abort_handler +__tx_abort_handler + B __tx_abort_handler ; Abort exception handler +; + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_reserved_handler +__tx_reserved_handler + B __tx_reserved_handler ; Reserved exception handler +; + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_irq_handler + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_irq_processing_return +__tx_irq_handler +; +; /* Jump to context save to save system context. */ + B _tx_thread_context_save +__tx_irq_processing_return +; +; /* At this point execution is still in the IRQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. In +; addition, IRQ interrupts may be re-enabled - with certain restrictions - +; if nested IRQ interrupts are desired. Interrupts may be re-enabled over +; small code sequences where lr is saved before enabling interrupts and +; restored after interrupts are again disabled. */ +; +; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start +; from IRQ mode with interrupts disabled. This routine switches to the +; system mode and returns with IRQ interrupts enabled. +; +; NOTE: It is very important to ensure all IRQ interrupts are cleared +; prior to enabling nested IRQ interrupts. */ +#ifdef TX_ENABLE_IRQ_NESTING + BL _tx_thread_irq_nesting_start +#endif +; +; /* For debug purpose, execute the timer interrupt processing here. In +; a real system, some kind of status indication would have to be checked +; before the timer interrupt handler could be called. */ +; + BL _tx_timer_interrupt ; Timer interrupt handler +; +; /* Application IRQ handlers can be called here! */ +; +; /* If interrupt nesting was started earlier, the end of interrupt nesting +; service must be called before returning to _tx_thread_context_restore. +; This routine returns in processing in IRQ mode with interrupts disabled. */ +#ifdef TX_ENABLE_IRQ_NESTING + BL _tx_thread_irq_nesting_end +#endif +; +; /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore +; +; +; /* This is an example of a vectored IRQ handler. */ +; +; RSEG .text:CODE:NOROOT(2) +; PUBLIC __tx_example_vectored_irq_handler +;__tx_example_vectored_irq_handler +; +; /* Jump to context save to save system context. */ +; STMDB sp!, {r0-r3} ; Save some scratch registers +; MRS r0, SPSR ; Pickup saved SPSR +; SUB lr, lr, #4 ; Adjust point of interrupt +; STMDB sp!, {r0, r10, r12, lr} ; Store other registers +; BL _tx_thread_vectored_context_save +; +; /* At this point execution is still in the IRQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. In +; addition, IRQ interrupts may be re-enabled - with certain restrictions - +; if nested IRQ interrupts are desired. Interrupts may be re-enabled over +; small code sequences where lr is saved before enabling interrupts and +; restored after interrupts are again disabled. */ +; +; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start +; from IRQ mode with interrupts disabled. This routine switches to the +; system mode and returns with IRQ interrupts enabled. +; +; NOTE: It is very important to ensure all IRQ interrupts are cleared +; prior to enabling nested IRQ interrupts. */ +;#ifdef TX_ENABLE_IRQ_NESTING +; BL _tx_thread_irq_nesting_start +;#endif +; +; /* Application IRQ handler is called here! */ +; +; /* If interrupt nesting was started earlier, the end of interrupt nesting +; service must be called before returning to _tx_thread_context_restore. +; This routine returns in processing in IRQ mode with interrupts disabled. */ +;#ifdef TX_ENABLE_IRQ_NESTING +; BL _tx_thread_irq_nesting_end +;#endif +; +; /* Jump to context restore to restore system context. */ +; B _tx_thread_context_restore +; +; +#ifdef TX_ENABLE_FIQ_SUPPORT + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_fiq_handler + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_fiq_processing_return +__tx_fiq_handler +; +; /* Jump to fiq context save to save system context. */ + B _tx_thread_fiq_context_save +__tx_fiq_processing_return +; +; /* At this point execution is still in the FIQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. */ +; +; /* Interrupt nesting is allowed after calling _tx_thread_fiq_nesting_start +; from FIQ mode with interrupts disabled. This routine switches to the +; system mode and returns with FIQ interrupts enabled. +; +; NOTE: It is very important to ensure all FIQ interrupts are cleared +; prior to enabling nested FIQ interrupts. */ +#ifdef TX_ENABLE_FIQ_NESTING + BL _tx_thread_fiq_nesting_start +#endif +; +; /* Application FIQ handlers can be called here! */ +; +; /* If interrupt nesting was started earlier, the end of interrupt nesting +; service must be called before returning to _tx_thread_fiq_context_restore. */ +#ifdef TX_ENABLE_FIQ_NESTING + BL _tx_thread_fiq_nesting_end +#endif +; +; /* Jump to fiq context restore to restore system context. */ + B _tx_thread_fiq_context_restore +; +; +#else + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_fiq_handler +__tx_fiq_handler + B __tx_fiq_handler ; FIQ interrupt handler +#endif +; +; +BUILD_OPTIONS + DC32 _tx_build_options ; Reference to ensure it comes in +VERSION_ID + DC32 _tx_version_id ; Reference to ensure it comes in + END + diff --git a/ports/arm11/iar/inc/tx_port.h b/ports/arm11/iar/inc/tx_port.h new file mode 100644 index 000000000..9a305c69b --- /dev/null +++ b/ports/arm11/iar/inc/tx_port.h @@ -0,0 +1,401 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 1996-2018 by Express Logic Inc. */ +/* */ +/* This software is copyrighted by and is the sole property of Express */ +/* Logic, Inc. All rights, title, ownership, or other interests */ +/* in the software remain the property of Express Logic, Inc. This */ +/* software may only be used in accordance with the corresponding */ +/* license agreement. Any unauthorized use, duplication, transmission, */ +/* distribution, or disclosure of this software is expressly forbidden. */ +/* */ +/* This Copyright notice may not be removed or modified without prior */ +/* written consent of Express Logic, Inc. */ +/* */ +/* Express Logic, Inc. reserves the right to modify this software */ +/* without notice. */ +/* */ +/* Express Logic, Inc. info@expresslogic.com */ +/* 11423 West Bernardo Court http://www.expresslogic.com */ +/* San Diego, CA 92127 */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Port Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_port.h ARM11/IAR */ +/* 6.0.1 */ +/* */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Express Logic, Inc. */ +/* */ +/* DESCRIPTION */ +/* */ +/* This file contains data type definitions that make the ThreadX */ +/* real-time kernel function identically on a variety of different */ +/* processor architectures. For example, the size or number of bits */ +/* in an "int" data type vary between microprocessor architectures and */ +/* even C compilers for the same microprocessor. ThreadX does not */ +/* directly use native C data types. Instead, ThreadX creates its */ +/* own special types that can be mapped to actual data types by this */ +/* file to guarantee consistency in the interface and functionality. */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 06-30-2020 William E. Lamie Initial ARM11 IAR */ +/* Support Version 6.0.1 */ +/* */ +/**************************************************************************/ + +#ifndef TX_PORT_H +#define TX_PORT_H + + +/* Determine if the optional ThreadX user define file should be used. */ + +#ifdef TX_INCLUDE_USER_DEFINE_FILE + + +/* Yes, include the user defines in tx_user.h. The defines in this file may + alternately be defined on the command line. */ + +#include "tx_user.h" +#endif + + +/* Define compiler library include files. */ + +#include +#include +#include +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif + + +/* Define ThreadX basic types for this port. */ + +#define VOID void +typedef char CHAR; +typedef unsigned char UCHAR; +typedef int INT; +typedef unsigned int UINT; +typedef long LONG; +typedef unsigned long ULONG; +typedef short SHORT; +typedef unsigned short USHORT; + + +/* Define the priority levels for ThreadX. Legal values range + from 32 to 1024 and MUST be evenly divisible by 32. */ + +#ifndef TX_MAX_PRIORITIES +#define TX_MAX_PRIORITIES 32 +#endif + + +/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during + thread creation is less than this value, the thread create call will return an error. */ + +#ifndef TX_MINIMUM_STACK +#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */ +#endif + + +/* Define the system timer thread's default stack size and priority. These are only applicable + if TX_TIMER_PROCESS_IN_ISR is not defined. */ + +#ifndef TX_TIMER_THREAD_STACK_SIZE +#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ +#endif + +#ifndef TX_TIMER_THREAD_PRIORITY +#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ +#endif + + +/* Define various constants for the ThreadX ARM port. */ + +#ifdef TX_ENABLE_FIQ_SUPPORT +#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */ +#else +#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */ +#endif +#define TX_INT_ENABLE 0x00 /* Enable IRQ interrupts */ + + +/* Define the clock source for trace event entry time stamp. The following two item are port specific. + For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock + source constants would be: + +#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024) +#define TX_TRACE_TIME_MASK 0x0000FFFFUL + +*/ + +#ifndef TX_MISRA_ENABLE +#ifndef TX_TRACE_TIME_SOURCE +#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time +#endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + +#ifndef TX_TRACE_TIME_MASK +#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL +#endif + + +/* Define the port specific options for the _tx_build_options variable. This variable indicates + how the ThreadX library was built. */ + +#ifdef TX_ENABLE_FIQ_SUPPORT +#define TX_FIQ_ENABLED 1 +#else +#define TX_FIQ_ENABLED 0 +#endif + +#ifdef TX_ENABLE_IRQ_NESTING +#define TX_IRQ_NESTING_ENABLED 2 +#else +#define TX_IRQ_NESTING_ENABLED 0 +#endif + +#ifdef TX_ENABLE_FIQ_NESTING +#define TX_FIQ_NESTING_ENABLED 4 +#else +#define TX_FIQ_NESTING_ENABLED 0 +#endif + +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED) + + +/* Define the in-line initialization constant so that modules with in-line + initialization capabilities can prevent their initialization from being + a function call. */ + +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else +#define TX_INLINE_INITIALIZATION +#endif + + +/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is + disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack + checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING + define is negated, thereby forcing the stack fill which is necessary for the stack checking + logic. */ + +#ifndef TX_MISRA_ENABLE +#ifdef TX_ENABLE_STACK_CHECKING +#undef TX_DISABLE_STACK_FILLING +#endif +#endif + + +/* Define the TX_THREAD control block extensions for this port. The main reason + for the multiple macros is so that backward compatibility can be maintained with + existing ThreadX kernel awareness modules. */ + +#define TX_THREAD_EXTENSION_0 +#define TX_THREAD_EXTENSION_1 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#else +#define TX_THREAD_EXTENSION_2 +#endif +#define TX_THREAD_EXTENSION_3 + + +/* Define the port extensions of the remaining ThreadX objects. */ + +#define TX_BLOCK_POOL_EXTENSION +#define TX_BYTE_POOL_EXTENSION +#define TX_EVENT_FLAGS_GROUP_EXTENSION +#define TX_MUTEX_EXTENSION +#define TX_QUEUE_EXTENSION +#define TX_SEMAPHORE_EXTENSION +#define TX_TIMER_EXTENSION + + +/* Define the user extension field of the thread control block. Nothing + additional is needed for this port so it is defined as white space. */ + +#ifndef TX_THREAD_USER_EXTENSION +#define TX_THREAD_USER_EXTENSION +#endif + + +/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete, + tx_thread_shell_entry, and tx_thread_terminate. */ + + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) + + +/* Define the ThreadX object creation extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr) +#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr) +#define TX_QUEUE_CREATE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr) +#define TX_TIMER_CREATE_EXTENSION(timer_ptr) + + +/* Define the ThreadX object deletion extensions for the remaining objects. */ + +#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr) +#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr) +#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr) +#define TX_QUEUE_DELETE_EXTENSION(queue_ptr) +#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr) +#define TX_TIMER_DELETE_EXTENSION(timer_ptr) + + +/* Determine if the ARM architecture has the CLZ instruction. This is available on + architectures v5 and above. If available, redefine the macro for calculating the + lowest bit set. */ + +#ifndef TX_DISABLE_INLINE + +#if __CORE__ > __ARM4TM__ + +#if __CPU_MODE__ == 2 + +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \ + b = (UINT) __CLZ(m); \ + b = 31 - b; +#endif +#endif +#endif + + +/* Define ThreadX interrupt lockout and restore macros for protection on + access of critical kernel information. The restore interrupt macro must + restore the interrupt posture of the running thread prior to the value + present prior to the disable macro. In most cases, the save area macro + is used to define a local function save area for the disable and restore + macros. */ + + +/* First, check and see what mode the file is being compiled in. The IAR compiler + defines __CPU_MODE__ to 1, if the Thumb mode is present, and 2 if ARM 32-bit mode + is present. If ARM 32-bit mode is present, the fast CPSR manipulation macros + are available. Otherwise, if Thumb mode is present, we must use function calls. */ + +#ifdef TX_DISABLE_INLINE + +UINT _tx_thread_interrupt_disable(void); +void _tx_thread_interrupt_restore(UINT old_posture); + + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); + +#else +#if __CPU_MODE__ == 2 + +#if (__VER__ < 8002000) +__intrinsic unsigned long __get_CPSR(); +__intrinsic void __set_CPSR( unsigned long ); +#endif + + +#if (__VER__ < 8002000) +#define TX_INTERRUPT_SAVE_AREA unsigned long interrupt_save; +#else +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; +#endif + +#define TX_DISABLE interrupt_save = __get_CPSR(); \ + __set_CPSR(interrupt_save | TX_INT_DISABLE); +#define TX_RESTORE __set_CPSR(interrupt_save); + +#else + +UINT _tx_thread_interrupt_disable(void); +void _tx_thread_interrupt_restore(UINT old_posture); + + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); + +#endif +#endif + + +/* Define the interrupt lockout macros for each ThreadX object. */ + +#define TX_BLOCK_POOL_DISABLE TX_DISABLE +#define TX_BYTE_POOL_DISABLE TX_DISABLE +#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE +#define TX_MUTEX_DISABLE TX_DISABLE +#define TX_QUEUE_DISABLE TX_DISABLE +#define TX_SEMAPHORE_DISABLE TX_DISABLE + + +/* Define the version ID of ThreadX. This may be utilized by the application. */ + +#ifdef TX_THREAD_INIT +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX ARM11/IAR Version 6.0.1 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; +#else +extern CHAR _tx_version_id[]; +#endif +#endif + + +#endif + + + diff --git a/ports/arm11/iar/readme_threadx.txt b/ports/arm11/iar/readme_threadx.txt new file mode 100644 index 000000000..d585f5171 --- /dev/null +++ b/ports/arm11/iar/readme_threadx.txt @@ -0,0 +1,527 @@ + Microsoft's Azure RTOS ThreadX for ARM11 + + Thumb & 32-bit Mode + + Using the IAR Tools + +1. Building the ThreadX run-time Library + +Building the ThreadX library is easy. First, open the Azure RTOS workspace +azure_rtos.eww. Next, make the TX project the "active project" in the +IAR Embedded Workbench and select the "Make" button. You should observe +assembly and compilation of a series of ThreadX source files. This +results in the ThreadX run-time library file tx.a, which is needed by +the application. + + +2. Demonstration System + +The ThreadX demonstration is designed to execute under the IAR +Windows-based ARM11 simulator. + +Building the demonstration is easy; simply make the sample_threadx.ewp project +the "active project" in the IAR Embedded Workbench and select the +"Make" button. + +You should observe the compilation of sample_threadx.c (which is the demonstration +application) and linking with tx.a. The resulting file sample_threadx.out is a +binary file that can be downloaded and executed on IAR's ARM11 simulator. + +A SPECIAL NOTE: The IAR ARM simulator does simulate interrupts. In order +for the ThreadX demonstration to run properly, a periodic IRQ interrupt must +be setup in the IAR debugging environment. We recommend setting an IRQ +interrupt to execute every 9999 cycles. + + +3. System Initialization + +The entry point in ThreadX for the ARM11 using IAR tools is at label +?cstartup. This is defined within the IAR compiler's startup code. In +addition, this is where all static and global preset C variable +initialization processing takes place. + +The ThreadX tx_initialize_low_level.s file is responsible for setting up +various system data structures, and a periodic timer interrupt source. +By default, the vector area is defined at the top of cstartup.s, which is +a slightly modified from the base IAR file. + +The _tx_initialize_low_level function inside of tx_initialize_low_level.s +also determines the first available address for use by the application, which +is supplied as the sole input parameter to your application definition function, +tx_application_define. To accomplish this, a section is created in +tx_initialize_low_level.s called FREE_MEM, which must be located after all +other RAM sections in memory. + + +4. Register Usage and Stack Frames + +The IAR ARM compiler assumes that registers r0-r3 (a1-a4) and r12 (ip) are +scratch registers for each function. All other registers used by a C function +must be preserved by the function. ThreadX takes advantage of this in +situations where a context switch happens as a result of making a ThreadX +service call (which is itself a C function). In such cases, the saved +context of a thread is only the non-scratch registers. + +The following defines the saved context stack frames for context switches +that occur as a result of interrupt handling or from thread-level API calls. +All suspended threads have one of these two types of stack frames. The top +of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the +associated thread control block TX_THREAD. + + + + Offset Interrupted Stack Frame Non-Interrupt Stack Frame + + 0x00 1 0 + 0x04 CPSR CPSR + 0x08 r0 (a1) r4 (v1) + 0x0C r1 (a2) r5 (v2) + 0x10 r2 (a3) r6 (v3) + 0x14 r3 (a4) r7 (v4) + 0x18 r4 (v1) r8 (v5) + 0x1C r5 (v2) r9 (v6) + 0x20 r6 (v3) r10 (v7) + 0x24 r7 (v4) r11 (fp) + 0x28 r8 (v5) r14 (lr) + 0x2C r9 (v6) + 0x30 r10 (v7) + 0x34 r11 (fp) + 0x38 r12 (ip) + 0x3C r14 (lr) + 0x40 PC + + +5. Conditional Compilation Switches + +The following are conditional compilation options for building the ThreadX library +and application: + + + TX_ENABLE_FIQ_SUPPORT This assembler/compiler define enables + FIQ interrupt handling support in the + ThreadX assembly files. If used, + it should be used on all assembly + files and the generic C source of + ThreadX should be compiled with + TX_ENABLE_FIQ_SUPPORT defined as well. + + TX_ENABLE_IRQ_NESTING This assembler define enables IRQ + nested support. If IRQ nested + interrupt support is needed, this + define should be applied to + tx_initialize_low_level.s. + + TX_ENABLE_FIQ_NESTING This assembler define enables FIQ + nested support. If FIQ nested + interrupt support is needed, this + define should be applied to + tx_initialize_low_level.s. In addition, + IRQ nesting should also be enabled. + + TX_DISABLE_ERROR_CHECKING If defined before tx_api.h is included, + this define causes basic ThreadX error + checking to be disabled. Please see + Chapter 2 in the "ThreadX User Guide" + for more details. + + TX_MAX_PRIORITIES Defines the priority levels for ThreadX. + Legal values range from 32 through + 1024 (inclusive) and MUST be evenly divisible + by 32. Increasing the number of priority levels + supported increases the RAM usage by 128 bytes + for every group of 32 priorities. However, there + is only a negligible effect on performance. By + default, this value is set to 32 priority levels. + + TX_MINIMUM_STACK Defines the minimum stack size (in bytes). It is + used for error checking when threads are created. + The default value is port-specific and is found + in tx_port.h. + + TX_TIMER_THREAD_STACK_SIZE Defines the stack size (in bytes) of the internal + ThreadX timer thread. This thread processes all + thread sleep requests as well as all service call + timeouts. In addition, all application timer callback + routines are invoked from this context. The default + value is port-specific and is found in tx_port.h. + + TX_TIMER_THREAD_PRIORITY Defines the priority of the internal ThreadX timer + thread. The default value is priority 0 - the highest + priority in ThreadX. The default value is defined + in tx_port.h. + + TX_TIMER_PROCESS_IN_ISR Defined, this option eliminates the internal system + timer thread for ThreadX. This results in improved + performance on timer events and smaller RAM requirements + because the timer stack and control block are no + longer needed. However, using this option moves all + the timer expiration processing to the timer ISR level. + By default, this option is not defined. + + TX_REACTIVATE_INLINE Defined, this option performs reactivation of ThreadX + timers in-line instead of using a function call. This + improves performance but slightly increases code size. + By default, this option is not defined. + + TX_DISABLE_STACK_FILLING Defined, placing the 0xEF value in each byte of each + thread's stack is disabled. By default, this option is + not defined. + + TX_ENABLE_STACK_CHECKING Defined, this option enables ThreadX run-time stack checking, + which includes analysis of how much stack has been used and + examination of data pattern "fences" before and after the + stack area. If a stack error is detected, the registered + application stack error handler is called. This option does + result in slightly increased overhead and code size. Please + review the tx_thread_stack_error_notify API for more information. + By default, this option is not defined. + + TX_DISABLE_PREEMPTION_THRESHOLD Defined, this option disables the preemption-threshold feature + and slightly reduces code size and improves performance. Of course, + the preemption-threshold capabilities are no longer available. + By default, this option is not defined. + + TX_DISABLE_REDUNDANT_CLEARING Defined, this option removes the logic for initializing ThreadX + global C data structures to zero. This should only be used if + the compiler's initialization code sets all un-initialized + C global data to zero. Using this option slightly reduces + code size and improves performance during initialization. + By default, this option is not defined. + + TX_DISABLE_NOTIFY_CALLBACKS Defined, this option disables the notify callbacks for various + ThreadX objects. Using this option slightly reduces code size + and improves performance. + + TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on block pools. By default, this option is + not defined. + + TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on byte pools. By default, this option is + not defined. + + TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on event flags groups. By default, this option + is not defined. + + TX_MUTEX_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on mutexes. By default, this option is + not defined. + + TX_QUEUE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on queues. By default, this option is + not defined. + + TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on semaphores. By default, this option is + not defined. + + TX_THREAD_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on threads. By default, this option is + not defined. + + TX_TIMER_ENABLE_PERFORMANCE_INFO Defined, this option enables the gathering of performance + information on timers. By default, this option is + not defined. + + TX_ENABLE_EVENT_TRACE Defined, this option enables the internal ThreadX trace + feature. The trace buffer is supplied at a later time + via an application call to tx_trace_enable. + + TX_TRACE_TIME_SOURCE This defines the time-stamp source for event tracing. + This define is only pertinent if the ThreadX library is + built with TX_ENABLE_EVENT_TRACE defined. + + TX_TRACE_TIME_MASK This defines the number of valid bits in the event trace + time-stamp source defined previously. If the time-stamp + source is 16-bits, this value should be 0xFFFF. Alternatively, + if the time-stamp source is 32-bits, this value should be + 0xFFFFFFFF. This define is only pertinent if the ThreadX + library is built with TX_ENABLE_EVENT_TRACE defined. + + TX_THUMB Defined, this option enables the BX LR calling return sequence + in assembly files, to ensure correct operation on systems that + use both ARM and Thumb mode. By default, this option is + not defined + + + + + +6. Improving Performance + +The distribution version of ThreadX is built without any compiler +optimizations. This makes it easy to debug because you can trace or set +breakpoints inside of ThreadX itself. Of course, this costs some +performance. To make it run faster, you can change the ThreadX library +project to enable various compiler optimizations. + +In addition, you can eliminate the ThreadX basic API error checking by +compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING +defined. + + +7. Interrupt Handling + +ThreadX provides complete and high-performance interrupt handling for ARM11 +targets. There are a certain set of requirements that are defined in the +following sub-sections: + + +7.1 Vector Area + +The ARM11 vectors start at address zero. The demonstration system startup +cstartup.s file contains the vectors and is loaded at address zero. +On actual hardware platforms, this area might have to be copied to address 0. + + +7.2 IRQ ISRs + +ThreadX fully manages standard and vectored IRQ interrupts. ThreadX also supports nested +IRQ interrupts. The following sub-sections define the IRQ capabilities. + + +7.2.1 Standard IRQ ISRs + +The standard ARM IRQ mechanism has a single interrupt vector at address 0x18. This IRQ +interrupt is managed by the __tx_irq_handler code in tx_initialize_low_level. The following +is the default IRQ handler defined in tx_initialize_low_level.s: + + PUBLIC __tx_irq_handler + PUBLIC __tx_irq_processing_return +__tx_irq_handler +; +; /* Jump to context save to save system context. */ + B _tx_thread_context_save +__tx_irq_processing_return +; +; /* At this point execution is still in the IRQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. Note +; that IRQ interrupts are still disabled upon return from the context +; save function. */ +; +; /* Application ISR dispatch call goes here! */ +; +; /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore + + +7.2.2 Vectored IRQ ISRs + +The vectored ARM IRQ mechanism has multiple interrupt vectors at addresses specified +by the particular implementation. The following is an example IRQ handler defined in +tx_initialize_low_level.s: + + + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_example_vectored_irq_handler +__tx_example_vectored_irq_handler +; +; /* Jump to context save to save system context. */ + STMDB sp!, {r0-r3} ; Save some scratch registers + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} ; Store other registers + BL _tx_thread_vectored_context_save +; +; /* At this point execution is still in the IRQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. Note +; that IRQ interrupts are still disabled upon return from the context +; save function. */ +; +; /* Application ISR dispatch call goes here! */ +; +; /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore + + +7.2.3 Nested IRQ Support + +By default, nested IRQ interrupt support is not enabled. To enable nested +IRQ support, the entire library should be built with TX_ENABLE_IRQ_NESTING +defined. With this defined, two new IRQ interrupt management services are +available, namely _tx_thread_irq_nesting_start and _tx_thread_irq_nesting_end. +These function should be called between the IRQ context save and restore +calls. + +Execution between the calls to _tx_thread_irq_nesting_start and +_tx_thread_irq_nesting_end is enabled for IRQ nesting. This is achieved +by switching from IRQ mode to SYS mode and enabling IRQ interrupts. +The SYS mode stack is used during the SYS mode operation, which was +setup in tx_initialize_low_level.s. When nested IRQ interrupts are no +longer required, calling the _tx_thread_irq_nesting_end service disables +nesting by disabling IRQ interrupts and switching back to IRQ mode in +preparation for the IRQ context restore service. + +The following is an example of enabling IRQ nested interrupts in a standard +IRQ handler: + + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_irq_handler + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_irq_processing_return +__tx_irq_handler +; +; /* Jump to context save to save system context. */ + B _tx_thread_context_save +__tx_irq_processing_return +; +; /* At this point execution is still in the IRQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. Note +; that IRQ interrupts are still disabled upon return from the context +; save function. */ +; +; /* Interrupt nesting is allowed after calling _tx_thread_irq_nesting_start +; from IRQ mode with interrupts disabled. This routine switches to the +; system mode and returns with IRQ interrupts enabled. +; +; NOTE: It is very important to ensure all IRQ interrupts are cleared +; prior to enabling nested IRQ interrupts. */ +; + BL _tx_thread_irq_nesting_start + +; /* Application ISR dispatch call goes here! */ +; +; /* If interrupt nesting was started earlier, the end of interrupt nesting +; service must be called before returning to _tx_thread_context_restore. +; This routine returns in processing in IRQ mode with interrupts disabled. */ +; + BL _tx_thread_irq_nesting_end +; +; /* Jump to context restore to restore system context. */ + B _tx_thread_context_restore + + +7.3 FIQ Interrupts + +By default, ARM11 FIQ interrupts are left alone by ThreadX. Of course, this +means that the application is fully responsible for enabling the FIQ interrupt +and saving/restoring any registers used in the FIQ ISR processing. To globally +enable FIQ interrupts, the application should enable FIQ interrupts at the +beginning of each thread or before any threads are created in tx_application_define. +In addition, the application must ensure that no ThreadX service calls are made +from default FIQ ISRs, which is located in tx_initialize_low_level.s. + + +7.3.1 Managed FIQ Interrupts + +Full ThreadX management of FIQ interrupts is provided if the ThreadX sources +are built with the TX_ENABLE_FIQ_SUPPORT defined. If the library is built +this way, the FIQ interrupt handlers are very similar to the IRQ interrupt +handlers defined previously. The following is default FIQ handler +defined in tx_initialize_low_level.s: + + + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_fiq_handler + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_fiq_processing_return +__tx_fiq_handler +; +; /* Jump to fiq context save to save system context. */ + B _tx_thread_fiq_context_save +__tx_fiq_processing_return: +; +; /* At this point execution is still in the FIQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. */ +; +; /* Application FIQ dispatch call goes here! */ +; +; /* Jump to fiq context restore to restore system context. */ + B _tx_thread_fiq_context_restore + + + +7.3.1.1 Nested FIQ Support + +By default, nested FIQ interrupt support is not enabled. To enable nested +FIQ support, the entire library should be built with TX_ENABLE_FIQ_NESTING +defined. With this defined, two new FIQ interrupt management services are +available, namely _tx_thread_fiq_nesting_start and _tx_thread_fiq_nesting_end. +These function should be called between the FIQ context save and restore +calls. + +Execution between the calls to _tx_thread_fiq_nesting_start and +_tx_thread_fiq_nesting_end is enabled for FIQ nesting. This is achieved +by switching from FIQ mode to SYS mode and enabling FIQ interrupts. +The SYS mode stack is used during the SYS mode operation, which was +setup in tx_initialize_low_level.s. When nested FIQ interrupts are no +longer required, calling the _tx_thread_fiq_nesting_end service disables +nesting by disabling FIQ interrupts and switching back to FIQ mode in +preparation for the FIQ context restore service. + +The following is an example of enabling FIQ nested interrupts in the +typical FIQ handler: + + + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_fiq_handler + RSEG .text:CODE:NOROOT(2) + PUBLIC __tx_fiq_processing_return +__tx_fiq_handler +; +; /* Jump to fiq context save to save system context. */ + B _tx_thread_fiq_context_save +__tx_fiq_processing_return: +; +; /* At this point execution is still in the FIQ mode. The CPSR, point of +; interrupt, and all C scratch registers are available for use. */ +; +; /* Enable nested FIQ interrupts. NOTE: Since this service returns +; with FIQ interrupts enabled, all FIQ interrupt sources must be +; cleared prior to calling this service. */ + BL _tx_thread_fiq_nesting_start +; +; /* Application FIQ dispatch call goes here! */ +; +; /* Disable nested FIQ interrupts. The mode is switched back to +; FIQ mode and FIQ interrupts are disable upon return. */ + BL _tx_thread_fiq_nesting_end +; +; /* Jump to fiq context restore to restore system context. */ + B _tx_thread_fiq_context_restore + + +8. ThreadX Timer Interrupt + +ThreadX requires a periodic interrupt source to manage all time-slicing, +thread sleeps, timeouts, and application timers. Without such a timer +interrupt source, these services are not functional. However, all other +ThreadX services are operational without a periodic timer source. + +To add the timer interrupt processing, simply make a call to _tx_timer_interrupt +in the IRQ processing. + + +9. Thumb/ARM11 Mixed Mode + +By default, ThreadX is setup for running in ARM11 32-bit mode. This is +also true for the demonstration system. It is possible to build any +ThreadX file and/or the application in Thumb mode. The only exception +to this is the file tx_thread_shell_entry.c. This file must always be +built in 32-bit mode. In addition, if any Thumb code is used the entire +ThreadX assembly source should be built with TX_THUMB defined. + + +10. IAR Thread-safe Library Support + +Thread-safe support for the IAR tools is easily enabled by building the ThreadX library +and the application with TX_ENABLE_IAR_LIBRARY_SUPPORT. Also, the linker control file +should have the following line added (if not already in place): + +initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application + +The project options "General Options -> Library Configuration" should also have the +"Enable thread support in library" box selected. + + +11. Revision History + +06/30/2020 Initial ThreadX 6.0.1 version for ARM11 using IAR's ARM tools. + + +Copyright(c) 1996-2020 Microsoft Corporation + + +https://azure.com/rtos + diff --git a/ports/arm11/iar/src/tx_iar.c b/ports/arm11/iar/src/tx_iar.c new file mode 100644 index 000000000..95592d4b0 --- /dev/null +++ b/ports/arm11/iar/src/tx_iar.c @@ -0,0 +1,816 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) 1996-2018 by Express Logic Inc. */ +/* */ +/* This software is copyrighted by and is the sole property of Express */ +/* Logic, Inc. All rights, title, ownership, or other interests */ +/* in the software remain the property of Express Logic, Inc. This */ +/* software may only be used in accordance with the corresponding */ +/* license agreement. Any unauthorized use, duplication, transmission, */ +/* distribution, or disclosure of this software is expressly forbidden. */ +/* */ +/* This Copyright notice may not be removed or modified without prior */ +/* written consent of Express Logic, Inc. */ +/* */ +/* Express Logic, Inc. reserves the right to modify this software */ +/* without notice. */ +/* */ +/* Express Logic, Inc. info@expresslogic.com */ +/* 11423 West Bernardo Court www.expresslogic.com */ +/* San Diego, CA 92127 */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** IAR Multithreaded Library Support */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define TX_SOURCE_CODE + + +/* Define IAR library for tools prior to version 8. */ + +#if (__VER__ < 8000000) + + +/* IAR version 7 and below. */ + +/* Include necessary system files. */ + +#include "tx_api.h" +#include "tx_initialize.h" +#include "tx_thread.h" +#include "tx_mutex.h" + + +/* This implementation requires that the following macros are defined in the + tx_port.h file and is included with the following code segments: + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#else +#define TX_THREAD_EXTENSION_2 +#endif + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif + + This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the + application. + + Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected. +*/ + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT + +#include + + +#if _MULTI_THREAD + +TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK]; +UINT __tx_iar_system_lock_next_free_mutex = 0; + + +/* Define error counters, just for debug purposes. */ + +UINT __tx_iar_system_lock_no_mutexes; +UINT __tx_iar_system_lock_internal_errors; +UINT __tx_iar_system_lock_isr_caller; + + +/* Define the TLS access function for the IAR library. */ + +void _DLIB_TLS_MEMORY *__iar_dlib_perthread_access(void _DLIB_TLS_MEMORY *symbp) +{ + +char _DLIB_TLS_MEMORY *p = 0; + + /* Is there a current thread? */ + if (_tx_thread_current_ptr) + p = (char _DLIB_TLS_MEMORY *) _tx_thread_current_ptr -> tx_thread_iar_tls_pointer; + else + p = (void _DLIB_TLS_MEMORY *) __segment_begin("__DLIB_PERTHREAD"); + p += __IAR_DLIB_PERTHREAD_SYMBOL_OFFSET(symbp); + return (void _DLIB_TLS_MEMORY *) p; +} + + +/* Define mutexes for IAR library. */ + +void __iar_system_Mtxinit(__iar_Rmtx *m) +{ + +UINT i; +UINT status; +TX_MUTEX *mutex_ptr; + + + /* First, find a free mutex in the list. */ + for (i = 0; i < _MAX_LOCK; i++) + { + + /* Setup a pointer to the start of the next free mutex. */ + mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++]; + + /* Check for wrap-around on the next free mutex. */ + if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK) + { + + /* Yes, set the free index back to 0. */ + __tx_iar_system_lock_next_free_mutex = 0; + } + + /* Is this mutex free? */ + if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID) + { + + /* Yes, this mutex is free, get out of the loop! */ + break; + } + } + + /* Determine if a free mutex was found. */ + if (i >= _MAX_LOCK) + { + + /* Error! No more free mutexes! */ + + /* Increment the no mutexes error counter. */ + __tx_iar_system_lock_no_mutexes++; + + /* Set return pointer to NULL. */ + *m = TX_NULL; + + /* Return. */ + return; + } + + /* Now create the ThreadX mutex for the IAR library. */ + status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT); + + /* Determine if the creation was successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, successful creation, return mutex pointer. */ + *m = (VOID *) mutex_ptr; + } + else + { + + /* Increment the internal error counter. */ + __tx_iar_system_lock_internal_errors++; + + /* Return a NULL pointer to indicate an error. */ + *m = TX_NULL; + } +} + +void __iar_system_Mtxdst(__iar_Rmtx *m) +{ + + /* Simply delete the mutex. */ + _tx_mutex_delete((TX_MUTEX *) *m); +} + +void __iar_system_Mtxlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex locks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Get the mutex. */ + status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_system_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_system_lock_isr_caller++; + } +} + +void __iar_system_Mtxunlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex unlocks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Release the mutex. */ + status = _tx_mutex_put((TX_MUTEX *) *m); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_system_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_system_lock_isr_caller++; + } +} + + +#if _DLIB_FILE_DESCRIPTOR + +TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK]; +UINT __tx_iar_file_lock_next_free_mutex = 0; + + +/* Define error counters, just for debug purposes. */ + +UINT __tx_iar_file_lock_no_mutexes; +UINT __tx_iar_file_lock_internal_errors; +UINT __tx_iar_file_lock_isr_caller; + + +void __iar_file_Mtxinit(__iar_Rmtx *m) +{ + +UINT i; +UINT status; +TX_MUTEX *mutex_ptr; + + + /* First, find a free mutex in the list. */ + for (i = 0; i < _MAX_FLOCK; i++) + { + + /* Setup a pointer to the start of the next free mutex. */ + mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; + + /* Check for wrap-around on the next free mutex. */ + if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + { + + /* Yes, set the free index back to 0. */ + __tx_iar_file_lock_next_free_mutex = 0; + } + + /* Is this mutex free? */ + if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID) + { + + /* Yes, this mutex is free, get out of the loop! */ + break; + } + } + + /* Determine if a free mutex was found. */ + if (i >= _MAX_LOCK) + { + + /* Error! No more free mutexes! */ + + /* Increment the no mutexes error counter. */ + __tx_iar_file_lock_no_mutexes++; + + /* Set return pointer to NULL. */ + *m = TX_NULL; + + /* Return. */ + return; + } + + /* Now create the ThreadX mutex for the IAR library. */ + status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT); + + /* Determine if the creation was successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, successful creation, return mutex pointer. */ + *m = (VOID *) mutex_ptr; + } + else + { + + /* Increment the internal error counter. */ + __tx_iar_file_lock_internal_errors++; + + /* Return a NULL pointer to indicate an error. */ + *m = TX_NULL; + } +} + +void __iar_file_Mtxdst(__iar_Rmtx *m) +{ + + /* Simply delete the mutex. */ + _tx_mutex_delete((TX_MUTEX *) *m); +} + +void __iar_file_Mtxlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex locks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Get the mutex. */ + status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_file_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_file_lock_isr_caller++; + } +} + +void __iar_file_Mtxunlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex unlocks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Release the mutex. */ + status = _tx_mutex_put((TX_MUTEX *) *m); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_file_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_file_lock_isr_caller++; + } +} +#endif /* _DLIB_FILE_DESCRIPTOR */ + +#endif /* _MULTI_THREAD */ + +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ + +#else /* IAR version 8 and above. */ + + +/* Include necessary system files. */ + +#include "tx_api.h" +#include "tx_initialize.h" +#include "tx_thread.h" +#include "tx_mutex.h" + +/* This implementation requires that the following macros are defined in the + tx_port.h file and is included with the following code segments: + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_iar_tls_pointer; +#else +#define TX_THREAD_EXTENSION_2 +#endif + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {__iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif + + This should be done automatically if TX_ENABLE_IAR_LIBRARY_SUPPORT is defined while building the ThreadX library and the + application. + + Finally, the project options General Options -> Library Configuration should have the "Enable thread support in library" box selected. +*/ + +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT + +#include + + +void * __aeabi_read_tp(); + +void* _tx_iar_create_per_thread_tls_area(); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); + +#pragma section="__iar_tls$$DATA" + +/* Define the TLS access function for the IAR library. */ +void * __aeabi_read_tp(void) +{ + void *p = 0; + TX_THREAD *thread_ptr = _tx_thread_current_ptr; + if (thread_ptr) + { + p = thread_ptr->tx_thread_iar_tls_pointer; + } + else + { + p = __section_begin("__iar_tls$$DATA"); + } + return p; +} + +/* Define the TLS creation and destruction to use malloc/free. */ + +void* _tx_iar_create_per_thread_tls_area() +{ + UINT tls_size = __iar_tls_size(); + + /* Get memory for TLS. */ + void *p = malloc(tls_size); + + /* Initialize TLS-area and run constructors for objects in TLS */ + __iar_tls_init(p); + return p; +} + +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr) +{ + /* Destroy objects living in TLS */ + __call_thread_dtors(); + free(tls_ptr); +} + +#ifndef _MAX_LOCK +#define _MAX_LOCK 4 +#endif + +static TX_MUTEX __tx_iar_system_lock_mutexes[_MAX_LOCK]; +static UINT __tx_iar_system_lock_next_free_mutex = 0; + + +/* Define error counters, just for debug purposes. */ + +UINT __tx_iar_system_lock_no_mutexes; +UINT __tx_iar_system_lock_internal_errors; +UINT __tx_iar_system_lock_isr_caller; + + +/* Define mutexes for IAR library. */ + +void __iar_system_Mtxinit(__iar_Rmtx *m) +{ + +UINT i; +UINT status; +TX_MUTEX *mutex_ptr; + + + /* First, find a free mutex in the list. */ + for (i = 0; i < _MAX_LOCK; i++) + { + + /* Setup a pointer to the start of the next free mutex. */ + mutex_ptr = &__tx_iar_system_lock_mutexes[__tx_iar_system_lock_next_free_mutex++]; + + /* Check for wrap-around on the next free mutex. */ + if (__tx_iar_system_lock_next_free_mutex >= _MAX_LOCK) + { + + /* Yes, set the free index back to 0. */ + __tx_iar_system_lock_next_free_mutex = 0; + } + + /* Is this mutex free? */ + if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID) + { + + /* Yes, this mutex is free, get out of the loop! */ + break; + } + } + + /* Determine if a free mutex was found. */ + if (i >= _MAX_LOCK) + { + + /* Error! No more free mutexes! */ + + /* Increment the no mutexes error counter. */ + __tx_iar_system_lock_no_mutexes++; + + /* Set return pointer to NULL. */ + *m = TX_NULL; + + /* Return. */ + return; + } + + /* Now create the ThreadX mutex for the IAR library. */ + status = _tx_mutex_create(mutex_ptr, "IAR System Library Lock", TX_NO_INHERIT); + + /* Determine if the creation was successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, successful creation, return mutex pointer. */ + *m = (VOID *) mutex_ptr; + } + else + { + + /* Increment the internal error counter. */ + __tx_iar_system_lock_internal_errors++; + + /* Return a NULL pointer to indicate an error. */ + *m = TX_NULL; + } +} + +void __iar_system_Mtxdst(__iar_Rmtx *m) +{ + + /* Simply delete the mutex. */ + _tx_mutex_delete((TX_MUTEX *) *m); +} + +void __iar_system_Mtxlock(__iar_Rmtx *m) +{ + if (*m) + { + UINT status; + + /* Determine the caller's context. Mutex locks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Get the mutex. */ + status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_system_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_system_lock_isr_caller++; + } + } +} + +void __iar_system_Mtxunlock(__iar_Rmtx *m) +{ + if (*m) + { + UINT status; + + /* Determine the caller's context. Mutex unlocks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Release the mutex. */ + status = _tx_mutex_put((TX_MUTEX *) *m); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_system_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_system_lock_isr_caller++; + } + } +} + + +#if _DLIB_FILE_DESCRIPTOR + +#include /* Added to get access to FOPEN_MAX */ +#ifndef _MAX_FLOCK +#define _MAX_FLOCK FOPEN_MAX /* Define _MAX_FLOCK as the maximum number of open files */ +#endif + + +TX_MUTEX __tx_iar_file_lock_mutexes[_MAX_FLOCK]; +UINT __tx_iar_file_lock_next_free_mutex = 0; + + +/* Define error counters, just for debug purposes. */ + +UINT __tx_iar_file_lock_no_mutexes; +UINT __tx_iar_file_lock_internal_errors; +UINT __tx_iar_file_lock_isr_caller; + + +void __iar_file_Mtxinit(__iar_Rmtx *m) +{ + +UINT i; +UINT status; +TX_MUTEX *mutex_ptr; + + + /* First, find a free mutex in the list. */ + for (i = 0; i < _MAX_FLOCK; i++) + { + + /* Setup a pointer to the start of the next free mutex. */ + mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; + + /* Check for wrap-around on the next free mutex. */ + if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + { + + /* Yes, set the free index back to 0. */ + __tx_iar_file_lock_next_free_mutex = 0; + } + + /* Is this mutex free? */ + if (mutex_ptr -> tx_mutex_id != TX_MUTEX_ID) + { + + /* Yes, this mutex is free, get out of the loop! */ + break; + } + } + + /* Determine if a free mutex was found. */ + if (i >= _MAX_LOCK) + { + + /* Error! No more free mutexes! */ + + /* Increment the no mutexes error counter. */ + __tx_iar_file_lock_no_mutexes++; + + /* Set return pointer to NULL. */ + *m = TX_NULL; + + /* Return. */ + return; + } + + /* Now create the ThreadX mutex for the IAR library. */ + status = _tx_mutex_create(mutex_ptr, "IAR File Library Lock", TX_NO_INHERIT); + + /* Determine if the creation was successful. */ + if (status == TX_SUCCESS) + { + + /* Yes, successful creation, return mutex pointer. */ + *m = (VOID *) mutex_ptr; + } + else + { + + /* Increment the internal error counter. */ + __tx_iar_file_lock_internal_errors++; + + /* Return a NULL pointer to indicate an error. */ + *m = TX_NULL; + } +} + +void __iar_file_Mtxdst(__iar_Rmtx *m) +{ + + /* Simply delete the mutex. */ + _tx_mutex_delete((TX_MUTEX *) *m); +} + +void __iar_file_Mtxlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex locks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Get the mutex. */ + status = _tx_mutex_get((TX_MUTEX *) *m, TX_WAIT_FOREVER); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_file_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_file_lock_isr_caller++; + } +} + +void __iar_file_Mtxunlock(__iar_Rmtx *m) +{ + +UINT status; + + + /* Determine the caller's context. Mutex unlocks are only available from initialization and + threads. */ + if ((_tx_thread_system_state == 0) || (_tx_thread_system_state >= TX_INITIALIZE_IN_PROGRESS)) + { + + /* Release the mutex. */ + status = _tx_mutex_put((TX_MUTEX *) *m); + + /* Check the status of the mutex release. */ + if (status) + { + + /* Internal error, increment the counter. */ + __tx_iar_file_lock_internal_errors++; + } + } + else + { + + /* Increment the ISR caller error. */ + __tx_iar_file_lock_isr_caller++; + } +} +#endif /* _DLIB_FILE_DESCRIPTOR */ + +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ + +#endif /* IAR version 8 and above. */ diff --git a/ports/arm11/iar/src/tx_thread_context_restore.s b/ports/arm11/iar/src/tx_thread_context_restore.s new file mode 100644 index 000000000..a66ecdc54 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_context_restore.s @@ -0,0 +1,258 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +SVC_MODE DEFINE 0xD3 ; SVC mode +IRQ_MODE DEFINE 0xD2 ; IRQ mode +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; Disable IRQ interrupts +#else +DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts +#endif +MODE_MASK DEFINE 0x1F ; Mode mask +THUMB_MASK DEFINE 0x20 ; Thumb bit mask +SVC_MODE_BITS DEFINE 0x13 ; SVC mode value + +; + EXTERN _tx_thread_system_state + EXTERN _tx_thread_current_ptr + EXTERN _tx_thread_execute_ptr + EXTERN _tx_timer_time_slice + EXTERN _tx_thread_schedule + EXTERN _tx_thread_preempt_disable + EXTERN _tx_execution_isr_exit +; +; + +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_restore ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function restores the interrupt context if it is processing a */ +;/* nested interrupt. If not, it returns to the interrupt thread if no */ +;/* preemption is necessary. Otherwise, if preemption is necessary or */ +;/* if no thread was running, the function returns to the scheduler. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling routine */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs Interrupt Service Routines */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_restore(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_context_restore + CODE32 +_tx_thread_context_restore +; +; /* Lockout interrupts. */ +; + MRS r3, CPSR ; Pickup current CPSR + ORR r0, r3, #DISABLE_INTS ; Build interrupt disable value + MSR CPSR_cxsf, r0 ; Lockout interrupts + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR exit function to indicate an ISR is complete. */ +; + BL _tx_execution_isr_exit ; Call the ISR exit function +#endif +; +; /* Determine if interrupts are nested. */ +; if (--_tx_thread_system_state) +; { +; + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3, #0] ; Pickup system state + SUB r2, r2, #1 ; Decrement the counter + STR r2, [r3, #0] ; Store the counter + CMP r2, #0 ; Was this the first interrupt? + BEQ __tx_thread_not_nested_restore ; If so, not a nested restore +; +; /* Interrupts are nested. */ +; +; /* Just recover the saved registers and return to the point of +; interrupt. */ +; + LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +__tx_thread_not_nested_restore +; +; /* Determine if a thread was interrupted and no preemption is required. */ +; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +; || (_tx_thread_preempt_disable)) +; { +; + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup actual current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_idle_system_restore ; Yes, idle system was interrupted +; + LDR r3, =_tx_thread_preempt_disable ; Pickup preempt disable address + LDR r2, [r3, #0] ; Pickup actual preempt disable flag + CMP r2, #0 ; Is it set? + BNE __tx_thread_no_preempt_restore ; Yes, don't preempt this thread + LDR r3, =_tx_thread_execute_ptr ; Pickup address of execute thread ptr + LDR r2, [r3, #0] ; Pickup actual execute thread pointer + CMP r0, r2 ; Is the same thread highest priority? + BNE __tx_thread_preempt_restore ; No, preemption needs to happen +; +; +__tx_thread_no_preempt_restore +; +; /* Restore interrupted thread or ISR. */ +; +; /* Pickup the saved stack pointer. */ +; tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; +; +; /* Recover the saved context and return to the point of interrupt. */ +; + LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +; else +; { +__tx_thread_preempt_restore +; + LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers + MOV r1, lr ; Save lr (point of interrupt) + MOV r2, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_c, r2 ; Enter SVC mode + STR r1, [sp, #-4]! ; Save point of interrupt + STMDB sp!, {r4-r12, lr} ; Save upper half of registers + MOV r4, r3 ; Save SPSR in r4 + MOV r2, #IRQ_MODE ; Build IRQ mode CPSR + MSR CPSR_c, r2 ; Enter IRQ mode + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOV r5, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_c, r5 ; Enter SVC mode + STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack + MOV r3, #1 ; Build interrupt stack type + STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup current thread pointer + STR sp, [r0, #8] ; Save stack pointer in thread control + ; block + BIC r4, r4, #THUMB_MASK ; Clear the Thumb bit of CPSR + ORR r3, r4, #DISABLE_INTS ; Or-in interrupt lockout bit(s) + MSR CPSR_cxsf, r3 ; Lockout interrupts +; +; /* Save the remaining time-slice and disable it. */ +; if (_tx_timer_time_slice) +; { +; + LDR r3, =_tx_timer_time_slice ; Pickup time-slice variable address + LDR r2, [r3, #0] ; Pickup time-slice + CMP r2, #0 ; Is it active? + BEQ __tx_thread_dont_save_ts ; No, don't save it +; +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + STR r2, [r0, #24] ; Save thread's time-slice + MOV r2, #0 ; Clear value + STR r2, [r3, #0] ; Disable global time-slice flag +; +; } +__tx_thread_dont_save_ts +; +; +; /* Clear the current task pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + MOV r0, #0 ; NULL value + STR r0, [r1, #0] ; Clear current thread pointer +; +; /* Return to the scheduler. */ +; _tx_thread_schedule(); +; + B _tx_thread_schedule ; Return to scheduler +; } +; +__tx_thread_idle_system_restore +; +; /* Just return back to the scheduler! */ +; + MRS r3, CPSR ; Pickup current CPSR + BIC r3, r3, #MODE_MASK ; Clear the mode portion of the CPSR + ORR r3, r3, #SVC_MODE_BITS ; Or-in new interrupt lockout bit + MSR CPSR_cxsf, r3 ; Lockout interrupts + B _tx_thread_schedule ; Return to scheduler +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_context_save.s b/ports/arm11/iar/src/tx_thread_context_save.s new file mode 100644 index 000000000..71d7347e4 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_context_save.s @@ -0,0 +1,222 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled +#else +DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled +#endif + + + EXTERN _tx_thread_system_state + EXTERN _tx_thread_current_ptr + EXTERN __tx_irq_processing_return + EXTERN _tx_execution_isr_enter +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_context_save ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function saves the context of an executing thread in the */ +;/* beginning of interrupt processing. The function also ensures that */ +;/* the system stack is used upon return to the calling ISR. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_context_save(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_context_save + CODE32 +_tx_thread_context_save +; +; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +; out, we are in IRQ mode, and all registers are intact. */ +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; + STMDB sp!, {r0-r3} ; Save some working registers +#ifdef TX_ENABLE_FIQ_SUPPORT + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt CPSR + MSR CPSR_cxsf, r0 ; Disable interrupts +#endif + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3, #0] ; Pickup system state + CMP r2, #0 ; Is this the first interrupt? + BEQ __tx_thread_not_nested_save ; Yes, not a nested context save +; +; /* Nested interrupt condition. */ +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3, #0] ; Store it back in the variable +; +; /* Save the rest of the scratch registers on the stack and return to the +; calling ISR. */ +; + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} ; Store other registers +; +; /* Return to the ISR. */ +; + MOV r10, #0 ; Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr +#endif + + B __tx_irq_processing_return ; Continue IRQ processing +; +__tx_thread_not_nested_save +; } +; +; /* Otherwise, not nested, check to see if a thread was running. */ +; else if (_tx_thread_current_ptr) +; { +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3, #0] ; Store it back in the variable + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_idle_system_save ; If so, interrupt occured in + ; scheduling loop - nothing needs saving! +; +; /* Save minimal context of interrupted thread. */ +; + MRS r2, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r2, r10, r12, lr} ; Store other registers +; +; /* Save the current stack pointer in the thread's control block. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +; +; /* Switch to the system stack. */ +; sp = _tx_thread_system_stack_ptr; +; + MOV r10, #0 ; Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr +#endif + + B __tx_irq_processing_return ; Continue IRQ processing +; +; } +; else +; { +; +__tx_thread_idle_system_save +; +; /* Interrupt occurred in the scheduling loop. */ +; +; /* Not much to do here, just adjust the stack pointer, and return to IRQ +; processing. */ +; + MOV r10, #0 ; Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr +#endif + + ADD sp, sp, #16 ; Recover saved registers + B __tx_irq_processing_return ; Continue IRQ processing +; +; } +;} +; + +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_fiq_context_restore.s b/ports/arm11/iar/src/tx_thread_fiq_context_restore.s new file mode 100644 index 000000000..a8f9f0bdd --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_fiq_context_restore.s @@ -0,0 +1,269 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +SVC_MODE DEFINE 0xD3 ; SVC mode +FIQ_MODE DEFINE 0xD1 ; FIQ mode +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; Disable IRQ & FIQ interrupts +#else +DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts +#endif +MODE_MASK DEFINE 0x1F ; Mode mask +THUMB_MASK DEFINE 0x20 ; Thumb bit mask +IRQ_MODE_BITS DEFINE 0x12 ; IRQ mode bits +SVC_MODE_BITS DEFINE 0x13 ; SVC mode value + +; + EXTERN _tx_thread_system_state + EXTERN _tx_thread_current_ptr + EXTERN _tx_thread_execute_ptr + EXTERN _tx_timer_time_slice + EXTERN _tx_thread_schedule + EXTERN _tx_thread_preempt_disable + EXTERN _tx_execution_isr_exit +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_context_restore ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function restores the fiq interrupt context when processing a */ +;/* nested interrupt. If not, it returns to the interrupt thread if no */ +;/* preemption is necessary. Otherwise, if preemption is necessary or */ +;/* if no thread was running, the function returns to the scheduler. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling routine */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* FIQ ISR Interrupt Service Routines */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_fiq_context_restore(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_fiq_context_restore + CODE32 +_tx_thread_fiq_context_restore +; +; /* Lockout interrupts. */ +; + MRS r3, CPSR ; Pickup current CPSR + ORR r0, r3, #DISABLE_INTS ; Build interrupt disable value + MSR CPSR_cxsf, r0 ; Lockout interrupts + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR exit function to indicate an ISR is complete. */ +; + BL _tx_execution_isr_exit ; Call the ISR exit function +#endif +; +; /* Determine if interrupts are nested. */ +; if (--_tx_thread_system_state) +; { +; + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3] ; Pickup system state + SUB r2, r2, #1 ; Decrement the counter + STR r2, [r3] ; Store the counter + CMP r2, #0 ; Was this the first interrupt? + BEQ __tx_thread_fiq_not_nested_restore ; If so, not a nested restore +; +; /* Interrupts are nested. */ +; +; /* Just recover the saved registers and return to the point of +; interrupt. */ +; + LDMIA sp!, {r0, r10, r12, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +__tx_thread_fiq_not_nested_restore +; +; /* Determine if a thread was interrupted and no preemption is required. */ +; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr) +; || (_tx_thread_preempt_disable)) +; { +; + LDR r1, [sp] ; Pickup the saved SPSR + MOV r2, #MODE_MASK ; Build mask to isolate the interrupted mode + AND r1, r1, r2 ; Isolate mode bits + CMP r1, #IRQ_MODE_BITS ; Was an interrupt taken in IRQ mode before we + ; got to context save? */ + BEQ __tx_thread_fiq_no_preempt_restore ; Yes, just go back to point of interrupt + + + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1] ; Pickup actual current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_fiq_idle_system_restore ; Yes, idle system was interrupted + + LDR r3, =_tx_thread_preempt_disable ; Pickup preempt disable address + LDR r2, [r3] ; Pickup actual preempt disable flag + CMP r2, #0 ; Is it set? + BNE __tx_thread_fiq_no_preempt_restore ; Yes, don't preempt this thread + LDR r3, =_tx_thread_execute_ptr ; Pickup address of execute thread ptr + LDR r2, [r3] ; Pickup actual execute thread pointer + CMP r0, r2 ; Is the same thread highest priority? + BNE __tx_thread_fiq_preempt_restore ; No, preemption needs to happen + + +__tx_thread_fiq_no_preempt_restore +; +; /* Restore interrupted thread or ISR. */ +; +; /* Pickup the saved stack pointer. */ +; tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr; +; +; /* Recover the saved context and return to the point of interrupt. */ +; + LDMIA sp!, {r0, lr} ; Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 ; Put SPSR back + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOVS pc, lr ; Return to point of interrupt +; +; } +; else +; { +__tx_thread_fiq_preempt_restore +; + LDMIA sp!, {r3, lr} ; Recover temporarily saved registers + MOV r1, lr ; Save lr (point of interrupt) + MOV r2, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_cxsf, r2 ; Enter SVC mode + STR r1, [sp, #-4]! ; Save point of interrupt + STMDB sp!, {r4-r12, lr} ; Save upper half of registers + MOV r4, r3 ; Save SPSR in r4 + MOV r2, #FIQ_MODE ; Build FIQ mode CPSR + MSR CPSR_cxsf, r2 ; Re-enter FIQ mode + LDMIA sp!, {r0-r3} ; Recover r0-r3 + MOV r5, #SVC_MODE ; Build SVC mode CPSR + MSR CPSR_cxsf, r5 ; Enter SVC mode + STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack + MOV r3, #1 ; Build interrupt stack type + STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1] ; Pickup current thread pointer + STR sp, [r0, #8] ; Save stack pointer in thread control + ; block */ + BIC r4, r4, #THUMB_MASK ; Clear the Thumb bit of CPSR + ORR r3, r4, #DISABLE_INTS ; Or-in interrupt lockout bit(s) + MSR CPSR_cxsf, r3 ; Lockout interrupts +; +; /* Save the remaining time-slice and disable it. */ +; if (_tx_timer_time_slice) +; { +; + LDR r3, =_tx_timer_time_slice ; Pickup time-slice variable address + LDR r2, [r3] ; Pickup time-slice + CMP r2, #0 ; Is it active? + BEQ __tx_thread_fiq_dont_save_ts ; No, don't save it +; +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + STR r2, [r0, #24] ; Save thread's time-slice + MOV r2, #0 ; Clear value + STR r2, [r3] ; Disable global time-slice flag +; +; } +__tx_thread_fiq_dont_save_ts +; +; +; /* Clear the current task pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + MOV r0, #0 ; NULL value + STR r0, [r1] ; Clear current thread pointer +; +; /* Return to the scheduler. */ +; _tx_thread_schedule(); +; + B _tx_thread_schedule ; Return to scheduler +; } +; +__tx_thread_fiq_idle_system_restore +; +; /* Just return back to the scheduler! */ +; + ADD sp, sp, #24 ; Recover FIQ stack space + MRS r3, CPSR ; Pickup current CPSR + BIC r3, r3, #MODE_MASK ; Clear the mode portion of the CPSR + ORR r3, r3, #SVC_MODE_BITS ; Or-in new interrupt lockout bit + MSR CPSR_cxsf, r3 ; Lockout interrupts + B _tx_thread_schedule ; Return to scheduler +; +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_fiq_context_save.s b/ports/arm11/iar/src/tx_thread_fiq_context_save.s new file mode 100644 index 000000000..7745f756b --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_fiq_context_save.s @@ -0,0 +1,215 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; + EXTERN _tx_thread_system_state + EXTERN _tx_thread_current_ptr + EXTERN __tx_fiq_processing_return + EXTERN _tx_execution_isr_enter +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_context_save ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function saves the context of an executing thread in the */ +;/* beginning of interrupt processing. The function also ensures that */ +;/* the system stack is used upon return to the calling ISR. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +; VOID _tx_thread_fiq_context_save(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_fiq_context_save + CODE32 +_tx_thread_fiq_context_save +; +; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +; out, we are in IRQ mode, and all registers are intact. */ +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; + STMDB sp!, {r0-r3} ; Save some working registers + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3] ; Pickup system state + CMP r2, #0 ; Is this the first interrupt? + BEQ __tx_thread_fiq_not_nested_save ; Yes, not a nested context save +; +; /* Nested interrupt condition. */ +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3] ; Store it back in the variable +; +; /* Save the rest of the scratch registers on the stack and return to the +; calling ISR. */ +; + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} ; Store other registers +; +; /* Return to the ISR. */ +; + MOV r10, #0 ; Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr +#endif + + B __tx_fiq_processing_return ; Continue FIQ processing +; +__tx_thread_fiq_not_nested_save +; } +; +; /* Otherwise, not nested, check to see if a thread was running. */ +; else if (_tx_thread_current_ptr) +; { +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3] ; Store it back in the variable + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1] ; Pickup current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_fiq_idle_system_save ; If so, interrupt occurred in +; ; scheduling loop - nothing needs saving! +; +; /* Save minimal context of interrupted thread. */ +; + MRS r2, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r2, lr} ; Store other registers, Note that we don't +; ; need to save sl and ip since FIQ has +; ; copies of these registers. Nested +; ; interrupt processing does need to save +; ; these registers. +; +; /* Save the current stack pointer in the thread's control block. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +; +; /* Switch to the system stack. */ +; sp = _tx_thread_system_stack_ptr; +; + MOV r10, #0 ; Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr +#endif + + B __tx_fiq_processing_return ; Continue FIQ processing +; +; } +; else +; { +; +__tx_thread_fiq_idle_system_save +; +; /* Interrupt occurred in the scheduling loop. */ +; +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr +#endif +; +; /* Not much to do here, save the current SPSR and LR for possible +; use in IRQ interrupted in idle system conditions, and return to +; FIQ interrupt processing. */ +; + MRS r0, SPSR ; Pickup saved SPSR + SUB lr, lr, #4 ; Adjust point of interrupt + STMDB sp!, {r0, lr} ; Store other registers that will get used +; ; or stripped off the stack in context +; ; restore + B __tx_fiq_processing_return ; Continue FIQ processing +; +; } +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_fiq_nesting_end.s b/ports/arm11/iar/src/tx_thread_fiq_nesting_end.s new file mode 100644 index 000000000..008b3b407 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_fiq_nesting_end.s @@ -0,0 +1,121 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; Disable IRQ & FIQ interrupts +#else +DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts +#endif +MODE_MASK DEFINE 0x1F ; Mode mask +FIQ_MODE_BITS DEFINE 0x11 ; FIQ mode bits +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_nesting_end ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from FIQ mode after */ +;/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */ +;/* processing from system mode back to FIQ mode prior to the ISR */ +;/* calling _tx_thread_fiq_context_restore. Note that this function */ +;/* assumes the system stack pointer is in the same position after */ +;/* nesting start function was called. */ +;/* */ +;/* This function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s79). */ +;/* */ +;/* This function returns with FIQ interrupts disabled. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_fiq_nesting_end(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_fiq_nesting_end + CODE32 +_tx_thread_fiq_nesting_end + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt value + MSR CPSR_cxsf, r0 ; Disable interrupts + LDR lr, [sp] ; Pickup saved lr + ADD sp, sp, #4 ; Adjust stack pointer + BIC r0, r0, #MODE_MASK ; Clear mode bits + ORR r0, r0, #FIQ_MODE_BITS ; Build IRQ mode CPSR + MSR CPSR_cxsf, r0 ; Re-enter IRQ mode + MOV pc, r3 ; Return to ISR +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_fiq_nesting_start.s b/ports/arm11/iar/src/tx_thread_fiq_nesting_start.s new file mode 100644 index 000000000..f4411d086 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_fiq_nesting_start.s @@ -0,0 +1,114 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +FIQ_DISABLE DEFINE 0x40 ; FIQ disable bit +MODE_MASK DEFINE 0x1F ; Mode mask +SYS_MODE_BITS DEFINE 0x1F ; System mode bits +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_fiq_nesting_start ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from FIQ mode after */ +;/* _tx_thread_fiq_context_save has been called and switches the FIQ */ +;/* processing to the system mode so nested FIQ interrupt processing */ +;/* is possible (system mode has its own "lr" register). Note that */ +;/* this function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s79). */ +;/* */ +;/* This function returns with FIQ interrupts enabled. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_fiq_nesting_start(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_fiq_nesting_start + CODE32 +_tx_thread_fiq_nesting_start + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + BIC r0, r0, #MODE_MASK ; Clear the mode bits + ORR r0, r0, #SYS_MODE_BITS ; Build system mode CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + STR lr, [sp, #-4]! ; Push the system mode lr on the system mode stack + BIC r0, r0, #FIQ_DISABLE ; Build enable FIQ CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + MOV pc, r3 ; Return to ISR +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_interrupt_control.s b/ports/arm11/iar/src/tx_thread_interrupt_control.s new file mode 100644 index 000000000..f80e31d8a --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_interrupt_control.s @@ -0,0 +1,115 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +#ifdef TX_ENABLE_FIQ_SUPPORT +INT_MASK DEFINE 0xC0 ; Interrupt bit mask +#else +INT_MASK DEFINE 0x80 ; Interrupt bit mask +#endif +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_control ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for changing the interrupt lockout */ +;/* posture of the system. */ +;/* */ +;/* INPUT */ +;/* */ +;/* new_posture New interrupt lockout posture */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* old_posture Old interrupt lockout posture */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* Application Code */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;UINT _tx_thread_interrupt_control(UINT new_posture) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_interrupt_control + CODE32 +_tx_thread_interrupt_control +; +; /* Pickup current interrupt lockout posture. */ +; + MRS r3, CPSR ; Pickup current CPSR + BIC r1, r3, #INT_MASK ; Clear interrupt lockout bits + ORR r1, r1, r0 ; Or-in new interrupt lockout bits +; +; /* Apply the new interrupt posture. */ +; + MSR CPSR_cxsf, r1 ; Setup new CPSR + AND r0, r3, #INT_MASK ; Return previous interrupt mask +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +; +;} +; +; + END diff --git a/ports/arm11/iar/src/tx_thread_interrupt_disable.s b/ports/arm11/iar/src/tx_thread_interrupt_disable.s new file mode 100644 index 000000000..e3029ecb0 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_interrupt_disable.s @@ -0,0 +1,113 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled +#else +DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled +#endif +; +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_disable ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for disabling interrupts */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* old_posture Old interrupt lockout posture */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* Application Code */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;UINT _tx_thread_interrupt_disable(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_interrupt_disable + CODE32 +_tx_thread_interrupt_disable??rA +_tx_thread_interrupt_disable +; +; /* Pickup current interrupt lockout posture. */ +; + MRS r0, CPSR ; Pickup current CPSR +; +; /* Mask interrupts. */ +; + ORR r1, r0, #DISABLE_INTS ; Mask interrupts + MSR CPSR_cxsf, r1 ; Setup new CPSR +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +;} +; +; + END diff --git a/ports/arm11/iar/src/tx_thread_interrupt_restore.s b/ports/arm11/iar/src/tx_thread_interrupt_restore.s new file mode 100644 index 000000000..0c0fdef03 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_interrupt_restore.s @@ -0,0 +1,99 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_interrupt_restore ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is responsible for restoring interrupts to the state */ +;/* returned by a previous _tx_thread_interrupt_disable call. */ +;/* */ +;/* INPUT */ +;/* */ +;/* old_posture Old interrupt lockout posture */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* Application Code */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;void _tx_thread_interrupt_restore(UINT old_posture) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_interrupt_restore + CODE32 +_tx_thread_interrupt_restore +; +; /* Apply the new interrupt posture. */ +; + MSR CPSR_cxsf, r0 ; Setup new CPSR +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +;} +; + END diff --git a/ports/arm11/iar/src/tx_thread_irq_nesting_end.s b/ports/arm11/iar/src/tx_thread_irq_nesting_end.s new file mode 100644 index 000000000..50da22c41 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_irq_nesting_end.s @@ -0,0 +1,122 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; Disable IRQ & FIQ interrupts +#else +DISABLE_INTS DEFINE 0x80 ; Disable IRQ interrupts +#endif +MODE_MASK DEFINE 0x1F ; Mode mask +IRQ_MODE_BITS DEFINE 0x12 ; IRQ mode bits +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_irq_nesting_end ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from IRQ mode after */ +;/* _tx_thread_irq_nesting_start has been called and switches the IRQ */ +;/* processing from system mode back to IRQ mode prior to the ISR */ +;/* calling _tx_thread_context_restore. Note that this function */ +;/* assumes the system stack pointer is in the same position after */ +;/* nesting start function was called. */ +;/* */ +;/* This function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s79). */ +;/* */ +;/* This function returns with IRQ interrupts disabled. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_irq_nesting_end(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_irq_nesting_end + CODE32 +_tx_thread_irq_nesting_end + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt value + MSR CPSR_cxsf, r0 ; Disable interrupts + LDR lr, [sp] ; Pickup saved lr + ADD sp, sp, #4 ; Adjust stack pointer + BIC r0, r0, #MODE_MASK ; Clear mode bits + ORR r0, r0, #IRQ_MODE_BITS ; Build IRQ mode CPSR + MSR CPSR_cxsf, r0 ; Re-enter IRQ mode + MOV pc, r3 ; Return to ISR +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_irq_nesting_start.s b/ports/arm11/iar/src/tx_thread_irq_nesting_start.s new file mode 100644 index 000000000..eb1977ccf --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_irq_nesting_start.s @@ -0,0 +1,114 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +IRQ_DISABLE DEFINE 0x80 ; IRQ disable bit +MODE_MASK DEFINE 0x1F ; Mode mask +SYS_MODE_BITS DEFINE 0x1F ; System mode bits +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_irq_nesting_start ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is called by the application from IRQ mode after */ +;/* _tx_thread_context_save has been called and switches the IRQ */ +;/* processing to the system mode so nested IRQ interrupt processing */ +;/* is possible (system mode has its own "lr" register). Note that */ +;/* this function assumes that the system mode stack pointer was setup */ +;/* during low-level initialization (tx_initialize_low_level.s79). */ +;/* */ +;/* This function returns with IRQ interrupts enabled. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_irq_nesting_start(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_irq_nesting_start + CODE32 +_tx_thread_irq_nesting_start + MOV r3,lr ; Save ISR return address + MRS r0, CPSR ; Pickup the CPSR + BIC r0, r0, #MODE_MASK ; Clear the mode bits + ORR r0, r0, #SYS_MODE_BITS ; Build system mode CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + STR lr, [sp, #-4]! ; Push the system mode lr on the system mode stack + BIC r0, r0, #IRQ_DISABLE ; Build enable IRQ CPSR + MSR CPSR_cxsf, r0 ; Enter system mode + MOV pc, r3 ; Return to ISR +;} +; +; + END + diff --git a/ports/arm11/iar/src/tx_thread_schedule.s b/ports/arm11/iar/src/tx_thread_schedule.s new file mode 100644 index 000000000..db2d2591f --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_schedule.s @@ -0,0 +1,183 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +#ifdef TX_ENABLE_FIQ_SUPPORT +ENABLE_INTS DEFINE 0xC0 ; IRQ & FIQ Interrupts enabled mask +#else +ENABLE_INTS DEFINE 0x80 ; IRQ Interrupts enabled mask +#endif +; +; + EXTERN _tx_thread_execute_ptr + EXTERN _tx_thread_current_ptr + EXTERN _tx_timer_time_slice + EXTERN _tx_execution_thread_enter +; +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_schedule ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function waits for a thread control block pointer to appear in */ +;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */ +;/* in the variable, the corresponding thread is resumed. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* _tx_initialize_kernel_enter ThreadX entry function */ +;/* _tx_thread_system_return Return to system from thread */ +;/* _tx_thread_context_restore Restore thread's context */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_schedule(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_schedule + CODE32 +_tx_thread_schedule??rA +_tx_thread_schedule +; +; /* Enable interrupts. */ +; + MRS r2, CPSR ; Pickup CPSR + BIC r0, r2, #ENABLE_INTS ; Clear the disable bit(s) + MSR CPSR_cxsf, r0 ; Enable interrupts +; +; /* Wait for a thread to execute. */ +; do +; { + LDR r1, =_tx_thread_execute_ptr ; Address of thread execute ptr +; +__tx_thread_schedule_loop +; + LDR r0, [r1, #0] ; Pickup next thread to execute + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_schedule_loop ; If so, keep looking for a thread +; +; } +; while(_tx_thread_execute_ptr == TX_NULL); +; +; /* Yes! We have a thread to execute. Lockout interrupts and +; transfer control to it. */ +; + MSR CPSR_cxsf, r2 ; Disable interrupts +; +; /* Setup the current thread pointer. */ +; _tx_thread_current_ptr = _tx_thread_execute_ptr; +; + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread + STR r0, [r1, #0] ; Setup current thread pointer +; +; /* Increment the run count for this thread. */ +; _tx_thread_current_ptr -> tx_thread_run_count++; +; + LDR r2, [r0, #4] ; Pickup run counter + LDR r3, [r0, #24] ; Pickup time-slice for this thread + ADD r2, r2, #1 ; Increment thread run-counter + STR r2, [r0, #4] ; Store the new run counter +; +; /* Setup time-slice, if present. */ +; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; +; + LDR r2, =_tx_timer_time_slice ; Pickup address of time slice + ; variable + LDR sp, [r0, #8] ; Switch stack pointers + STR r3, [r2, #0] ; Setup time-slice +; +; /* Switch to the thread's stack. */ +; sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr; +; +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the thread entry function to indicate the thread is executing. */ +; + BL _tx_execution_thread_enter ; Call the thread execution enter function +#endif +; +; /* Determine if an interrupt frame or a synchronous task suspension frame +; is present. */ +; + LDMIA sp!, {r0, r1} ; Pickup the stack type and saved CPSR + CMP r0, #0 ; Check for synchronous context switch + MSRNE SPSR_cxsf, r1 ; Setup SPSR for return + LDMNEIA sp!, {r0-r12, lr, pc}^ ; Return to point of thread interrupt + LDMIA sp!, {r4-r11, lr} ; Return to thread synchronously + MSR CPSR_cxsf, r1 ; Recover CPSR +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +; +;} +; + END + diff --git a/ports/arm11/iar/src/tx_thread_stack_build.s b/ports/arm11/iar/src/tx_thread_stack_build.s new file mode 100644 index 000000000..61b3f8a1b --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_stack_build.s @@ -0,0 +1,170 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +; +; +SVC_MODE DEFINE 0x13 ; SVC mode +#ifdef TX_ENABLE_FIQ_SUPPORT +CPSR_MASK DEFINE 0xDF ; Mask initial CPSR, IRQ & FIQ ints enabled +#else +CPSR_MASK DEFINE 0x9F ; Mask initial CPSR, IRQ ints enabled +#endif +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_stack_build ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function builds a stack frame on the supplied thread's stack. */ +;/* The stack frame results in a fake interrupt return to the supplied */ +;/* function pointer. */ +;/* */ +;/* INPUT */ +;/* */ +;/* thread_ptr Pointer to thread control blk */ +;/* function_ptr Pointer to return function */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* _tx_thread_create Create thread service */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_stack_build + + CODE32 +_tx_thread_stack_build +; +; +; /* Build a fake interrupt frame. The form of the fake interrupt stack +; on the ARM9 should look like the following after it is built: +; +; Stack Top: 1 Interrupt stack frame type +; CPSR Initial value for CPSR +; a1 (r0) Initial value for a1 +; a2 (r1) Initial value for a2 +; a3 (r2) Initial value for a3 +; a4 (r3) Initial value for a4 +; v1 (r4) Initial value for v1 +; v2 (r5) Initial value for v2 +; v3 (r6) Initial value for v3 +; v4 (r7) Initial value for v4 +; v5 (r8) Initial value for v5 +; sb (r9) Initial value for sb +; sl (r10) Initial value for sl +; fp (r11) Initial value for fp +; ip (r12) Initial value for ip +; lr (r14) Initial value for lr +; pc (r15) Initial value for pc +; 0 For stack backtracing +; +; Stack Bottom: (higher memory address) */ +; + LDR r2, [r0, #16] ; Pickup end of stack area + BIC r2, r2, #7 ; Ensure long-word alignment + SUB r2, r2, #76 ; Allocate space for the stack frame +; +; /* Actually build the stack frame. */ +; + MOV r3, #1 ; Build interrupt stack type + STR r3, [r2, #0] ; Store stack type + MOV r3, #0 ; Build initial register value + STR r3, [r2, #8] ; Store initial r0 + STR r3, [r2, #12] ; Store initial r1 + STR r3, [r2, #16] ; Store initial r2 + STR r3, [r2, #20] ; Store initial r3 + STR r3, [r2, #24] ; Store initial r4 + STR r3, [r2, #28] ; Store initial r5 + STR r3, [r2, #32] ; Store initial r6 + STR r3, [r2, #36] ; Store initial r7 + STR r3, [r2, #40] ; Store initial r8 + STR r3, [r2, #44] ; Store initial r9 + LDR r3, [r0, #12] ; Pickup stack starting address + STR r3, [r2, #48] ; Store initial r10 (sl) + MOV r3, #0 ; Build initial register value + STR r3, [r2, #52] ; Store initial r11 + STR r3, [r2, #56] ; Store initial r12 + STR r3, [r2, #60] ; Store initial lr + STR r1, [r2, #64] ; Store initial pc + STR r3, [r2, #68] ; 0 for back-trace + MRS r1, CPSR ; Pickup CPSR + BIC r1, r1, #CPSR_MASK ; Mask mode bits of CPSR + ORR r3, r1, #SVC_MODE ; Build CPSR, SVC mode, interrupts enabled + STR r3, [r2, #4] ; Store initial CPSR +; +; /* Setup stack pointer. */ +; thread_ptr -> tx_thread_stack_ptr = r2; +; + STR r2, [r0, #8] ; Save stack pointer in thread's + ; control block +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +;} + END + diff --git a/ports/arm11/iar/src/tx_thread_system_return.s b/ports/arm11/iar/src/tx_thread_system_return.s new file mode 100644 index 000000000..0c6198af5 --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_system_return.s @@ -0,0 +1,161 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled +#else +DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled +#endif +; +; + EXTERN _tx_thread_current_ptr + EXTERN _tx_timer_time_slice + EXTERN _tx_thread_schedule + EXTERN _tx_execution_thread_exit +; +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_system_return ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function is target processor specific. It is used to transfer */ +;/* control from a thread back to the ThreadX system. Only a */ +;/* minimal context is saved since the compiler assumes temp registers */ +;/* are going to get slicked by a function call anyway. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_thread_schedule Thread scheduling loop */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ThreadX components */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_system_return(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_system_return + CODE32 +_tx_thread_system_return??rA +_tx_thread_system_return +; +; /* Save minimal context on the stack. */ +; + MOV r0, #0 ; Build a solicited stack type + MRS r1, CPSR ; Pickup the CPSR + STMDB sp!, {r0-r1, r4-r11, lr} ; Save minimal context +; +; /* Lockout interrupts. */ +; + ORR r2, r1, #DISABLE_INTS ; Build disable interrupt CPSR + MSR CPSR_cxsf, r2 ; Disable interrupts + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the thread exit function to indicate the thread is no longer executing. */ +; + BL _tx_execution_thread_exit ; Call the thread exit function +#endif + + LDR r3, =_tx_thread_current_ptr ; Pickup address of current ptr + LDR r0, [r3, #0] ; Pickup current thread pointer + LDR r2, =_tx_timer_time_slice ; Pickup address of time slice + LDR r1, [r2, #0] ; Pickup current time slice +; +; /* Save current stack and switch to system stack. */ +; _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; +; sp = _tx_thread_system_stack_ptr; +; + STR sp, [r0, #8] ; Save thread stack pointer +; +; /* Determine if the time-slice is active. */ +; if (_tx_timer_time_slice) +; { +; + MOV r4, #0 ; Build clear value + CMP r1, #0 ; Is a time-slice active? + BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice +; +; /* Save time-slice for the thread and clear the current time-slice. */ +; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice; +; _tx_timer_time_slice = 0; +; + STR r4, [r2, #0] ; Clear time-slice + STR r1, [r0, #24] ; Save current time-slice +; +; } +__tx_thread_dont_save_ts +; +; /* Clear the current thread pointer. */ +; _tx_thread_current_ptr = TX_NULL; +; + STR r4, [r3, #0] ; Clear current thread pointer + B _tx_thread_schedule ; Jump to scheduler! +; +;} + END + diff --git a/ports/arm11/iar/src/tx_thread_vectored_context_save.s b/ports/arm11/iar/src/tx_thread_vectored_context_save.s new file mode 100644 index 000000000..6bf9209ce --- /dev/null +++ b/ports/arm11/iar/src/tx_thread_vectored_context_save.s @@ -0,0 +1,207 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Thread */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_thread.h" +;#include "tx_timer.h" +; +; +#ifdef TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS DEFINE 0xC0 ; IRQ & FIQ interrupts disabled +#else +DISABLE_INTS DEFINE 0x80 ; IRQ interrupts disabled +#endif + + EXTERN _tx_thread_system_state + EXTERN _tx_thread_current_ptr + EXTERN _tx_execution_isr_enter +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_thread_vectored_context_save ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function saves the context of an executing thread in the */ +;/* beginning of interrupt processing. The function also ensures that */ +;/* the system stack is used upon return to the calling ISR. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* None */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* ISRs */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_thread_vectored_context_save(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_thread_vectored_context_save + CODE32 +_tx_thread_vectored_context_save +; +; /* Upon entry to this routine, it is assumed that IRQ interrupts are locked +; out, we are in IRQ mode, the minimal context is already saved, and the +; lr register contains the return ISR address. */ +; +; /* Check for a nested interrupt condition. */ +; if (_tx_thread_system_state++) +; { +; +#ifdef TX_ENABLE_FIQ_SUPPORT + MRS r0, CPSR ; Pickup the CPSR + ORR r0, r0, #DISABLE_INTS ; Build disable interrupt CPSR + MSR CPSR_cxsf, r0 ; Disable interrupts +#endif + LDR r3, =_tx_thread_system_state ; Pickup address of system state var + LDR r2, [r3, #0] ; Pickup system state + CMP r2, #0 ; Is this the first interrupt? + BEQ __tx_thread_not_nested_save ; Yes, not a nested context save +; +; /* Nested interrupt condition. */ +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3, #0] ; Store it back in the variable +; +; /* Note: Minimal context of interrupted thread is already saved. */ +; +; /* Return to the ISR. */ +; + MOV r10, #0 ; Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr +#endif + + MOV pc, lr ; Return to caller +; +__tx_thread_not_nested_save +; } +; +; /* Otherwise, not nested, check to see if a thread was running. */ +; else if (_tx_thread_current_ptr) +; { +; + ADD r2, r2, #1 ; Increment the interrupt counter + STR r2, [r3, #0] ; Store it back in the variable + LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr + LDR r0, [r1, #0] ; Pickup current thread pointer + CMP r0, #0 ; Is it NULL? + BEQ __tx_thread_idle_system_save ; If so, interrupt occured in + ; scheduling loop - nothing needs saving! +; +; /* Note: Minimal context of interrupted thread is already saved. */ +; +; /* Save the current stack pointer in the thread's control block. */ +; _tx_thread_current_ptr -> tx_stack_ptr = sp; +; +; /* Switch to the system stack. */ +; sp = _tx_thread_system_stack_ptr; +; + MOV r10, #0 ; Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr +#endif + + MOV pc, lr ; Return to caller +; +; } +; else +; { +; +__tx_thread_idle_system_save +; +; /* Interrupt occurred in the scheduling loop. */ +; +; /* Not much to do here, just adjust the stack pointer, and return to IRQ +; processing. */ +; + MOV r10, #0 ; Clear stack limit + +#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +; +; /* Call the ISR enter function to indicate an ISR is executing. */ +; + PUSH {lr} ; Save ISR lr + BL _tx_execution_isr_enter ; Call the ISR enter function + POP {lr} ; Recover ISR lr +#endif + + ADD sp, sp, #32 ; Recover saved registers + MOV pc, lr ; Return to caller +; +; } +;} + END + diff --git a/ports/arm11/iar/src/tx_timer_interrupt.s b/ports/arm11/iar/src/tx_timer_interrupt.s new file mode 100644 index 000000000..7bb4f09fb --- /dev/null +++ b/ports/arm11/iar/src/tx_timer_interrupt.s @@ -0,0 +1,272 @@ +;/**************************************************************************/ +;/* */ +;/* Copyright (c) 1996-2018 by Express Logic Inc. */ +;/* */ +;/* This software is copyrighted by and is the sole property of Express */ +;/* Logic, Inc. All rights, title, ownership, or other interests */ +;/* in the software remain the property of Express Logic, Inc. This */ +;/* software may only be used in accordance with the corresponding */ +;/* license agreement. Any unauthorized use, duplication, transmission, */ +;/* distribution, or disclosure of this software is expressly forbidden. */ +;/* */ +;/* This Copyright notice may not be removed or modified without prior */ +;/* written consent of Express Logic, Inc. */ +;/* */ +;/* Express Logic, Inc. reserves the right to modify this software */ +;/* without notice. */ +;/* */ +;/* Express Logic, Inc. info@expresslogic.com */ +;/* 11423 West Bernardo Court http://www.expresslogic.com */ +;/* San Diego, CA 92127 */ +;/* */ +;/**************************************************************************/ +; +; +;/**************************************************************************/ +;/**************************************************************************/ +;/** */ +;/** ThreadX Component */ +;/** */ +;/** Timer */ +;/** */ +;/**************************************************************************/ +;/**************************************************************************/ +; +;#define TX_SOURCE_CODE +; +; +;/* Include necessary system files. */ +; +;#include "tx_api.h" +;#include "tx_timer.h" +;#include "tx_thread.h" +; +; +;Define Assembly language external references... +; + EXTERN _tx_timer_time_slice + EXTERN _tx_timer_system_clock + EXTERN _tx_timer_current_ptr + EXTERN _tx_timer_list_start + EXTERN _tx_timer_list_end + EXTERN _tx_timer_expired_time_slice + EXTERN _tx_timer_expired + EXTERN _tx_thread_time_slice + EXTERN _tx_timer_expiration_process +; +; +; +;/**************************************************************************/ +;/* */ +;/* FUNCTION RELEASE */ +;/* */ +;/* _tx_timer_interrupt ARM11/IAR */ +;/* 6.0.1 */ +;/* AUTHOR */ +;/* */ +;/* William E. Lamie, Express Logic, Inc. */ +;/* */ +;/* DESCRIPTION */ +;/* */ +;/* This function processes the hardware timer interrupt. This */ +;/* processing includes incrementing the system clock and checking for */ +;/* time slice and/or timer expiration. If either is found, the */ +;/* interrupt context save/restore functions are called along with the */ +;/* expiration functions. */ +;/* */ +;/* INPUT */ +;/* */ +;/* None */ +;/* */ +;/* OUTPUT */ +;/* */ +;/* None */ +;/* */ +;/* CALLS */ +;/* */ +;/* _tx_timer_expiration_process Timer expiration processing */ +;/* _tx_thread_time_slice Time-slice interrupted thread */ +;/* */ +;/* CALLED BY */ +;/* */ +;/* interrupt vector */ +;/* */ +;/* RELEASE HISTORY */ +;/* */ +;/* DATE NAME DESCRIPTION */ +;/* */ +;/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */ +;/* */ +;/**************************************************************************/ +;VOID _tx_timer_interrupt(VOID) +;{ + RSEG .text:CODE:NOROOT(2) + PUBLIC _tx_timer_interrupt + CODE32 +_tx_timer_interrupt +; +; /* Upon entry to this routine, it is assumed that context save has already +; been called, and therefore the compiler scratch registers are available +; for use. */ +; +; /* Increment the system clock. */ +; _tx_timer_system_clock++; +; + LDR r1, =_tx_timer_system_clock ; Pickup address of system clock + LDR r0, [r1, #0] ; Pickup system clock + ADD r0, r0, #1 ; Increment system clock + STR r0, [r1, #0] ; Store new system clock +; +; /* Test for time-slice expiration. */ +; if (_tx_timer_time_slice) +; { +; + LDR r3, =_tx_timer_time_slice ; Pickup address of time-slice + LDR r2, [r3, #0] ; Pickup time-slice + CMP r2, #0 ; Is it non-active? + BEQ __tx_timer_no_time_slice ; Yes, skip time-slice processing +; +; /* Decrement the time_slice. */ +; _tx_timer_time_slice--; +; + SUB r2, r2, #1 ; Decrement the time-slice + STR r2, [r3, #0] ; Store new time-slice value +; +; /* Check for expiration. */ +; if (__tx_timer_time_slice == 0) +; + CMP r2, #0 ; Has it expired? + BNE __tx_timer_no_time_slice ; No, skip expiration processing +; +; /* Set the time-slice expired flag. */ +; _tx_timer_expired_time_slice = TX_TRUE; +; + LDR r3, =_tx_timer_expired_time_slice ; Pickup address of expired flag + MOV r0, #1 ; Build expired value + STR r0, [r3, #0] ; Set time-slice expiration flag +; +; } +; +__tx_timer_no_time_slice +; +; /* Test for timer expiration. */ +; if (*_tx_timer_current_ptr) +; { +; + LDR r1, =_tx_timer_current_ptr ; Pickup current timer pointer addr + LDR r0, [r1, #0] ; Pickup current timer + LDR r2, [r0, #0] ; Pickup timer list entry + CMP r2, #0 ; Is there anything in the list? + BEQ __tx_timer_no_timer ; No, just increment the timer +; +; /* Set expiration flag. */ +; _tx_timer_expired = TX_TRUE; +; + LDR r3, =_tx_timer_expired ; Pickup expiration flag address + MOV r2, #1 ; Build expired value + STR r2, [r3, #0] ; Set expired flag + B __tx_timer_done ; Finished timer processing +; +; } +; else +; { +__tx_timer_no_timer +; +; /* No timer expired, increment the timer pointer. */ +; _tx_timer_current_ptr++; +; + ADD r0, r0, #4 ; Move to next timer +; +; /* Check for wrap-around. */ +; if (_tx_timer_current_ptr == _tx_timer_list_end) +; + LDR r3, =_tx_timer_list_end ; Pickup addr of timer list end + LDR r2, [r3, #0] ; Pickup list end + CMP r0, r2 ; Are we at list end? + BNE __tx_timer_skip_wrap ; No, skip wrap-around logic +; +; /* Wrap to beginning of list. */ +; _tx_timer_current_ptr = _tx_timer_list_start; +; + LDR r3, =_tx_timer_list_start ; Pickup addr of timer list start + LDR r0, [r3, #0] ; Set current pointer to list start +; +__tx_timer_skip_wrap +; + STR r0, [r1, #0] ; Store new current timer pointer +; } +; +__tx_timer_done +; +; +; /* See if anything has expired. */ +; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired)) +; { +; + LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of expired flag + LDR r2, [r3, #0] ; Pickup time-slice expired flag + CMP r2, #0 ; Did a time-slice expire? + BNE __tx_something_expired ; If non-zero, time-slice expired + LDR r1, =_tx_timer_expired ; Pickup addr of other expired flag + LDR r0, [r1, #0] ; Pickup timer expired flag + CMP r0, #0 ; Did a timer expire? + BEQ __tx_timer_nothing_expired ; No, nothing expired +; +__tx_something_expired +; +; + STMDB sp!, {r0, lr} ; Save the lr register on the stack + ; and save r0 just to keep 8-byte alignment +; +; /* Did a timer expire? */ +; if (_tx_timer_expired) +; { +; + LDR r1, =_tx_timer_expired ; Pickup addr of expired flag + LDR r0, [r1, #0] ; Pickup timer expired flag + CMP r0, #0 ; Check for timer expiration + BEQ __tx_timer_dont_activate ; If not set, skip timer activation +; +; /* Process timer expiration. */ +; _tx_timer_expiration_process(); +; + BL _tx_timer_expiration_process ; Call the timer expiration handling routine +; +; } +__tx_timer_dont_activate +; +; /* Did time slice expire? */ +; if (_tx_timer_expired_time_slice) +; { +; + LDR r3, =_tx_timer_expired_time_slice ; Pickup addr of time-slice expired + LDR r2, [r3, #0] ; Pickup the actual flag + CMP r2, #0 ; See if the flag is set + BEQ __tx_timer_not_ts_expiration ; No, skip time-slice processing +; +; /* Time slice interrupted thread. */ +; _tx_thread_time_slice(); + + BL _tx_thread_time_slice ; Call time-slice processing +; +; } +; +__tx_timer_not_ts_expiration +; +; + LDMIA sp!, {r0, lr} ; Recover lr register (r0 is just there for + ; the 8-byte stack alignment +; +; } +; +__tx_timer_nothing_expired +; +#ifdef TX_THUMB + BX lr ; Return to caller +#else + MOV pc, lr ; Return to caller +#endif +; +;} + END +

9J?!Nbi%O@J}jw4MISTtOpL@PY&Tv&IiI4bEbsC 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