mirror of
https://github.com/eclipse-threadx/threadx.git
synced 2025-11-16 12:34:48 +00:00
Release 6.1.7
This commit is contained in:
7
ports_module/cortex_a7/ac5/example_build/build_all.bat
Normal file
7
ports_module/cortex_a7/ac5/example_build/build_all.bat
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
call build_threadx.bat
|
||||
call build_threadx_module_library.bat
|
||||
call build_threadx_module_sample.bat
|
||||
call ..\..\..\..\common_modules\utilities\module_to_c_array.exe sample_threadx_module.axf module_code.c
|
||||
powershell -Command "(gc module_code.c) -replace 'unsigned', '__align(4096) unsigned' | Out-File module_code.c"
|
||||
call build_threadx_module_manager_sample.bat
|
||||
290
ports_module/cortex_a7/ac5/example_build/build_threadx.bat
Normal file
290
ports_module/cortex_a7/ac5/example_build/build_threadx.bat
Normal file
@@ -0,0 +1,290 @@
|
||||
del tx.a
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork tx_initialize_low_level.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_stack_build.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_schedule.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_system_return.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_context_save.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_context_restore.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_interrupt_control.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_timer_interrupt.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_fiq_context_restore.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_fiq_context_save.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_fiq_nesting_end.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_fiq_nesting_start.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_interrupt_disable.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_interrupt_restore.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_irq_nesting_end.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_irq_nesting_start.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/tx_thread_vectored_context_save.s
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_allocate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_cleanup.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_performance_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_performance_system_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_release.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_allocate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_cleanup.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_performance_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_pool_search.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_byte_release.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_cleanup.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_performance_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_performance_system_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_set.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_event_flags_set_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_initialize_high_level.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_initialize_kernel_enter.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_initialize_kernel_setup.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_cleanup.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_performance_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_performance_system_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_priority_change.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_mutex_put.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_cleanup.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_flush.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_front_send.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_performance_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_performance_system_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_receive.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_send.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_queue_send_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_ceiling_put.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_cleanup.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_performance_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_performance_system_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_put.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_semaphore_put_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_entry_exit_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_identify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_performance_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_performance_system_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_preemption_change.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_priority_change.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_relinquish.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_reset.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_resume.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_shell_entry.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_sleep.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_stack_analyze.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_stack_error_handler.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_stack_error_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_suspend.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_system_preempt_check.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_system_resume.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_system_suspend.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_terminate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_time_slice.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_time_slice_change.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_timeout.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_thread_wait_abort.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_time_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_time_set.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_activate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_change.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_deactivate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_expiration_process.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_performance_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_performance_system_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_system_activate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_system_deactivate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_timer_thread_entry.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_enable.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_disable.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_interrupt_control.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_isr_enter_insert.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_isr_exit_insert.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_object_register.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_object_unregister.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_user_event_insert.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_buffer_full_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_event_filter.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_event_unfilter.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_allocate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_release.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_allocate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_pool_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_pool_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_pool_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_pool_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_byte_release.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_set.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_event_flags_set_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_mutex_put.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_flush.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_front_send.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_receive.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_send.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_queue_send_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_ceiling_put.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_prioritize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_put.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_semaphore_put_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_entry_exit_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_preemption_change.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_priority_change.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_relinquish.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_reset.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_resume.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_suspend.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_terminate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_time_slice_change.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_thread_wait_abort.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_activate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_change.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_deactivate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_delete.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_info_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_alignment_adjust.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_application_request.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_callback_request.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_event_flags_notify_trampoline.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_external_memory_enable.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_file_load.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_in_place_load.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_internal_load.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_mm_initialize.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_kernel_dispatch.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_maximum_module_priority_set.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_memory_fault_handler.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_memory_fault_notify.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_memory_load.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_allocate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_deallocate.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_pointer_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_pointer_get_extended.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_object_pool_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_properties_get.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_queue_notify_trampoline.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_semaphore_notify_trampoline.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_manager/src/txm_module_manager_mm_register_setup.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_start.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_stop.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_thread_create.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_thread_notify_trampoline.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_thread_reset.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_timer_notify_trampoline.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_unload.c
|
||||
armcc -g -O0 --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_manager/src/txm_module_manager_util.c
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/txm_module_manager_thread_stack_build.s
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork ../module_manager/src/txm_module_manager_user_mode_entry.s
|
||||
|
||||
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_initialize_low_level.o tx_thread_fiq_context_restore.o tx_thread_fiq_context_save.o tx_thread_fiq_nesting_end.o tx_thread_fiq_nesting_start.o tx_thread_interrupt_disable.o
|
||||
armar -r tx.a tx_thread_interrupt_restore.o tx_thread_irq_nesting_end.o tx_thread_irq_nesting_start.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
|
||||
|
||||
armar -r tx.a txm_module_manager_alignment_adjust.o txm_module_manager_application_request.o txm_module_manager_callback_request.o
|
||||
armar -r tx.a txm_module_manager_event_flags_notify_trampoline.o txm_module_manager_external_memory_enable.o txm_module_manager_file_load.o
|
||||
armar -r tx.a txm_module_manager_in_place_load.o txm_module_manager_initialize.o txm_module_manager_mm_initialize.o
|
||||
armar -r tx.a txm_module_manager_kernel_dispatch.o txm_module_manager_maximum_module_priority_set.o txm_module_manager_memory_fault_handler.o
|
||||
armar -r tx.a txm_module_manager_memory_fault_notify.o txm_module_manager_memory_load.o txm_module_manager_object_pointer_get.o
|
||||
armar -r tx.a txm_module_manager_object_pool_create.o txm_module_manager_queue_notify_trampoline.o txm_module_manager_semaphore_notify_trampoline.o
|
||||
armar -r tx.a txm_module_manager_mm_register_setup.o txm_module_manager_start.o txm_module_manager_stop.o
|
||||
armar -r tx.a txm_module_manager_thread_create.o txm_module_manager_thread_notify_trampoline.o txm_module_manager_thread_reset.o
|
||||
armar -r tx.a txm_module_manager_timer_notify_trampoline.o txm_module_manager_unload.o txm_module_manager_thread_stack_build.o
|
||||
armar -r tx.a txm_module_manager_user_mode_entry.o
|
||||
armar -r tx.a txm_module_manager_internal_load.o
|
||||
armar -r tx.a txm_module_manager_object_allocate.o
|
||||
armar -r tx.a txm_module_manager_object_deallocate.o
|
||||
armar -r tx.a txm_module_manager_object_pointer_get_extended.o
|
||||
armar -r tx.a txm_module_manager_properties_get.o
|
||||
armar -r tx.a txm_module_manager_util.o
|
||||
@@ -0,0 +1,120 @@
|
||||
del txm.a
|
||||
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_allocate.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_create.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_delete.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_performance_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_performance_system_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_pool_prioritize.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_block_release.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_allocate.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_create.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_delete.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_performance_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_performance_system_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_pool_prioritize.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_byte_release.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_create.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_delete.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_performance_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_performance_system_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_set.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_event_flags_set_notify.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_application_request.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_callback_request_thread_entry.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_object_allocate.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_object_deallocate.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_object_pointer_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../module_lib/src/txm_module_thread_shell_entry.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_module_thread_system_suspend.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_create.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_delete.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_performance_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_performance_system_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_prioritize.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_mutex_put.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_create.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_delete.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_flush.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_front_send.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_performance_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_performance_system_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_prioritize.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_receive.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_send.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_queue_send_notify.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_ceiling_put.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_create.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_delete.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_performance_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_performance_system_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_prioritize.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_put.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_semaphore_put_notify.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_create.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_delete.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_entry_exit_notify.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_identify.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_interrupt_control.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_performance_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_performance_system_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_preemption_change.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_priority_change.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_relinquish.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_reset.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_resume.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_sleep.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_stack_error_notify.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_suspend.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_terminate.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_time_slice_change.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_thread_wait_abort.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_time_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_time_set.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_activate.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_change.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_create.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_deactivate.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_delete.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_performance_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_timer_performance_system_info_get.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_buffer_full_notify.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_disable.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_enable.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_event_filter.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_event_unfilter.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_isr_enter_insert.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_isr_exit_insert.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc ../../../../common_modules/module_lib/src/txm_trace_user_event_insert.c
|
||||
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork/ropi/rwpi ../module_lib/src/txm_module_initialize.s
|
||||
|
||||
armar --create txm.a txm_block_allocate.o txm_block_pool_create.o txm_block_pool_delete.o txm_block_pool_info_get.o txm_block_pool_performance_info_get.o txm_block_pool_performance_system_info_get.o
|
||||
armar -r txm.a txm_block_pool_prioritize.o txm_block_release.o
|
||||
armar -r txm.a txm_byte_allocate.o txm_byte_pool_create.o txm_byte_pool_delete.o txm_byte_pool_info_get.o txm_byte_pool_performance_info_get.o txm_byte_pool_performance_system_info_get.o
|
||||
armar -r txm.a txm_byte_pool_prioritize.o txm_byte_release.o
|
||||
armar -r txm.a txm_event_flags_create.o txm_event_flags_delete.o txm_event_flags_get.o txm_event_flags_info_get.o txm_event_flags_performance_info_get.o txm_event_flags_performance_system_info_get.o
|
||||
armar -r txm.a txm_event_flags_set.o txm_event_flags_set_notify.o
|
||||
armar -r txm.a txm_module_application_request.o txm_module_callback_request_thread_entry.o txm_module_initialize.o txm_module_object_allocate.o txm_module_object_deallocate.o txm_module_object_pointer_get.o txm_module_thread_shell_entry.o txm_module_thread_system_suspend.o
|
||||
armar -r txm.a txm_mutex_create.o txm_mutex_delete.o txm_mutex_get.o txm_mutex_info_get.o txm_mutex_performance_info_get.o txm_mutex_performance_system_info_get.o txm_mutex_prioritize.o txm_mutex_put.o
|
||||
armar -r txm.a txm_queue_create.o txm_queue_delete.o txm_queue_flush.o txm_queue_front_send.o txm_queue_info_get.o txm_queue_performance_info_get.o txm_queue_performance_system_info_get.o
|
||||
armar -r txm.a txm_queue_prioritize.o txm_queue_receive.o txm_queue_send.o txm_queue_send_notify.o
|
||||
armar -r txm.a txm_semaphore_ceiling_put.o txm_semaphore_create.o txm_semaphore_delete.o txm_semaphore_get.o txm_semaphore_info_get.o txm_semaphore_performance_info_get.o txm_semaphore_performance_system_info_get.o
|
||||
armar -r txm.a txm_semaphore_prioritize.o txm_semaphore_put.o txm_semaphore_put_notify.o
|
||||
armar -r txm.a txm_thread_create.o txm_thread_delete.o txm_thread_entry_exit_notify.o txm_thread_identify.o txm_thread_info_get.o txm_thread_interrupt_control.o txm_thread_performance_info_get.o
|
||||
armar -r txm.a txm_thread_performance_system_info_get.o txm_thread_preemption_change.o txm_thread_priority_change.o txm_thread_relinquish.o txm_thread_reset.o txm_thread_resume.o
|
||||
armar -r txm.a txm_thread_sleep.o txm_thread_stack_error_notify.o txm_thread_suspend.o txm_thread_terminate.o txm_thread_time_slice_change.o txm_thread_wait_abort.o
|
||||
armar -r txm.a txm_time_get.o txm_time_set.o
|
||||
armar -r txm.a txm_timer_activate.o txm_timer_change.o txm_timer_create.o txm_timer_deactivate.o txm_timer_delete.o txm_timer_info_get.o txm_timer_performance_info_get.o txm_timer_performance_system_info_get.o
|
||||
armar -r txm.a txm_trace_buffer_full_notify.o txm_trace_disable.o txm_trace_enable.o txm_trace_event_filter.o txm_trace_event_unfilter.o txm_trace_isr_enter_insert.o txm_trace_isr_exit_insert.o txm_trace_user_event_insert.o
|
||||
@@ -0,0 +1,5 @@
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=interwork tx_initialize_low_level.s
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc sample_threadx_module_manager.c
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c module_code.c
|
||||
armlink -d -o sample_threadx_module_manager.axf --elf --ro 0x80000000 --first tx_initialize_low_level.o(VECTORS) --remove --map --symbols --list sample_threadx_module_manager.map tx_initialize_low_level.o sample_threadx_module_manager.o module_code.o tx.a
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=/interwork/ropi/rwpi txm_module_preamble.s
|
||||
armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c --apcs=/interwork/ropi/rwpi --lower_ropi -I../inc -I../../../../common/inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc sample_threadx_module.c
|
||||
armlink -d -o sample_threadx_module.axf --elf --ro 0 --first txm_module_preamble.o(Init) --entry=_txm_module_thread_shell_entry --ropi --rwpi --remove --map --symbols --list sample_threadx_module.map txm_module_preamble.o sample_threadx_module.o txm.a
|
||||
|
||||
BIN
ports_module/cortex_a7/ac5/example_build/module_code.c
Normal file
BIN
ports_module/cortex_a7/ac5/example_build/module_code.c
Normal file
Binary file not shown.
427
ports_module/cortex_a7/ac5/example_build/sample_threadx_module.c
Normal file
427
ports_module/cortex_a7/ac5/example_build/sample_threadx_module.c
Normal file
@@ -0,0 +1,427 @@
|
||||
/* This is a small demo of the high-performance ThreadX kernel running as a module. It includes
|
||||
examples of eight threads of different priorities, using a message queue, semaphore, mutex,
|
||||
event flags group, byte pool, and block pool. */
|
||||
|
||||
/* Specify that this is a module! */
|
||||
|
||||
#define TXM_MODULE
|
||||
|
||||
|
||||
/* Include the ThreadX module definitions. */
|
||||
|
||||
#include "txm_module.h"
|
||||
|
||||
|
||||
/* Define constants. */
|
||||
|
||||
#define DEMO_STACK_SIZE 1024
|
||||
#define DEMO_BYTE_POOL_SIZE 9120
|
||||
#define DEMO_BLOCK_POOL_SIZE 100
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the pool space in the bss section of the module. ULONG is used to
|
||||
get the word alignment. */
|
||||
|
||||
ULONG demo_module_pool_space[DEMO_BYTE_POOL_SIZE / 4];
|
||||
|
||||
|
||||
/* 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;
|
||||
ULONG semaphore_0_puts;
|
||||
ULONG event_0_sets;
|
||||
ULONG queue_0_sends;
|
||||
|
||||
/* 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);
|
||||
|
||||
void semaphore_0_notify(TX_SEMAPHORE *semaphore_ptr)
|
||||
{
|
||||
|
||||
if (semaphore_ptr == semaphore_0)
|
||||
semaphore_0_puts++;
|
||||
}
|
||||
|
||||
|
||||
void event_0_notify(TX_EVENT_FLAGS_GROUP *event_flag_group_ptr)
|
||||
{
|
||||
|
||||
if (event_flag_group_ptr == event_flags_0)
|
||||
event_0_sets++;
|
||||
}
|
||||
|
||||
|
||||
void queue_0_notify(TX_QUEUE *queue_ptr)
|
||||
{
|
||||
|
||||
if (queue_ptr == queue_0)
|
||||
queue_0_sends++;
|
||||
}
|
||||
|
||||
|
||||
/* Define the module start function. */
|
||||
|
||||
void demo_module_start(ULONG id)
|
||||
{
|
||||
|
||||
CHAR *pointer;
|
||||
|
||||
/* Allocate all the objects. In MMU mode, modules cannot allocate control blocks within
|
||||
their own memory area so they cannot corrupt the resident portion of ThreadX by overwriting
|
||||
the control block(s). */
|
||||
txm_module_object_allocate((void *) &thread_0, sizeof(TX_THREAD));
|
||||
txm_module_object_allocate((void *) &thread_1, sizeof(TX_THREAD));
|
||||
txm_module_object_allocate((void *) &thread_2, sizeof(TX_THREAD));
|
||||
txm_module_object_allocate((void *) &thread_3, sizeof(TX_THREAD));
|
||||
txm_module_object_allocate((void *) &thread_4, sizeof(TX_THREAD));
|
||||
txm_module_object_allocate((void *) &thread_5, sizeof(TX_THREAD));
|
||||
txm_module_object_allocate((void *) &thread_6, sizeof(TX_THREAD));
|
||||
txm_module_object_allocate((void *) &thread_7, sizeof(TX_THREAD));
|
||||
txm_module_object_allocate((void *) &queue_0, sizeof(TX_QUEUE));
|
||||
txm_module_object_allocate((void *) &semaphore_0, sizeof(TX_SEMAPHORE));
|
||||
txm_module_object_allocate((void *) &mutex_0, sizeof(TX_MUTEX));
|
||||
txm_module_object_allocate((void *) &event_flags_0, sizeof(TX_EVENT_FLAGS_GROUP));
|
||||
txm_module_object_allocate((void *) &byte_pool_0, sizeof(TX_BYTE_POOL));
|
||||
txm_module_object_allocate((void *) &block_pool_0, sizeof(TX_BLOCK_POOL));
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
tx_byte_pool_create(byte_pool_0, "module byte pool 0", demo_module_pool_space, 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module 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, "module queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
|
||||
|
||||
tx_queue_send_notify(queue_0, queue_0_notify);
|
||||
|
||||
/* Create the semaphore used by threads 3 and 4. */
|
||||
tx_semaphore_create(semaphore_0, "module semaphore 0", 1);
|
||||
|
||||
tx_semaphore_put_notify(semaphore_0, semaphore_0_notify);
|
||||
|
||||
/* Create the event flags group used by threads 1 and 5. */
|
||||
tx_event_flags_create(event_flags_0, "module event flags 0");
|
||||
|
||||
tx_event_flags_set_notify(event_flags_0, event_0_notify);
|
||||
|
||||
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
|
||||
tx_mutex_create(mutex_0, "module 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, "module 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;
|
||||
|
||||
/* Test external/shared memory. */
|
||||
*(ULONG *) 0x90000000 = 0xdeadbeef;
|
||||
*(ULONG *) 0x90000FFC = 0xfeed0add;
|
||||
*(ULONG *) 0x90001000 = 0xfedcba01;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/* Small demonstration of the ThreadX module manager. This demonstration assumes the program
|
||||
manager is loaded at 0 and that RAM addresses 0x200000 through 0x400000 are available for
|
||||
use. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "txm_module.h"
|
||||
|
||||
|
||||
#define DEMO_STACK_SIZE 1024
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
TX_THREAD module_manager;
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
void module_manager_entry(ULONG thread_input);
|
||||
|
||||
/* Define the module object pool area. */
|
||||
UCHAR object_memory[16384];
|
||||
|
||||
/* Define the module data pool area. */
|
||||
#define MODULE_DATA_SIZE 65536
|
||||
unsigned char module_data_area[MODULE_DATA_SIZE];
|
||||
|
||||
/* Define a module instance. */
|
||||
TXM_MODULE_INSTANCE my_module1;
|
||||
TXM_MODULE_INSTANCE my_module2;
|
||||
|
||||
/* Module code is in an array created by module_to_c_array utility. */
|
||||
extern unsigned char module_code[];
|
||||
|
||||
/* Define the count of memory faults. */
|
||||
ULONG memory_faults;
|
||||
|
||||
/* Define fault handler. */
|
||||
VOID module_fault_handler(TX_THREAD *thread, TXM_MODULE_INSTANCE *module)
|
||||
{
|
||||
/* Just increment the fault counter. */
|
||||
memory_faults++;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
||||
/* Create the module manager thread. */
|
||||
tx_thread_create(&module_manager, "Module Manager Thread", module_manager_entry, 0,
|
||||
first_unused_memory, DEMO_STACK_SIZE,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
void module_manager_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
/* Initialize the module manager. */
|
||||
txm_module_manager_initialize((VOID *) module_data_area, MODULE_DATA_SIZE);
|
||||
|
||||
/* Create a pool for module objects. */
|
||||
txm_module_manager_object_pool_create(object_memory, sizeof(object_memory));
|
||||
|
||||
/* Register a fault handler. */
|
||||
txm_module_manager_memory_fault_notify(module_fault_handler);
|
||||
|
||||
/* Initialize MMU. */
|
||||
txm_module_manager_mm_initialize();
|
||||
|
||||
/* Load the module that is already there, in this example it is placed there by the multiple image download. */
|
||||
txm_module_manager_in_place_load(&my_module1, "my module1", (VOID *) module_code);
|
||||
|
||||
/* Load a second instance of the module. */
|
||||
//txm_module_manager_in_place_load(&my_module2, "my module2", (VOID *) module_code);
|
||||
|
||||
/* Enable shared memory regions for one module. */
|
||||
//txm_module_manager_external_memory_enable(&my_module2, (void*)0x90000000, 0x010000, 0x3F);
|
||||
|
||||
/* Start the modules. */
|
||||
txm_module_manager_start(&my_module1);
|
||||
//txm_module_manager_start(&my_module2);
|
||||
|
||||
/* Sleep for a while and let the modules run.... */
|
||||
tx_thread_sleep(50);
|
||||
|
||||
/* Thread 0 in module1 should be terminated due to violating the MMU. */
|
||||
|
||||
/* Stop the modules. */
|
||||
txm_module_manager_stop(&my_module1);
|
||||
txm_module_manager_stop(&my_module2);
|
||||
|
||||
/* Unload the modules. */
|
||||
txm_module_manager_unload(&my_module1);
|
||||
txm_module_manager_unload(&my_module2);
|
||||
|
||||
/* Reload the modules. */
|
||||
txm_module_manager_in_place_load(&my_module2, "my module2", (VOID *) module_code);
|
||||
txm_module_manager_in_place_load(&my_module1, "my module1", (VOID *) module_code);
|
||||
|
||||
/* Give both modules shared memory. */
|
||||
txm_module_manager_external_memory_enable(&my_module2, (void*)0x90000000, 0x010000, 0x3F);
|
||||
txm_module_manager_external_memory_enable(&my_module1, (void*)0x90000000, 0x010000, 0x3F);
|
||||
|
||||
/* Start the module again. */
|
||||
txm_module_manager_start(&my_module2);
|
||||
txm_module_manager_start(&my_module1);
|
||||
|
||||
/* Now just spin... */
|
||||
while(1)
|
||||
{
|
||||
tx_thread_sleep(100);
|
||||
/* Thread 0 and 5 in module1 should not exist because they violate the maximum priority. */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
41
ports_module/cortex_a7/ac5/example_build/scatter.scat
Normal file
41
ports_module/cortex_a7/ac5/example_build/scatter.scat
Normal file
@@ -0,0 +1,41 @@
|
||||
;**************************************************
|
||||
; Copyright (c) 2011 ARM Ltd. All rights reserved.
|
||||
;**************************************************
|
||||
|
||||
; This scatter-file places application code, data, stack and heap at base address 0x80000000.
|
||||
; Using a scatter-file with ARM_LIB_STACKHEAP eliminates the need to set stack-limit or heap-base in the debugger.
|
||||
|
||||
|
||||
SDRAM 0x80000000
|
||||
{
|
||||
VECTORS +0
|
||||
{
|
||||
* (VECTORS, +FIRST) ; Vector table and other (assembler) startup code
|
||||
* (InRoot$$Sections) ; All (library) code that must be in a root region
|
||||
}
|
||||
|
||||
RO_CODE +0
|
||||
{ * (+RO-CODE) } ; Application RO code (.text)
|
||||
|
||||
RO_DATA +0
|
||||
{ * (+RO-DATA) } ; Application RO data (.constdata)
|
||||
|
||||
RW_DATA +0
|
||||
{ * (+RW) } ; Application RW data (.data)
|
||||
|
||||
ZI_DATA +0
|
||||
{ * (+ZI) } ; Application ZI data (.bss)
|
||||
|
||||
ARM_LIB_HEAP 0x80040000 EMPTY 0x00040000 ; Application heap
|
||||
{ }
|
||||
|
||||
ARM_LIB_STACK 0x80090000 EMPTY -0x00010000 ; Application (SVC mode) stack
|
||||
{ }
|
||||
|
||||
IRQ_STACK 0x800A0000 EMPTY -0x00010000 ; IRQ mode stack
|
||||
{ }
|
||||
|
||||
TTB 0x80100000 EMPTY 0x4000 ; Level-1 Translation Table for MMU
|
||||
{ }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,659 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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"
|
||||
;
|
||||
;
|
||||
|
||||
THUMB_MASK EQU 0x20 ; Thumb bit (5) of CPSR/SPSR
|
||||
FIQ_MODE EQU 0x11 ; FIQ mode
|
||||
IRQ_MODE EQU 0x12 ; IRQ mode
|
||||
SVC_MODE EQU 0x13 ; SVC mode
|
||||
ABT_MODE EQU 0x17 ; ABT mode
|
||||
SYS_MODE EQU 0x1F ; SYS mode
|
||||
|
||||
HEAP_SIZE EQU 4096 ; Heap size
|
||||
FIQ_STACK_SIZE EQU 512 ; FIQ stack size
|
||||
SYS_STACK_SIZE EQU 1024 ; SYS stack size
|
||||
IRQ_STACK_SIZE EQU 1024 ; IRQ stack size
|
||||
SVC_STACK_SIZE EQU 512 ; SVC stack size
|
||||
ABT_STACK_SIZE EQU 512 ; ABT stack size
|
||||
|
||||
VFPEnable EQU 0x40000000 ; VFP enable value
|
||||
|
||||
;
|
||||
;
|
||||
IMPORT __tx_swi_interrupt
|
||||
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 VECTORS, CODE, READONLY
|
||||
PRESERVE8
|
||||
;
|
||||
;/* Define the default Cortex-A7 vector area. This should be located or copied to 0. */
|
||||
;
|
||||
EXPORT __vectors
|
||||
__vectors
|
||||
LDR pc,=Reset_Vector ; 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
|
||||
;
|
||||
;
|
||||
EXPORT Reset_Vector
|
||||
Reset_Vector
|
||||
|
||||
IF {TARGET_FPU_VFP} = {TRUE}
|
||||
MRC p15, 0, r1, c1, c0, 2 ; r1 = Access Control Register
|
||||
ORR r1, r1, #(0xf << 20) ; Enable full access for p10,11
|
||||
MCR p15, 0, r1, c1, c0, 2 ; Access Control Register = r1
|
||||
MOV r1, #0
|
||||
MCR p15, 0, r1, c7, c5, 4 ; Flush prefetch buffer because of FMXR below and
|
||||
; CP 10 & 11 were only just enabled
|
||||
MOV r0, #VFPEnable ; Enable VFP itself
|
||||
FMXR FPEXC, r0 ; FPEXC = r0
|
||||
ENDIF
|
||||
|
||||
B __main
|
||||
;
|
||||
;
|
||||
AREA ||.text||, CODE, READONLY
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_initialize_low_level Cortex-A7/MMU/AC5 */
|
||||
;/* 6.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* Scott Larson, 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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 Scott Larson Initial Version 6.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. */
|
||||
;
|
||||
|
||||
; Set vector table.
|
||||
LDR r0, = __vectors
|
||||
MCR p15, 0, r0, c12, c0, 0
|
||||
|
||||
|
||||
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
|
||||
MOV r3, lr ; Save LR
|
||||
|
||||
LDR r2, =SYS_STACK_SIZE ; Pickup stack size
|
||||
CPS #SYS_MODE ; 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
|
||||
MOV lr, r3 ; Restore LR
|
||||
|
||||
LDR r2, =SVC_STACK_SIZE ; Pickup SVC stack size
|
||||
CPS #SVC_MODE ; Enter SVC mode
|
||||
ADD r1, r1, r2 ; Calculate start of SVC stack
|
||||
BIC r1, r1, #7 ; Ensure 8-byte alignment
|
||||
MOV sp, r1 ; Setup SVC stack pointer
|
||||
|
||||
LDR r2, =IRQ_STACK_SIZE ; Pickup IRQ stack size
|
||||
CPS #IRQ_MODE ; 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
|
||||
|
||||
LDR r2, =FIQ_STACK_SIZE ; Pickup FIQ stack size
|
||||
CPS #FIQ_MODE ; 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, =ABT_STACK_SIZE ; Pickup ABT stack size
|
||||
CPS #ABT_MODE ; Enter ABT mode
|
||||
ADD r1, r1, r2 ; Calculate start of ABT stack
|
||||
BIC r1, r1, #7 ; Ensure 8-byte alignment
|
||||
MOV sp, r1 ; Setup ABT stack pointer
|
||||
|
||||
CPS #SYS_MODE ; Enter SYS mode
|
||||
;
|
||||
; /* Save the first available memory address. */
|
||||
; _tx_initialize_unused_memory = (VOID_PTR) |Image$$ZI$$Limit| + HEAP + SYS_STACK + SVC_STACK + IRQ_STACK + FIQ_STACK + ABT_STACK;
|
||||
;
|
||||
ADD r0, r1, #4 ; Increment to next free word
|
||||
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. */
|
||||
;
|
||||
|
||||
GIC1_CPU_INTERFACE_BASE EQU 0x2C002000
|
||||
GIC1_DIST_INTERFACE_BASE EQU 0x2C001000
|
||||
|
||||
PUSH {r4-r12, lr}
|
||||
ldr r2, =GIC1_CPU_INTERFACE_BASE
|
||||
ldr r7, =GIC1_DIST_INTERFACE_BASE
|
||||
; Enable GIC
|
||||
mov r3, #0x1
|
||||
str r3, [r2, #0x0000]
|
||||
; Enable GIC forwarding
|
||||
str r3, [r7, #0x000]
|
||||
; Set Binary Point Register to 0
|
||||
eor r3, r3, r3
|
||||
str r3, [r2, #0x0008]
|
||||
|
||||
; At this point GIC is enabled
|
||||
; All INTS are disabled / not configured
|
||||
|
||||
; r0 - interrupt number
|
||||
; r1 - priority
|
||||
; r2 - interrupt type (edge / level trig.)
|
||||
ldr r0, =34
|
||||
ldr r1, =0xF0
|
||||
ldr r2, =1
|
||||
|
||||
ldr r7, =GIC1_DIST_INTERFACE_BASE
|
||||
|
||||
; enable the interrupt in isenable register
|
||||
mov r4, #0x100 ; ISEN REG offset base
|
||||
mov r5, r0, LSR #5 ; Interrupt_Number DIV 5
|
||||
add r4, r4, r5, LSL #2 ; final offset from GIC DIST BASE
|
||||
and r5, r0, #31 ; bit number
|
||||
mov r8, #1
|
||||
|
||||
|
||||
ldr r6, [r7, r4]
|
||||
orr r6, r6, r8, LSL r5
|
||||
str r6, [r7, r4]
|
||||
|
||||
; setup priority
|
||||
mov r4, #0x400
|
||||
mov r5, r0, LSR #2 ; Interrupt_Number DIV 4
|
||||
add r4, r4, r5, LSL #2 ; final offset from GIC DIST BASE
|
||||
and r5, r0, #3 ; Int_Num MOD 4
|
||||
lsl r5, #3
|
||||
lsl r1, r5
|
||||
|
||||
ldr r6, [r7, r4]
|
||||
orr r1, r6, r1
|
||||
str r1, [r7, r4]
|
||||
|
||||
; set up processor target
|
||||
mov r4, #0x800
|
||||
mov r5, r0, LSR #2 ; Interrupt_Number DIV 4
|
||||
add r4, r4, r5, LSL #2 ; final offset from GIC DIST BASE
|
||||
and r5, r0, #3 ; Int_Num MOD 4
|
||||
lsl r5, #3
|
||||
mov r1, #0xff
|
||||
lsl r1, r5
|
||||
|
||||
ldr r6, [r7, r4]
|
||||
orr r1, r6, r1
|
||||
str r1, [r7, r4]
|
||||
|
||||
; set up interrupt type
|
||||
mov r4, #0xC00
|
||||
mov r5, r0, LSR #4
|
||||
add r4, r4, r5, LSL #2 ; offset from base
|
||||
|
||||
; field
|
||||
and r5, r0, #15
|
||||
lsl r5, #1
|
||||
lsl r2, r5
|
||||
|
||||
ldr r6, [r7, r4]
|
||||
orr r2, r6, r2
|
||||
str r2, [r7, r4]
|
||||
|
||||
ldr r2, =GIC1_CPU_INTERFACE_BASE
|
||||
|
||||
; set the interrupt id prio mask
|
||||
; Max Priorities = 32.
|
||||
; mask = (32 - 1) << 3
|
||||
mov r3, #0xF8
|
||||
str r3, [r2, #0x0004]
|
||||
|
||||
CPSIE if
|
||||
|
||||
; Timer base
|
||||
ldr r0, =0x1C110000
|
||||
|
||||
; get the timer id
|
||||
ldr r1, [r0, #0xfe0]
|
||||
|
||||
; set count value in load register
|
||||
ldr r1, =0x00000020
|
||||
str r1, [r0, #00]
|
||||
|
||||
; enable the timer
|
||||
; periodic mode
|
||||
mov r1, #0xe2
|
||||
str r1, [r0, #08]
|
||||
|
||||
POP {r4-r12, lr}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;
|
||||
; /* Done, return to caller. */
|
||||
;
|
||||
BX lr ; Return to caller
|
||||
;}
|
||||
;
|
||||
;
|
||||
;/* 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_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. */
|
||||
;
|
||||
;
|
||||
BL _tx_timer_interrupt ; Timer interrupt handler
|
||||
|
||||
; clear timer interrupt
|
||||
ldr r0, =0x1C110000
|
||||
eor r1, r1, r1
|
||||
str r1, [r0, #0x0C]
|
||||
|
||||
_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
|
||||
|
||||
|
||||
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* __tx_prefetch_handler & __tx_abort_handler Cortex-A7/MMU/AC5 */
|
||||
;/* 6.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* Scott Larson, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function handles MMU exceptions and fills the */
|
||||
;/* _txm_module_manager_memory_fault_info struct. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* _txm_module_manager_memory_fault_handler */
|
||||
;/* _tx_execution_thread_exit */
|
||||
;/* _tx_thread_schedule */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* MMU exceptions */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
|
||||
; *******************************************************************
|
||||
; MMU Exception Handling
|
||||
; *******************************************************************
|
||||
EXTERN _tx_thread_system_state
|
||||
EXTERN _txm_module_manager_memory_fault_info
|
||||
EXTERN _tx_thread_current_ptr
|
||||
EXTERN _txm_module_manager_memory_fault_handler
|
||||
EXTERN _tx_execution_thread_exit
|
||||
EXTERN _tx_thread_schedule
|
||||
|
||||
EXPORT __tx_prefetch_handler
|
||||
EXPORT __tx_abort_handler
|
||||
__tx_prefetch_handler
|
||||
__tx_abort_handler
|
||||
STMDB sp!, {r0-r3} ; Save some working registers
|
||||
LDR r3, =_tx_thread_system_state ; Pickup address of system state var
|
||||
LDR r2, [r3, #0] ; Pickup system state
|
||||
ADD r2, r2, #1 ; Increment the interrupt counter
|
||||
STR r2, [r3, #0] ; Store it back in the variable
|
||||
SUB lr, lr, #4 ; Adjust point of exception
|
||||
;
|
||||
; /* Now pickup and store all the fault related information. */
|
||||
;
|
||||
; Pickup the memory fault info struct
|
||||
LDR r3, =_txm_module_manager_memory_fault_info
|
||||
LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address
|
||||
LDR r1, [r0] ; Pickup the current thread pointer
|
||||
STR r1, [r3, #0] ; Save current thread pointer
|
||||
STR lr, [r3, #4] ; Save point of fault
|
||||
MRC p15, 0, r0, c6, c0, 0 ; Read DFAR
|
||||
STR r0, [r3, #8] ; Save DFAR
|
||||
MRC p15, 0, r0, c5, c0, 0 ; Read DFSR
|
||||
STR r0, [r3, #12] ; Save DFSR
|
||||
MRC p15, 0, r0, c6, c0, 2 ; Read IFAR
|
||||
STR r0, [r3, #16] ; Save IFAR
|
||||
MRC p15, 0, r0, c5, c0, 1 ; Read IFSR
|
||||
STR r0, [r3, #20] ; Save IFSR
|
||||
|
||||
; Save registers r0-r12
|
||||
POP {r0-r2}
|
||||
STR r0, [r3, #28] ; Save r0
|
||||
STR r1, [r3, #32] ; Save r1
|
||||
STR r2, [r3, #36] ; Save r2
|
||||
POP {r0}
|
||||
STR r0, [r3, #40] ; Save r3
|
||||
STR r4, [r3, #44] ; Save r4
|
||||
STR r5, [r3, #48] ; Save r5
|
||||
STR r6, [r3, #52] ; Save r6
|
||||
STR r7, [r3, #56] ; Save r7
|
||||
STR r8, [r3, #60] ; Save r8
|
||||
STR r9, [r3, #64] ; Save r9
|
||||
STR r10,[r3, #68] ; Save r10
|
||||
STR r11,[r3, #72] ; Save r11
|
||||
STR r12,[r3, #76] ; Save r12
|
||||
|
||||
CPS #SYS_MODE ; Enter SYS mode
|
||||
MOV r0, lr ; Pickup lr
|
||||
MOV r1, sp ; Pickup sp
|
||||
CPS #ABT_MODE ; Back to ABT mode
|
||||
STR r0, [r3, #80] ; Save lr
|
||||
STR r1, [r3, #24] ; Save sp
|
||||
MRS r0, SPSR ; Pickup SPSR
|
||||
STR r0, [r3, #84] ; Save SPSR
|
||||
ORR r0, r0, #SYS_MODE ; Return into SYS mode
|
||||
BIC r0, r0, #THUMB_MASK ; Clear THUMB mode
|
||||
MSR SPSR_c, r0 ; Save SPSR
|
||||
|
||||
; Call memory manager fault handler
|
||||
BL _txm_module_manager_memory_fault_handler
|
||||
|
||||
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 r0, =_tx_thread_system_state ; Pickup address of system state
|
||||
LDR r1, [r0] ; Pickup system state
|
||||
SUB r1, r1, #1 ; Decrement
|
||||
STR r1, [r0] ; Store new system state
|
||||
|
||||
MOV r1, #0 ; Build NULL value
|
||||
LDR r0, =_tx_thread_current_ptr ; Pickup address of current thread pointer
|
||||
STR r1, [r0] ; Clear current thread pointer
|
||||
|
||||
; Return from exception
|
||||
LDR lr, =_tx_thread_schedule ; Load scheduler address
|
||||
MOVS pc, lr ; Return to scheduler
|
||||
; *******************************************************************
|
||||
; End of MMU exception handling.
|
||||
; *******************************************************************
|
||||
|
||||
;
|
||||
; /* 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
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
AREA Init, CODE, READONLY
|
||||
|
||||
; /* Define public symbols. */
|
||||
|
||||
EXPORT __txm_module_preamble
|
||||
|
||||
|
||||
; /* Define application-specific start/stop entry points for the module. */
|
||||
|
||||
IMPORT demo_module_start
|
||||
|
||||
|
||||
; /* Define common external refrences. */
|
||||
|
||||
IMPORT _txm_module_thread_shell_entry
|
||||
IMPORT _txm_module_callback_request_thread_entry
|
||||
IMPORT |Image$$ER_RO$$Length|
|
||||
IMPORT |Image$$ER_RW$$Length|
|
||||
|
||||
|
||||
__txm_module_preamble
|
||||
DCD 0x4D4F4455 ; Module ID
|
||||
DCD 0x6 ; Module Major Version
|
||||
DCD 0x1 ; Module Minor Version
|
||||
DCD 32 ; Module Preamble Size in 32-bit words
|
||||
DCD 0x12345678 ; Module ID (application defined)
|
||||
DCD 0x01000001 ; Module Properties where:
|
||||
; Bits 31-24: Compiler ID
|
||||
; 0 -> IAR
|
||||
; 1 -> RVDS
|
||||
; 2 -> GNU
|
||||
; Bits 23-1: Reserved
|
||||
; Bit 0: 0 -> Privileged mode execution (no MMU protection)
|
||||
; 1 -> User mode execution (MMU protection)
|
||||
DCD _txm_module_thread_shell_entry - . + . ; Module Shell Entry Point
|
||||
DCD demo_module_start - . + . ; Module Start Thread Entry Point
|
||||
DCD 0 ; Module Stop Thread Entry Point
|
||||
DCD 1 ; Module Start/Stop Thread Priority
|
||||
DCD 2046 ; Module Start/Stop Thread Stack Size
|
||||
DCD _txm_module_callback_request_thread_entry - . + . ; Module Callback Thread Entry
|
||||
DCD 1 ; Module Callback Thread Priority
|
||||
DCD 2046 ; Module Callback Thread Stack Size
|
||||
DCD |Image$$ER_RO$$Length| + |Image$$ER_RW$$Length| ; Module Code Size
|
||||
DCD 0x4000 ; Module Data Size - default to 16K (need to make sure this is large enough for module's data needs!)
|
||||
DCD 0 ; Reserved 0
|
||||
DCD 0 ; Reserved 1
|
||||
DCD 0 ; Reserved 2
|
||||
DCD 0 ; Reserved 3
|
||||
DCD 0 ; Reserved 4
|
||||
DCD 0 ; Reserved 5
|
||||
DCD 0 ; Reserved 6
|
||||
DCD 0 ; Reserved 7
|
||||
DCD 0 ; Reserved 8
|
||||
DCD 0 ; Reserved 9
|
||||
DCD 0 ; Reserved 10
|
||||
DCD 0 ; Reserved 11
|
||||
DCD 0 ; Reserved 12
|
||||
DCD 0 ; Reserved 13
|
||||
DCD 0 ; Reserved 14
|
||||
DCD 0 ; Reserved 15
|
||||
|
||||
END
|
||||
|
||||
|
||||
355
ports_module/cortex_a7/ac5/inc/tx_port.h
Normal file
355
ports_module/cortex_a7/ac5/inc/tx_port.h
Normal file
@@ -0,0 +1,355 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 Cortex-A7/AC5 */
|
||||
/* 6.1.6 */
|
||||
/* */
|
||||
/* 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 */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */
|
||||
/* macro definition, */
|
||||
/* resulting in version 6.1.6 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* 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 ULONG tx_thread_vfp_enable; \
|
||||
VOID *tx_thread_module_instance_ptr; \
|
||||
VOID *tx_thread_module_entry_info_ptr; \
|
||||
ULONG tx_thread_module_current_user_mode; \
|
||||
ULONG tx_thread_module_user_mode; \
|
||||
VOID *tx_thread_module_kernel_stack_start; \
|
||||
VOID *tx_thread_module_kernel_stack_end; \
|
||||
ULONG tx_thread_module_kernel_stack_size; \
|
||||
VOID *tx_thread_module_stack_ptr; \
|
||||
VOID *tx_thread_module_stack_start; \
|
||||
VOID *tx_thread_module_stack_end; \
|
||||
ULONG tx_thread_module_stack_size; \
|
||||
VOID *tx_thread_module_reserved;
|
||||
#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 VOID *tx_event_flags_group_module_instance; \
|
||||
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
|
||||
#define TX_MUTEX_EXTENSION
|
||||
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
|
||||
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
|
||||
|
||||
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
|
||||
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
|
||||
|
||||
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
|
||||
VOID (*tx_timer_module_expiration_function)(ULONG id);
|
||||
|
||||
|
||||
/* 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 UINT 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 UINT interrupt_save;
|
||||
|
||||
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
|
||||
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define VFP extension for the Cortex-A5. Each is assumed to be called in the context of the executing
|
||||
thread. */
|
||||
|
||||
void tx_thread_vfp_enable(void);
|
||||
void tx_thread_vfp_disable(void);
|
||||
|
||||
|
||||
/* 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 Cortex-A7/AC5 Version 6.1.6 *";
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
413
ports_module/cortex_a7/ac5/inc/txm_module_port.h
Normal file
413
ports_module/cortex_a7/ac5/inc/txm_module_port.h
Normal file
@@ -0,0 +1,413 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/** Module Interface (API) */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* APPLICATION INTERFACE DEFINITION RELEASE */
|
||||
/* */
|
||||
/* txm_module_port.h Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file defines the basic module constants, interface structures, */
|
||||
/* and function prototypes. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TXM_MODULE_PORT_H
|
||||
#define TXM_MODULE_PORT_H
|
||||
|
||||
/* It is assumed that the base ThreadX tx_port.h file has been modified to add the
|
||||
following extensions to the ThreadX thread control block (this code should replace
|
||||
the corresponding macro define in tx_port.h):
|
||||
|
||||
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_vfp_enable; \
|
||||
VOID *tx_thread_module_instance_ptr; \
|
||||
VOID *tx_thread_module_entry_info_ptr; \
|
||||
ULONG tx_thread_module_current_user_mode; \
|
||||
ULONG tx_thread_module_user_mode; \
|
||||
VOID *tx_thread_module_kernel_stack_start; \
|
||||
VOID *tx_thread_module_kernel_stack_end; \
|
||||
ULONG tx_thread_module_kernel_stack_size; \
|
||||
VOID *tx_thread_module_stack_ptr; \
|
||||
VOID *tx_thread_module_stack_start; \
|
||||
VOID *tx_thread_module_stack_end; \
|
||||
ULONG tx_thread_module_stack_size; \
|
||||
VOID *tx_thread_module_reserved;
|
||||
|
||||
|
||||
The following extensions must also be defined in tx_port.h:
|
||||
|
||||
#define TX_EVENT_FLAGS_GROUP_EXTENSION VOID *tx_event_flags_group_module_instance; \
|
||||
VOID (*tx_event_flags_group_set_module_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *group_ptr);
|
||||
|
||||
#define TX_QUEUE_EXTENSION VOID *tx_queue_module_instance; \
|
||||
VOID (*tx_queue_send_module_notify)(struct TX_QUEUE_STRUCT *queue_ptr);
|
||||
|
||||
#define TX_SEMAPHORE_EXTENSION VOID *tx_semaphore_module_instance; \
|
||||
VOID (*tx_semaphore_put_module_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
|
||||
|
||||
#define TX_TIMER_EXTENSION VOID *tx_timer_module_instance; \
|
||||
VOID (*tx_timer_module_expiration_function)(ULONG id);
|
||||
*/
|
||||
|
||||
/* Define the kernel stack size for a module thread. */
|
||||
#ifndef TXM_MODULE_KERNEL_STACK_SIZE
|
||||
#define TXM_MODULE_KERNEL_STACK_SIZE 512
|
||||
#endif
|
||||
|
||||
/* Defined, this option enables the MMU hardware and requires memory protected
|
||||
module objects to be allocated from the module manager object pool.
|
||||
If this is undefined, module objects can be created in the module's data area
|
||||
or in the module manager object pool. If this is not defined (MMU hardware
|
||||
is disabled), a module requiring memory protection will not run (the load
|
||||
functions will return a TXM_MODULE_INVALID_PROPERTIES error).
|
||||
Default setting for this value is defined. */
|
||||
#define TXM_MODULE_MEMORY_PROTECTION_ENABLED
|
||||
|
||||
/* Define constants specific to the tools the module can be built with for this particular modules port. */
|
||||
|
||||
#define TXM_MODULE_IAR_COMPILER 0x00000000
|
||||
#define TXM_MODULE_RVDS_COMPILER 0x01000000
|
||||
#define TXM_MODULE_GNU_COMPILER 0x02000000
|
||||
#define TXM_MODULE_COMPILER_MASK 0xFF000000
|
||||
#define TXM_MODULE_OPTIONS_MASK 0x000000FF
|
||||
|
||||
|
||||
/* Define the properties for this particular module port. */
|
||||
#ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
|
||||
#define TXM_MODULE_MEMORY_PROTECTION 0x00000001
|
||||
#else
|
||||
#define TXM_MODULE_MEMORY_PROTECTION 0x00000000
|
||||
#endif
|
||||
|
||||
#define TXM_MODULE_USER_MODE 0x00000001
|
||||
|
||||
/* Define the supported options for this module. */
|
||||
|
||||
#define TXM_MODULE_MANAGER_SUPPORTED_OPTIONS (TXM_MODULE_MEMORY_PROTECTION)
|
||||
#define TXM_MODULE_MANAGER_REQUIRED_OPTIONS 0
|
||||
|
||||
|
||||
/* Define offset adjustments according to the compiler used to build the module. */
|
||||
|
||||
#define TXM_MODULE_IAR_SHELL_ADJUST 24
|
||||
#define TXM_MODULE_IAR_START_ADJUST 28
|
||||
#define TXM_MODULE_IAR_STOP_ADJUST 32
|
||||
#define TXM_MODULE_IAR_CALLBACK_ADJUST 44
|
||||
|
||||
#define TXM_MODULE_RVDS_SHELL_ADJUST 0
|
||||
#define TXM_MODULE_RVDS_START_ADJUST 0
|
||||
#define TXM_MODULE_RVDS_STOP_ADJUST 0
|
||||
#define TXM_MODULE_RVDS_CALLBACK_ADJUST 0
|
||||
|
||||
#define TXM_MODULE_GNU_SHELL_ADJUST 24
|
||||
#define TXM_MODULE_GNU_START_ADJUST 28
|
||||
#define TXM_MODULE_GNU_STOP_ADJUST 32
|
||||
#define TXM_MODULE_GNU_CALLBACK_ADJUST 44
|
||||
|
||||
|
||||
/* Define other module port-specific constants. */
|
||||
|
||||
/* Define INLINE_DECLARE to whitespace for ARM compiler. */
|
||||
#define INLINE_DECLARE
|
||||
|
||||
#define TXM_MAXIMUM_MODULES 16
|
||||
#define TXM_MODULE_LEVEL1_PAGE_TABLE_SIZE 32
|
||||
#define TXM_ASID_TABLE_LENGTH 256
|
||||
|
||||
#define TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET (TXM_MAXIMUM_MODULES * 0)
|
||||
#define TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET (TXM_MAXIMUM_MODULES * 1)
|
||||
#define TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET (TXM_MAXIMUM_MODULES * 2)
|
||||
#define TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET (TXM_MAXIMUM_MODULES * 3)
|
||||
|
||||
#define TXM_MASTER_PAGE_TABLE_INDEX 0
|
||||
|
||||
/* 1 entry per 1MB, so this covers 4G address space */
|
||||
#define TXM_MASTER_PAGE_TABLE_ENTRIES 4096
|
||||
|
||||
/* Smallest MMU page size is 4kB. */
|
||||
#define TXM_MODULE_MEMORY_ALIGNMENT 4096
|
||||
#define TXM_MMU_LEVEL1_PAGE_SHIFT 20
|
||||
#define TXM_MMU_LEVEL2_PAGE_SHIFT 12
|
||||
#define TXM_LEVEL_2_PAGE_TABLE_ENTRIES 256
|
||||
|
||||
/* Level 1 section base address mask. */
|
||||
#define TXM_MMU_LEVEL1_MASK 0xFFF00000
|
||||
|
||||
/* Level 2 section base address mask. */
|
||||
#define TXM_MMU_LEVEL2_MASK 0xFFFFF000
|
||||
|
||||
/* Non-global, outer & inner write-back, write-allocate, user read, no write. */
|
||||
#define TXM_MMU_LEVEL1_CODE_ATTRIBUTES 0x000219EE
|
||||
/* Non-global, outer & inner write-back, write-allocate, user read, write, no-execute. */
|
||||
#define TXM_MMU_LEVEL1_DATA_ATTRIBUTES 0x00021DFE
|
||||
|
||||
/* Level 1 "level 2 descriptor base address" mask. */
|
||||
#define TXM_MMU_LEVEL1_SECOND_MASK 0xFFFFFC00
|
||||
|
||||
/* Level 1 "level 2 descriptor" attributes. */
|
||||
#define TXM_MMU_LEVEL1_SECOND_ATTRIBUTES 0x0000001E1
|
||||
|
||||
/* Kernel level 2 attributes: global, outer & inner write-back, write-allocate, user read/write */
|
||||
#define TXM_MMU_KERNEL_LEVEL2_CODE_ATTRIBUTES 0x0000006E
|
||||
#define TXM_MMU_KERNEL_LEVEL2_DATA_ATTRIBUTES 0x0000005E
|
||||
|
||||
/* Module level 2 attributes: non-global, outer & inner write-back, write-allocate, user read, no write. */
|
||||
#define TXM_MMU_LEVEL2_CODE_ATTRIBUTES 0x0000086E
|
||||
#define TXM_MMU_LEVEL2_DATA_ATTRIBUTES 0x0000087F
|
||||
|
||||
|
||||
/* Settings the user can use to set up shared memory attributes. */
|
||||
#define TXM_MMU_ATTRIBUTE_XN 0x00000001
|
||||
#define TXM_MMU_ATTRIBUTE_B 0x00000002
|
||||
#define TXM_MMU_ATTRIBUTE_C 0x00000004
|
||||
#define TXM_MMU_ATTRIBUTE_AP 0x00000018
|
||||
#define TXM_MMU_ATTRIBUTE_TEX 0x000000E0
|
||||
|
||||
/* Masks for each attribute. */
|
||||
#define TXM_MMU_ATTRIBUTE_XN_MASK 0x00000001
|
||||
#define TXM_MMU_ATTRIBUTE_B_MASK 0x00000001
|
||||
#define TXM_MMU_ATTRIBUTE_C_MASK 0x00000001
|
||||
#define TXM_MMU_ATTRIBUTE_AP_MASK 0x00000003
|
||||
#define TXM_MMU_ATTRIBUTE_TEX_MASK 0x00000007
|
||||
|
||||
/* Shift amounts for bitfields above to correct register locations. */
|
||||
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_XN_SHIFT 4
|
||||
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_B_SHIFT 1
|
||||
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_C_SHIFT 1
|
||||
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_AP_SHIFT 7
|
||||
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_TEX_SHIFT 7
|
||||
#define TXM_MMU_LEVEL1_USER_ATTRIBUTE_BASE 0x000201E2
|
||||
|
||||
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_XN_SHIFT 0
|
||||
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_B_SHIFT 1
|
||||
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_C_SHIFT 1
|
||||
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_AP_SHIFT 1
|
||||
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_TEX_SHIFT 1
|
||||
#define TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE 0x00000802
|
||||
|
||||
/* Shift amounts from bit 0 position. */
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT 4
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT 2
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT 3
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT 10
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT 12
|
||||
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT 0
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT 2
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT 3
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT 4
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT 6
|
||||
|
||||
/* Masks for L1 page attributes. */
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK (TXM_MMU_ATTRIBUTE_XN_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT)
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK (TXM_MMU_ATTRIBUTE_B_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT)
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK (TXM_MMU_ATTRIBUTE_C_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT)
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK (TXM_MMU_ATTRIBUTE_AP_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT)
|
||||
#define TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK (TXM_MMU_ATTRIBUTE_TEX_MASK << TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT)
|
||||
|
||||
/* Masks for L2 page attributes. */
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_XN_MASK (TXM_MMU_ATTRIBUTE_XN_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT)
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_B_MASK (TXM_MMU_ATTRIBUTE_B_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT)
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_C_MASK (TXM_MMU_ATTRIBUTE_C_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT)
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_AP_MASK (TXM_MMU_ATTRIBUTE_AP_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT)
|
||||
#define TXM_MMU_LEVEL2_ATTRIBUTE_TEX_MASK (TXM_MMU_ATTRIBUTE_TEX_MASK << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT)
|
||||
|
||||
#define TXM_ADDRESS_TRANSLATION_FAULT_BIT 1
|
||||
|
||||
#define TXM_ASID_RESERVED 0xFFFFFFFF
|
||||
|
||||
#define TXM_MODULE_ASID_ERROR 0xF6
|
||||
#define TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR 0xF7
|
||||
|
||||
/* Number of L2 pages each module can have. */
|
||||
#define TXM_MODULE_LEVEL2_EXTERNAL_PAGES 16
|
||||
/* Size, in pages, of the L2 page pool. */
|
||||
#define TXM_LEVEL2_EXTERNAL_POOL_PAGES (TXM_MODULE_LEVEL2_EXTERNAL_PAGES * TXM_MAXIMUM_MODULES)
|
||||
|
||||
|
||||
/* Define the port-extensions to the module manager instance structure. */
|
||||
|
||||
#define TXM_MODULE_MANAGER_PORT_EXTENSION \
|
||||
ULONG txm_module_instance_asid; \
|
||||
ULONG *txm_external_page_table[TXM_MODULE_LEVEL2_EXTERNAL_PAGES];
|
||||
|
||||
/* Define the memory fault information structure that is populated when a memory fault occurs. */
|
||||
|
||||
|
||||
typedef struct TXM_MODULE_MANAGER_MEMORY_FAULT_INFO_STRUCT
|
||||
{
|
||||
TX_THREAD *txm_module_manager_memory_fault_info_thread_ptr;
|
||||
VOID *txm_module_manager_memory_fault_info_code_location;
|
||||
ULONG txm_module_manager_memory_fault_info_dfar;
|
||||
ULONG txm_module_manager_memory_fault_info_dfsr;
|
||||
ULONG txm_module_manager_memory_fault_info_ifar;
|
||||
ULONG txm_module_manager_memory_fault_info_ifsr;
|
||||
ULONG txm_module_manager_memory_fault_info_sp;
|
||||
ULONG txm_module_manager_memory_fault_info_r0;
|
||||
ULONG txm_module_manager_memory_fault_info_r1;
|
||||
ULONG txm_module_manager_memory_fault_info_r2;
|
||||
ULONG txm_module_manager_memory_fault_info_r3;
|
||||
ULONG txm_module_manager_memory_fault_info_r4;
|
||||
ULONG txm_module_manager_memory_fault_info_r5;
|
||||
ULONG txm_module_manager_memory_fault_info_r6;
|
||||
ULONG txm_module_manager_memory_fault_info_r7;
|
||||
ULONG txm_module_manager_memory_fault_info_r8;
|
||||
ULONG txm_module_manager_memory_fault_info_r9;
|
||||
ULONG txm_module_manager_memory_fault_info_r10;
|
||||
ULONG txm_module_manager_memory_fault_info_r11;
|
||||
ULONG txm_module_manager_memory_fault_info_r12;
|
||||
ULONG txm_module_manager_memory_fault_info_lr;
|
||||
ULONG txm_module_manager_memory_fault_info_cpsr;
|
||||
} TXM_MODULE_MANAGER_MEMORY_FAULT_INFO;
|
||||
|
||||
|
||||
#define TXM_MODULE_MANAGER_FAULT_INFO \
|
||||
TXM_MODULE_MANAGER_MEMORY_FAULT_INFO _txm_module_manager_memory_fault_info;
|
||||
|
||||
/* Define the macro to check the stack available in dispatch. */
|
||||
#define TXM_MODULE_MANAGER_CHECK_STACK_AVAILABLE
|
||||
|
||||
|
||||
/* Define the macro to check the code alignment. */
|
||||
|
||||
#define TXM_MODULE_MANAGER_CHECK_CODE_ALIGNMENT(module_location, code_alignment) \
|
||||
{ \
|
||||
ULONG temp; \
|
||||
temp = (ULONG) module_location; \
|
||||
temp = temp & (TXM_MODULE_MEMORY_ALIGNMENT - 1); \
|
||||
if (temp) \
|
||||
{ \
|
||||
_tx_mutex_put(&_txm_module_manager_mutex); \
|
||||
return(TXM_MODULE_ALIGNMENT_ERROR); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/* Define the macro to adjust the alignment and size for code/data areas. */
|
||||
|
||||
#define TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size, code_alignment, data_size, data_alignment) _txm_module_manager_alignment_adjust(module_preamble, &code_size, &code_alignment, &data_size, &data_alignment);
|
||||
|
||||
|
||||
/* Define the macro to adjust the symbols in the module preamble. */
|
||||
|
||||
#define TXM_MODULE_MANAGER_CALCULATE_ADJUSTMENTS(properties, shell_function_adjust, start_function_adjust, stop_function_adjust, callback_function_adjust) \
|
||||
if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_IAR_COMPILER) \
|
||||
{ \
|
||||
shell_function_adjust = TXM_MODULE_IAR_SHELL_ADJUST; \
|
||||
start_function_adjust = TXM_MODULE_IAR_START_ADJUST; \
|
||||
stop_function_adjust = TXM_MODULE_IAR_STOP_ADJUST; \
|
||||
callback_function_adjust = TXM_MODULE_IAR_CALLBACK_ADJUST; \
|
||||
} \
|
||||
else if ((properties & TXM_MODULE_COMPILER_MASK) == TXM_MODULE_RVDS_COMPILER) \
|
||||
{ \
|
||||
shell_function_adjust = TXM_MODULE_RVDS_SHELL_ADJUST; \
|
||||
start_function_adjust = TXM_MODULE_RVDS_START_ADJUST; \
|
||||
stop_function_adjust = TXM_MODULE_RVDS_STOP_ADJUST; \
|
||||
callback_function_adjust = TXM_MODULE_RVDS_CALLBACK_ADJUST; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
shell_function_adjust = TXM_MODULE_GNU_SHELL_ADJUST; \
|
||||
start_function_adjust = TXM_MODULE_GNU_START_ADJUST; \
|
||||
stop_function_adjust = TXM_MODULE_GNU_STOP_ADJUST; \
|
||||
callback_function_adjust = TXM_MODULE_GNU_CALLBACK_ADJUST; \
|
||||
}
|
||||
|
||||
|
||||
/* Define the macro to populate the thread control block with module port-specific information. */
|
||||
|
||||
#define TXM_MODULE_MANAGER_THREAD_SETUP(thread_ptr, module_instance) \
|
||||
thread_ptr -> tx_thread_module_current_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \
|
||||
thread_ptr -> tx_thread_module_user_mode = module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION; \
|
||||
if (thread_ptr -> tx_thread_module_user_mode) \
|
||||
{ \
|
||||
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_user_mode_entry; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
thread_entry_info -> txm_module_thread_entry_info_kernel_call_dispatcher = _txm_module_manager_kernel_dispatch; \
|
||||
}
|
||||
|
||||
|
||||
/* Define the macro to populate the module control block with module port-specific information.
|
||||
If memory protection is enabled, set up the MMU registers.
|
||||
*/
|
||||
#define TXM_MODULE_MANAGER_MODULE_SETUP(module_instance) \
|
||||
if (module_instance -> txm_module_instance_property_flags & TXM_MODULE_MEMORY_PROTECTION) \
|
||||
{ \
|
||||
_txm_module_manager_mm_register_setup(module_instance); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Do nothing. */ \
|
||||
}
|
||||
|
||||
/* Define the macro to perform port-specific functions when unloading the module. */
|
||||
#define TXM_MODULE_MANAGER_MODULE_UNLOAD(module_instance) \
|
||||
_txm_level2_page_clear(module_instance); \
|
||||
_txm_module_manager_remove_asid(module_instance);
|
||||
|
||||
/* Define the macros to perform port-specific checks when passing pointers to the kernel. */
|
||||
|
||||
/* Define macro to make sure object is inside the module's data or shared memory. */
|
||||
#define TXM_MODULE_MANAGER_CHECK_INSIDE_DATA(module_instance, obj_ptr, obj_size) \
|
||||
_txm_module_manager_inside_data_check((ULONG) obj_ptr)
|
||||
|
||||
|
||||
/* Define some internal prototypes to this module port. */
|
||||
|
||||
#ifndef TX_SOURCE_CODE
|
||||
#define txm_module_manager_memory_fault_notify _txm_module_manager_memory_fault_notify
|
||||
#define txm_module_manager_mm_initialize _txm_module_manager_mm_initialize
|
||||
#endif
|
||||
|
||||
|
||||
#define TXM_MODULE_MANAGER_ADDITIONAL_PROTOTYPES \
|
||||
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_size, ULONG *code_alignment, ULONG *data_size, ULONG *data_alignment); \
|
||||
ULONG _txm_module_manager_data_pointer_check(ULONG pointer); \
|
||||
VOID _txm_module_manager_memory_fault_handler(VOID); \
|
||||
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *)); \
|
||||
UINT _txm_module_manager_mm_initialize(VOID); \
|
||||
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance); \
|
||||
VOID _txm_level2_page_clear(TXM_MODULE_INSTANCE *module_instance); \
|
||||
VOID _txm_module_manager_remove_asid(TXM_MODULE_INSTANCE *module_instance); \
|
||||
UINT _txm_module_manager_inside_data_check(ULONG pointer);
|
||||
|
||||
#define TXM_MODULE_MANAGER_VERSION_ID \
|
||||
CHAR _txm_module_manager_version_id[] = \
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A7/MMU/AC5 Version 6.1 *";
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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 */
|
||||
;/** */
|
||||
;/** Module */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;
|
||||
;
|
||||
;
|
||||
IMPORT __scatterload
|
||||
|
||||
AREA ||.text||, CODE, READONLY
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _txm_module_initialize Cortex-A7/MMU/AC5 */
|
||||
;/* 6.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* Scott Larson, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function initializes the module c runtime. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* __scatterload Initialize C runtime */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* _txm_module_thread_shell_entry Start module thread */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _txm_module_initialize(VOID)
|
||||
;{
|
||||
EXPORT _txm_module_initialize
|
||||
_txm_module_initialize
|
||||
PUSH {r4-r12,lr} ; Save dregs and LR
|
||||
|
||||
B __scatterload ; Call ARM func to initialize variables
|
||||
|
||||
;/* Override __rt_exit function. */
|
||||
EXPORT __rt_exit
|
||||
__rt_exit
|
||||
|
||||
POP {r4-r12,lr} ; Restore dregs and LR
|
||||
BX lr ; Return to caller
|
||||
;}
|
||||
|
||||
END
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/** Module */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TXM_MODULE
|
||||
#define TXM_MODULE
|
||||
#endif
|
||||
|
||||
#ifndef TX_SOURCE_CODE
|
||||
#define TX_SOURCE_CODE
|
||||
#endif
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "txm_module.h"
|
||||
|
||||
|
||||
/* Define the global module entry pointer from the start thread of the module. */
|
||||
|
||||
TXM_MODULE_THREAD_ENTRY_INFO *_txm_module_entry_info;
|
||||
|
||||
|
||||
/* Define the dispatch function pointer used in the module implementation. */
|
||||
|
||||
ULONG (*_txm_module_kernel_call_dispatcher)(ULONG kernel_request, ULONG param_1, ULONG param_2, ULONG param3);
|
||||
|
||||
|
||||
|
||||
/* Define the RVDS startup code that clears the uninitialized global data and sets up the
|
||||
preset global variables. */
|
||||
extern VOID _txm_module_initialize(VOID);
|
||||
int main(VOID){return 0;}
|
||||
VOID __user_setup_stackheap(VOID){return;}
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_thread_shell_entry Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function calls the specified entry function of the thread. It */
|
||||
/* also provides a place for the thread's entry function to return. */
|
||||
/* If the thread returns, this function places the thread in a */
|
||||
/* "COMPLETED" state. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* thread_ptr Pointer to current thread */
|
||||
/* thread_info Pointer to thread entry info */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* __rt_lib_init RVDS global init function */
|
||||
/* thread_entry Thread's entry function */
|
||||
/* tx_thread_resume Resume the module callback thread */
|
||||
/* txm_module_thread_system_suspend Module thread suspension routine */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Initial thread stack frame */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _txm_module_thread_shell_entry(TX_THREAD *thread_ptr, TXM_MODULE_THREAD_ENTRY_INFO *thread_info)
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
VOID (*entry_exit_notify)(TX_THREAD *, UINT);
|
||||
#endif
|
||||
|
||||
|
||||
/* Determine if this is the start thread. If so, we must prepare the module for
|
||||
execution. If not, simply skip the C startup code. */
|
||||
if (thread_info -> txm_module_thread_entry_info_start_thread)
|
||||
{
|
||||
/* Initialize the RVDS C environment. */
|
||||
_txm_module_initialize();
|
||||
|
||||
/* Save the entry info pointer, for later use. */
|
||||
_txm_module_entry_info = thread_info;
|
||||
|
||||
/* Save the kernel function dispatch address. This is used to make all resident calls from
|
||||
the module. */
|
||||
_txm_module_kernel_call_dispatcher = thread_info -> txm_module_thread_entry_info_kernel_call_dispatcher;
|
||||
|
||||
/* Ensure that we have a valid pointer. */
|
||||
while (!_txm_module_kernel_call_dispatcher)
|
||||
{
|
||||
/* Loop here, if an error is present getting the dispatch function pointer!
|
||||
An error here typically indicates the resident portion of _tx_thread_schedule
|
||||
is not supporting the trap to obtain the function pointer. */
|
||||
}
|
||||
|
||||
/* Resume the module's callback thread, already created in the manager. */
|
||||
_txe_thread_resume(thread_info -> txm_module_thread_entry_info_callback_request_thread);
|
||||
}
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Pickup the entry/exit application callback routine. */
|
||||
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
|
||||
|
||||
/* Determine if an application callback routine is specified. */
|
||||
if (entry_exit_notify != TX_NULL)
|
||||
{
|
||||
|
||||
/* Yes, notify application that this thread has been entered! */
|
||||
(entry_exit_notify)(thread_ptr, TX_THREAD_ENTRY);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Call current thread's entry function. */
|
||||
(thread_info -> txm_module_thread_entry_info_entry) (thread_info -> txm_module_thread_entry_info_parameter);
|
||||
|
||||
/* Suspend thread with a "completed" state. */
|
||||
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Pickup the entry/exit application callback routine again. */
|
||||
entry_exit_notify = thread_info -> txm_module_thread_entry_info_exit_notify;
|
||||
|
||||
/* Determine if an application callback routine is specified. */
|
||||
if (entry_exit_notify != TX_NULL)
|
||||
{
|
||||
|
||||
/* Yes, notify application that this thread has exited! */
|
||||
(entry_exit_notify)(thread_ptr, TX_THREAD_EXIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Call actual thread suspension routine. */
|
||||
_txm_module_thread_system_suspend(thread_ptr);
|
||||
|
||||
#ifdef TX_SAFETY_CRITICAL
|
||||
|
||||
/* If we ever get here, raise safety critical exception. */
|
||||
TX_SAFETY_CRITICAL_EXCEPTION(__FILE__, __LINE__, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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 0x12 ; IRQ mode
|
||||
SVC_MODE EQU 0x13 ; SVC mode
|
||||
SYS_MODE EQU 0x1F ; SYS mode
|
||||
THUMB_MASK EQU 0x20 ; Thumb bit mask
|
||||
|
||||
IF :DEF:TX_ENABLE_FIQ_SUPPORT
|
||||
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
|
||||
ELSE
|
||||
DISABLE_INTS EQU 0x80 ; Disable IRQ interrupts
|
||||
ENDIF
|
||||
;
|
||||
;
|
||||
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 Cortex-A7/MMU/AC5 */
|
||||
;/* 6.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* Scott Larson, 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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_context_restore(VOID)
|
||||
;{
|
||||
EXPORT _tx_thread_context_restore
|
||||
_tx_thread_context_restore
|
||||
;
|
||||
; /* Lockout interrupts. */
|
||||
;
|
||||
IF :DEF:TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if ; Disable IRQ and FIQ interrupts
|
||||
ELSE
|
||||
CPSID i ; Disable IRQ interrupts
|
||||
ENDIF
|
||||
|
||||
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)
|
||||
CPS #SYS_MODE ; Enter SYS mode
|
||||
STR r1, [sp, #-4]! ; Save point of interrupt on thread's stack
|
||||
STMDB sp!, {r4-r12, lr} ; Save upper half of registers on thread's stack
|
||||
MOV r4, r3 ; Save SPSR in r4
|
||||
CPS #IRQ_MODE ; Enter IRQ mode
|
||||
LDMIA sp!, {r0-r3} ; Recover r0-r3
|
||||
CPS #SYS_MODE ; Enter SYS mode
|
||||
STMDB sp!, {r0-r3} ; Save r0-r3 on thread's stack
|
||||
|
||||
LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
|
||||
LDR r0, [r1, #0] ; Pickup current thread pointer
|
||||
|
||||
IF {TARGET_FPU_VFP} = {TRUE}
|
||||
LDR r2, [r0, #144] ; Pickup the VFP enabled flag
|
||||
CMP r2, #0 ; Is the VFP enabled?
|
||||
BEQ _tx_skip_irq_vfp_save ; No, skip VFP IRQ save
|
||||
VMRS r2, FPSCR ; Pickup the FPSCR
|
||||
STR r2, [sp, #-4]! ; Save FPSCR
|
||||
VSTMDB sp!, {D16-D31} ; Save D16-D31
|
||||
VSTMDB sp!, {D0-D15} ; Save D0-D15
|
||||
_tx_skip_irq_vfp_save
|
||||
ENDIF
|
||||
|
||||
MOV r3, #1 ; Build interrupt stack type
|
||||
STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR
|
||||
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, #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();
|
||||
;
|
||||
CPS #IRQ_MODE ; Enter IRQ mode
|
||||
MRS r1, SPSR ; Get SPSR
|
||||
ORR r1, r1, #SYS_MODE ; Change to SYS Mode
|
||||
BIC r1, r1, #THUMB_MASK ; Clear thumb bit
|
||||
MSR SPSR_cxsf, r1 ; Put SYS Mode in SPSR
|
||||
LDR lr, =_tx_thread_schedule ; Load scheduler address
|
||||
MOVS pc, lr ; Return to scheduler
|
||||
; }
|
||||
;
|
||||
__tx_thread_idle_system_restore
|
||||
;
|
||||
; /* Just return back to the scheduler! */
|
||||
;
|
||||
LDR lr, =_tx_thread_schedule ; Load scheduler address
|
||||
MOVS pc, lr ; Return to scheduler
|
||||
;}
|
||||
;
|
||||
END
|
||||
|
||||
@@ -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"
|
||||
;
|
||||
;
|
||||
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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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
|
||||
CPSID if ; Disable FIQ 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
|
||||
|
||||
@@ -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 */
|
||||
;/** */
|
||||
;/** 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
|
||||
MODE_MASK EQU 0x1F ; Mode mask
|
||||
IRQ_MODE_BITS EQU 0x12 ; IRQ mode bits
|
||||
;
|
||||
;
|
||||
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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_fiq_context_restore(VOID)
|
||||
;{
|
||||
EXPORT _tx_thread_fiq_context_restore
|
||||
_tx_thread_fiq_context_restore
|
||||
;
|
||||
; /* Lockout interrupts. */
|
||||
;
|
||||
CPSID if ; Disable IRQ and FIQ 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_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, #FIQ_MODE ; Build FIQ mode CPSR
|
||||
MSR CPSR_c, r2 ; Re-enter FIQ 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
|
||||
|
||||
LDR r1, =_tx_thread_current_ptr ; Pickup address of current thread ptr
|
||||
LDR r0, [r1] ; Pickup current thread pointer
|
||||
|
||||
IF {TARGET_FPU_VFP} = {TRUE}
|
||||
LDR r2, [r0, #144] ; Pickup the VFP enabled flag
|
||||
CMP r2, #0 ; Is the VFP enabled?
|
||||
BEQ _tx_skip_fiq_vfp_save ; No, skip VFP FIQ save
|
||||
VMRS r2, FPSCR ; Pickup the FPSCR
|
||||
STR r2, [sp, #-4]! ; Save FPSCR
|
||||
VSTMDB sp!, {D16-D31} ; Save D16-D31
|
||||
VSTMDB sp!, {D0-D15} ; Save D0-D15
|
||||
_tx_skip_fiq_vfp_save
|
||||
ENDIF
|
||||
|
||||
MOV r3, #1 ; Build interrupt stack type
|
||||
STMDB sp!, {r3, r4} ; Save interrupt stack type and SPSR
|
||||
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_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
|
||||
MOV r3, #SVC_MODE ; Build SVC mode CPSR
|
||||
MSR CPSR_c, r3 ; Enter SVC mode
|
||||
B _tx_thread_schedule ; Return to scheduler
|
||||
;
|
||||
;}
|
||||
;
|
||||
END
|
||||
|
||||
@@ -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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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
|
||||
|
||||
@@ -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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, 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_c, r0 ; Re-enter IRQ mode
|
||||
IF {INTER} = {TRUE}
|
||||
BX r3 ; Return to caller
|
||||
ELSE
|
||||
MOV pc, r3 ; Return to caller
|
||||
ENDIF
|
||||
;}
|
||||
;
|
||||
END
|
||||
|
||||
@@ -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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, 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_c, r0 ; Enter system mode
|
||||
IF {INTER} = {TRUE}
|
||||
BX r3 ; Return to caller
|
||||
ELSE
|
||||
MOV pc, r3 ; Return to caller
|
||||
ENDIF
|
||||
;}
|
||||
;
|
||||
END
|
||||
|
||||
@@ -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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, 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
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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_disable Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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. */
|
||||
;
|
||||
IF :DEF:TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if ; Disable IRQ and FIQ
|
||||
ELSE
|
||||
CPSID i ; Disable IRQ
|
||||
ENDIF
|
||||
|
||||
IF {INTER} = {TRUE}
|
||||
BX lr ; Return to caller
|
||||
ELSE
|
||||
MOV pc, lr ; Return to caller
|
||||
ENDIF
|
||||
;}
|
||||
;
|
||||
END
|
||||
|
||||
@@ -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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, r0 ; Setup new CPSR
|
||||
IF {INTER} = {TRUE}
|
||||
BX lr ; Return to caller
|
||||
ELSE
|
||||
MOV pc, lr ; Return to caller
|
||||
ENDIF
|
||||
;}
|
||||
;
|
||||
END
|
||||
|
||||
@@ -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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, 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_c, r0 ; Re-enter IRQ mode
|
||||
IF {INTER} = {TRUE}
|
||||
BX r3 ; Return to caller
|
||||
ELSE
|
||||
MOV pc, r3 ; Return to caller
|
||||
ENDIF
|
||||
;}
|
||||
END
|
||||
|
||||
@@ -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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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_c, 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_c, r0 ; Enter system mode
|
||||
IF {INTER} = {TRUE}
|
||||
BX r3 ; Return to caller
|
||||
ELSE
|
||||
MOV pc, r3 ; Return to caller
|
||||
ENDIF
|
||||
;}
|
||||
;
|
||||
END
|
||||
|
||||
@@ -0,0 +1,458 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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"
|
||||
;
|
||||
;
|
||||
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
|
||||
|
||||
IRQ_MODE EQU 0xD2 ; IRQ mode
|
||||
USR_MODE EQU 0x10 ; USR mode
|
||||
SVC_MODE EQU 0x13 ; SVC mode
|
||||
SYS_MODE EQU 0x1F ; SYS mode
|
||||
|
||||
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
|
||||
|
||||
MODE_MASK EQU 0x1F ; Mode mask
|
||||
THUMB_MASK EQU 0x20 ; Thumb bit mask
|
||||
|
||||
IMPORT _txm_system_mode_enter
|
||||
IMPORT _txm_system_mode_exit
|
||||
IMPORT _txm_ttbr1_page_table
|
||||
;
|
||||
;
|
||||
AREA ||.text||, CODE, READONLY
|
||||
PRESERVE8
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_schedule Cortex-A7/MMU/AC5 */
|
||||
;/* 6.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* Scott Larson, 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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_schedule(VOID)
|
||||
;{
|
||||
EXPORT _tx_thread_schedule
|
||||
_tx_thread_schedule
|
||||
|
||||
; Enter the scheduler.
|
||||
SVC 0
|
||||
|
||||
; We should never get here - ever!
|
||||
_tx_scheduler_fault__
|
||||
B _tx_scheduler_fault__
|
||||
;}
|
||||
; ****************************************************************************
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; SWI_Handler
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
EXPORT __tx_swi_interrupt ; Software interrupt handler
|
||||
__tx_swi_interrupt
|
||||
|
||||
STMFD sp!, {r0-r3, r12, lr} ; Store the registers
|
||||
MOV r1, sp ; Set pointer to parameters
|
||||
MRS r0, spsr ; Get spsr
|
||||
STMFD sp!, {r0, r3} ; Store spsr onto stack and another
|
||||
; register to maintain 8-byte-aligned stack
|
||||
TST r0, #THUMB_MASK ; Occurred in Thumb state?
|
||||
LDRNEH r0, [lr,#-2] ; Yes: Load halfword and...
|
||||
BICNE r0, r0, #0xFF00 ; ...extract comment field
|
||||
LDREQ r0, [lr,#-4] ; No: Load word and...
|
||||
BICEQ r0, r0, #0xFF000000 ; ...extract comment field
|
||||
|
||||
; r0 now contains SVC number
|
||||
; r1 now contains pointer to stacked registers
|
||||
|
||||
;
|
||||
; The service call is handled here
|
||||
;
|
||||
|
||||
CMP r0, #0 ; Is it a schedule request?
|
||||
BEQ _tx_handler_svc_schedule ; Yes, go there
|
||||
|
||||
CMP r0, #1 ; Is it a system mode enter request?
|
||||
BEQ _tx_handler_svc_super_enter ; Yes, go there
|
||||
|
||||
CMP r0, #2 ; Is it a system mode exit request?
|
||||
BEQ _tx_handler_svc_super_exit ; Yes, go there
|
||||
|
||||
LDR r2, =0x123456
|
||||
CMP r0, r2 ; Is it an ARM request?
|
||||
BEQ _tx_handler_svc_arm ; Yes, go there
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Unknown SVC argument
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Unrecognized service call
|
||||
_tx_handler_svc_unrecognized
|
||||
|
||||
_tx_handler_svc_unrecognized_loop ; We should never get here
|
||||
B _tx_handler_svc_unrecognized_loop
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; SVC 1
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; At this point we have an SVC 1, which means we are entering the system mode to service a kernel call
|
||||
_tx_handler_svc_super_enter
|
||||
; Make sure that we have been called from the system mode enter location (security)
|
||||
LDR r2, =_txm_system_mode_enter ; Load the address of the known call point
|
||||
SUB r1, lr, #4 ; Calculate the address of the actual call
|
||||
CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry?
|
||||
BNE _tx_handler_svc_unrecognized ; Return to where we came
|
||||
|
||||
; Clear the user mode flag in the thread structure
|
||||
LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address
|
||||
LDR r2, [r1] ; Load current thread location from the pointer (pointer indirection)
|
||||
MOV r1, #0 ; Load the new user mode flag value (user mode flag clear -> not user mode -> system)
|
||||
STR r1, [r2, #0x9C] ; Clear tx_thread_module_current_user_mode for thread
|
||||
|
||||
; Now we enter the system mode and return
|
||||
LDMFD sp!, {r0, r3} ; Get spsr from the stack
|
||||
BIC r0, r0, #MODE_MASK ; clear mode field
|
||||
ORR r0, r0, #SYS_MODE ; system mode code
|
||||
MSR SPSR_cxsf, r0 ; Restore the spsr
|
||||
|
||||
LDR r1, [r2, #0xA8] ; Load the module kernel stack pointer
|
||||
CPS #SYS_MODE ; Switch to SYS mode
|
||||
MOV r3, sp ; Grab thread stack pointer
|
||||
MOV sp, r1 ; Set SP to kernel stack pointer
|
||||
CPS #SVC_MODE ; Switch back to SVC mode
|
||||
STR r3, [r2, #0xB0] ; Save thread stack pointer
|
||||
IF :DEF:TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
|
||||
ELSE
|
||||
LDR r3, [r2, #0xAC] ; Load the module kernel stack size
|
||||
STR r3, [r2, #20] ; Set stack size
|
||||
LDRD r0, r1, [r2, #0xA4] ; Load the module kernel stack start and end
|
||||
STRD r0, r1, [r2, #0x0C] ; Set stack start and end
|
||||
ENDIF
|
||||
|
||||
LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; SVC 2
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; At this point we have an SVC 2, which means we are exiting the system mode after servicing a kernel call
|
||||
_tx_handler_svc_super_exit
|
||||
; Make sure that we have been called from the system mode exit location (security)
|
||||
LDR r2, =_txm_system_mode_exit ; Load the address of the known call point
|
||||
SUB r1, lr, #4 ; Calculate the address of the actual call
|
||||
CMP r1, r2 ; Did we come from txm_module_manager_user_mode_entry?
|
||||
BNE _tx_handler_svc_unrecognized ; Return to where we came
|
||||
|
||||
; Set the user mode flag into the thread structure
|
||||
LDR r1, =_tx_thread_current_ptr ; Load the current thread pointer address
|
||||
LDR r2, [r1] ; Load the current thread location from the pointer (pointer indirection)
|
||||
MOV r1, #1 ; Load the new user mode flag value (user mode enabled -> not system anymore)
|
||||
STR r1, [r2, #0x9C] ; Set tx_thread_module_current_user_mode for thread
|
||||
|
||||
; Now we enter user mode (exit the system mode) and return
|
||||
LDMFD sp!, {r0, r3} ; Get spsr from the stack
|
||||
BIC r0, r0, #MODE_MASK ; clear mode field
|
||||
ORR r0, r0, #USR_MODE ; user mode code
|
||||
MSR SPSR_cxsf, r0 ; Restore the spsr
|
||||
|
||||
LDR r1, [r2, #0xB0] ; Load the module thread stack pointer
|
||||
CPS #SYS_MODE ; Switch to SYS mode
|
||||
MOV r3, sp ; Grab kernel stack pointer
|
||||
MOV sp, r1 ; Set SP back to thread stack pointer
|
||||
CPS #SVC_MODE ; Switch back to SVC mode
|
||||
IF :DEF:TXM_MODULE_KERNEL_STACK_MAINTENANCE_DISABLE
|
||||
ELSE
|
||||
LDR r3, [r2, #0xBC] ; Load the module thread stack size
|
||||
STR r3, [r2, #20] ; Set stack size
|
||||
LDRD r0, r1, [r2, #0xB4] ; Load the module thread stack start and end
|
||||
STRD r0, r1, [r2, #0x0C] ; Set stack start and end
|
||||
ENDIF
|
||||
LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; ARM Semihosting
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
_tx_handler_svc_arm
|
||||
|
||||
; *** TODO: handle semihosting requests or ARM angel requests ***
|
||||
|
||||
; just return
|
||||
LDMFD sp!, {r0, r3} ; Get spsr from the stack
|
||||
MSR SPSR_cxsf, r0 ; Restore the spsr
|
||||
LDMFD sp!, {r0-r3, r12, pc}^ ; Restore the registers and return
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; SVC 0
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; At this point we have an SVC 0: enter the scheduler.
|
||||
_tx_handler_svc_schedule
|
||||
|
||||
LDMFD sp!, {r0, r3} ; Get spsr from stack
|
||||
MSR SPSR_cxsf, r0 ; Restore spsr
|
||||
LDMFD sp!, {r0-r3, r12, lr} ; Restore the registers
|
||||
|
||||
; This code 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.
|
||||
;
|
||||
; /* 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
|
||||
STR r3, [r2, #0] ; Setup time-slice
|
||||
|
||||
|
||||
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
;
|
||||
; /* Call the thread entry function to indicate the thread is executing. */
|
||||
;
|
||||
MOV r5, r0 ; Save r0
|
||||
BL _tx_execution_thread_enter ; Call the thread execution enter function
|
||||
MOV r0, r5 ; Restore r0
|
||||
ENDIF
|
||||
|
||||
; Determine if an interrupt frame or a synchronous task suspension frame is present.
|
||||
CPS #SYS_MODE ; Enter SYS mode
|
||||
LDR sp, [r0, #8] ; Switch to thread stack pointer
|
||||
LDMIA sp!, {r4, r5} ; Pickup the stack type and saved CPSR
|
||||
CPS #SVC_MODE ; Enter SVC mode
|
||||
|
||||
; **************************************************************************
|
||||
; Set up MMU for module.
|
||||
LDR r2, [r0, #0x94] ; Pickup the module pointer
|
||||
CMP r2, #0 ; Valid module pointer?
|
||||
LDRNE r2, [r2, #0x64] ; Load ASID
|
||||
; Otherwise, ASID 0 & master table will be loaded.
|
||||
; Is ASID already loaded?
|
||||
MRC p15, 0, r1, c13, c0, 1 ; Read CONTEXTIDR into r1
|
||||
CMP r1, r2
|
||||
; If so, skip MMU setup.
|
||||
BEQ _tx_skip_mmu_update
|
||||
; New ASID & TTBR values to load
|
||||
DSB
|
||||
ISB
|
||||
; Load new ASID and TTBR
|
||||
LDR r1, =_txm_ttbr1_page_table ; Load master TTBR
|
||||
ORR r1, r1, #0x48 ; OR it with #TTBR0_ATTRIBUTES
|
||||
MCR p15, 0, r1, c2, c0, 0 ; Change TTBR to master
|
||||
ISB
|
||||
DSB
|
||||
MCR p15, 0, r2, c13, c0, 1 ; Change ASID to new value
|
||||
ISB
|
||||
; Change TTBR to new value
|
||||
MOV r3, #14
|
||||
ADD r1, r1, r2, LSL r3
|
||||
MCR p15, 0, r1, c2, c0, 0 ; Change TTBR to new value
|
||||
|
||||
; refresh TLB
|
||||
MOV r2, #0
|
||||
DSB
|
||||
MCR p15, 0, r2, c8, c7, 0 ; Invalidate entire unified TLB
|
||||
MCR p15, 0, r2, c7, c5, 0 ; Invalidate all instruction caches to PoU
|
||||
MCR p15, 0, r2, c7, c5, 6 ; Invalidate branch predictor
|
||||
DSB
|
||||
ISB
|
||||
|
||||
;test address translation
|
||||
;mcr p15, 0, r0, c7, c8, 0
|
||||
|
||||
_tx_skip_mmu_update
|
||||
; **************************************************************************
|
||||
|
||||
CMP r4, #0 ; Check for synchronous context switch
|
||||
BEQ _tx_solicited_return
|
||||
|
||||
MSR SPSR_cxsf, r5 ; Setup SPSR for return
|
||||
LDR r1, [r0, #8] ; Get thread SP
|
||||
LDR lr, [r1, #0x40] ; Get thread PC
|
||||
CPS #SYS_MODE ; Enter SYS mode
|
||||
|
||||
IF {TARGET_FPU_VFP} = {TRUE}
|
||||
LDR r2, [r0, #144] ; Pickup the VFP enabled flag
|
||||
CMP r2, #0 ; Is the VFP enabled?
|
||||
BEQ _tx_skip_interrupt_vfp_restore ; No, skip VFP interrupt restore
|
||||
VLDMIA sp!, {D0-D15} ; Recover D0-D15
|
||||
VLDMIA sp!, {D16-D31} ; Recover D16-D31
|
||||
LDR r4, [sp], #4 ; Pickup FPSCR
|
||||
VMSR FPSCR, r4 ; Restore FPSCR
|
||||
CPS #SVC_MODE ; Enter SVC mode
|
||||
LDR lr, [r1, #0x144] ; Get thread PC
|
||||
CPS #SYS_MODE ; Enter SYS mode
|
||||
_tx_skip_interrupt_vfp_restore
|
||||
ENDIF
|
||||
|
||||
LDMIA sp!, {r0-r12, lr} ; Restore registers
|
||||
ADD sp, sp, #4 ; Fix stack pointer
|
||||
CPS #SVC_MODE ; Enter SVC mode
|
||||
SUBS pc, lr, #0 ; Return to point of thread interrupt
|
||||
|
||||
_tx_solicited_return
|
||||
MOV r2, r5 ; Move CPSR to scratch register
|
||||
CPS #SYS_MODE ; Enter SYS mode
|
||||
|
||||
IF {TARGET_FPU_VFP} = {TRUE}
|
||||
LDR r1, [r0, #144] ; Pickup the VFP enabled flag
|
||||
CMP r1, #0 ; Is the VFP enabled?
|
||||
BEQ _tx_skip_solicited_vfp_restore ; No, skip VFP solicited restore
|
||||
VLDMIA sp!, {D8-D15} ; Recover D8-D15
|
||||
VLDMIA sp!, {D16-D31} ; Recover D16-D31
|
||||
LDR r4, [sp], #4 ; Pickup FPSCR
|
||||
VMSR FPSCR, r4 ; Restore FPSCR
|
||||
_tx_skip_solicited_vfp_restore
|
||||
ENDIF
|
||||
|
||||
LDMIA sp!, {r4-r11, lr} ; Restore registers
|
||||
MOV r1, lr ; Copy lr to r1 to preserve across mode change
|
||||
CPS #SVC_MODE ; Enter SVC mode
|
||||
MSR SPSR_cxsf, r2 ; Recover CPSR
|
||||
MOV lr, r1 ; Deprecated return via r1, so copy r1 to lr and return via lr
|
||||
SUBS pc, lr, #0 ; Return to thread synchronously
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; End __tx_handler_swi
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
IF {TARGET_FPU_VFP} = {TRUE}
|
||||
EXPORT tx_thread_vfp_enable
|
||||
tx_thread_vfp_enable
|
||||
MRS r2, CPSR ; Pickup the CPSR
|
||||
IF :DEF:TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if ; Disable IRQ and FIQ interrupts
|
||||
ELSE
|
||||
CPSID i ; Disable IRQ interrupts
|
||||
ENDIF
|
||||
LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address
|
||||
LDR r1, [r0] ; Pickup current thread pointer
|
||||
CMP r1, #0 ; Check for NULL thread pointer
|
||||
BEQ __tx_no_thread_to_enable ; If NULL, skip VFP enable
|
||||
MOV r0, #1 ; Build enable value
|
||||
STR r0, [r1, #144] ; Set the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
|
||||
__tx_no_thread_to_enable
|
||||
MSR CPSR_cxsf, r2 ; Recover CPSR
|
||||
BX LR ; Return to caller
|
||||
|
||||
EXPORT tx_thread_vfp_disable
|
||||
tx_thread_vfp_disable
|
||||
MRS r2, CPSR ; Pickup the CPSR
|
||||
IF :DEF:TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if ; Disable IRQ and FIQ interrupts
|
||||
ELSE
|
||||
CPSID i ; Disable IRQ interrupts
|
||||
ENDIF
|
||||
LDR r0, =_tx_thread_current_ptr ; Build current thread pointer address
|
||||
LDR r1, [r0] ; Pickup current thread pointer
|
||||
CMP r1, #0 ; Check for NULL thread pointer
|
||||
BEQ __tx_no_thread_to_disable ; If NULL, skip VFP disable
|
||||
MOV r0, #0 ; Build disable value
|
||||
STR r0, [r1, #144] ; Clear the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
|
||||
__tx_no_thread_to_disable
|
||||
MSR CPSR_cxsf, r2 ; Recover CPSR
|
||||
BX LR ; Return to caller
|
||||
ENDIF
|
||||
|
||||
END
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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
|
||||
SYS_MODE EQU 0x1F ; SYS 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
|
||||
|
||||
THUMB_MASK EQU 0x20 ; Thumb bit (5) of CPSR/SPSR
|
||||
|
||||
;
|
||||
;
|
||||
AREA ||.text||, CODE, READONLY
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _tx_thread_stack_build Cortex-A7/MMU/AC5 */
|
||||
;/* 6.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* Scott Larson, 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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 Scott Larson Initial Version 6.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 Cortex-A7 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 r3, CPSR ; Pickup CPSR
|
||||
BIC r3, r3, #CPSR_MASK ; Mask mode bits of CPSR
|
||||
ORR r3, r3, #SYS_MODE ; Build CPSR, SYS mode, interrupts enabled
|
||||
BIC r3, r3, #THUMB_MASK ; Clear Thumb bit by default
|
||||
AND r1, r1, #1 ; Determine if the entry function is in Thumb mode
|
||||
CMP r1, #1 ; Is the Thumb bit set?
|
||||
ORREQ r3, r3, #THUMB_MASK ; Yes, set the Thumb bit
|
||||
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
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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"
|
||||
;
|
||||
;
|
||||
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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _tx_thread_system_return(VOID)
|
||||
;{
|
||||
EXPORT _tx_thread_system_return
|
||||
_tx_thread_system_return
|
||||
;
|
||||
; /* Save minimal context on the stack. */
|
||||
;
|
||||
STMDB sp!, {r4-r11, lr} ; Save minimal context
|
||||
LDR r5, =_tx_thread_current_ptr ; Pickup address of current ptr
|
||||
LDR r6, [r5, #0] ; Pickup current thread pointer
|
||||
|
||||
IF {TARGET_FPU_VFP} = {TRUE}
|
||||
LDR r0, [r6, #144] ; Pickup the VFP enabled flag
|
||||
CMP r0, #0 ; Is the VFP enabled?
|
||||
BEQ _tx_skip_solicited_vfp_save ; No, skip VFP solicited save
|
||||
VMRS r4, FPSCR ; Pickup the FPSCR
|
||||
STR r4, [sp, #-4]! ; Save FPSCR
|
||||
VSTMDB sp!, {D16-D31} ; Save D16-D31
|
||||
VSTMDB sp!, {D8-D15} ; Save D8-D15
|
||||
_tx_skip_solicited_vfp_save
|
||||
ENDIF
|
||||
|
||||
MOV r0, #0 ; Build a solicited stack type
|
||||
MRS r1, CPSR ; Pickup the CPSR
|
||||
STMDB sp!, {r0-r1} ; Save type and CPSR
|
||||
;
|
||||
; /* Lockout interrupts. */
|
||||
;
|
||||
IF :DEF:TX_ENABLE_FIQ_SUPPORT
|
||||
CPSID if ; Disable IRQ and FIQ interrupts
|
||||
ELSE
|
||||
CPSID i ; Disable IRQ interrupts
|
||||
ENDIF
|
||||
|
||||
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 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, [r6, #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 the current remaining 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, [r6, #24] ; Store current time-slice
|
||||
;
|
||||
; }
|
||||
__tx_thread_dont_save_ts
|
||||
;
|
||||
; /* Clear the current thread pointer. */
|
||||
; _tx_thread_current_ptr = TX_NULL;
|
||||
;
|
||||
STR r4, [r5, #0] ; Clear current thread pointer
|
||||
|
||||
B _tx_thread_schedule ; Jump to scheduler!
|
||||
;
|
||||
;}
|
||||
END
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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
|
||||
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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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
|
||||
CPSID if ; Disable IRQ and FIQ 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
|
||||
|
||||
@@ -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 Cortex-A7/AC5 */
|
||||
;/* 6.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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 William E. Lamie Initial Version 6.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
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/** Module Manager */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "txm_module.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_alignment_adjust Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function adjusts the alignment and size of the code and data */
|
||||
/* section for a given module implementation. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* code_size Size of the code area (updated) */
|
||||
/* code_alignment Code area alignment (updated) */
|
||||
/* data_size Size of data area (updated) */
|
||||
/* data_alignment Data area alignment (updated) */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Initial thread stack frame */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _txm_module_manager_alignment_adjust(TXM_MODULE_PREAMBLE *module_preamble, ULONG *code_size, ULONG *code_alignment, ULONG *data_size, ULONG *data_alignment)
|
||||
{
|
||||
|
||||
ULONG local_code_size;
|
||||
ULONG local_code_alignment;
|
||||
ULONG local_data_size;
|
||||
ULONG local_data_alignment;
|
||||
|
||||
|
||||
/* Copy the input parameters into local variables for ease of use. */
|
||||
local_code_size = *code_size;
|
||||
local_code_alignment = TXM_MODULE_MEMORY_ALIGNMENT;
|
||||
local_data_size = *data_size;
|
||||
local_data_alignment = TXM_MODULE_MEMORY_ALIGNMENT;
|
||||
|
||||
/* Return all the information to the caller. */
|
||||
*code_size = ((local_code_size + TXM_MODULE_MEMORY_ALIGNMENT - 1)/TXM_MODULE_MEMORY_ALIGNMENT) * TXM_MODULE_MEMORY_ALIGNMENT;
|
||||
*code_alignment = local_code_alignment;
|
||||
*data_size = ((local_data_size + TXM_MODULE_MEMORY_ALIGNMENT - 1)/TXM_MODULE_MEMORY_ALIGNMENT) * TXM_MODULE_MEMORY_ALIGNMENT;
|
||||
*data_alignment = local_data_alignment;
|
||||
}
|
||||
@@ -0,0 +1,483 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/** Module Manager */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_mutex.h"
|
||||
#include "tx_queue.h"
|
||||
#include "tx_thread.h"
|
||||
#include "txm_module.h"
|
||||
|
||||
/* External page tables. */
|
||||
extern ULONG _txm_level2_external_page_pool[TXM_LEVEL2_EXTERNAL_POOL_PAGES][TXM_LEVEL_2_PAGE_TABLE_ENTRIES];
|
||||
extern ULONG _txm_ttbr1_page_table[TXM_MAXIMUM_MODULES][TXM_MASTER_PAGE_TABLE_ENTRIES];
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_level2_page_get Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function gets an available L2 page table and places it in the */
|
||||
/* module external page table list. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Module instance pointer */
|
||||
/* page_addr Address of L2 page */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _txm_module_manager_external_memory_enable */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
ULONG _txm_level2_page_get(TXM_MODULE_INSTANCE *module_instance, ULONG *page_addr)
|
||||
{
|
||||
|
||||
UINT i;
|
||||
UINT status;
|
||||
UINT table_index;
|
||||
UINT pool_index;
|
||||
|
||||
/* Default status to success. */
|
||||
status = TX_SUCCESS;
|
||||
|
||||
/* Find first free table slot in module control block. */
|
||||
for(i = 0; i < TXM_MODULE_LEVEL2_EXTERNAL_PAGES; i++)
|
||||
{
|
||||
if(module_instance->txm_external_page_table[i] == TX_NULL)
|
||||
{
|
||||
table_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i >= TXM_MODULE_LEVEL2_EXTERNAL_PAGES)
|
||||
{
|
||||
status = TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* Find first free table in pool. */
|
||||
for(i = 0; i < TXM_LEVEL2_EXTERNAL_POOL_PAGES; i++)
|
||||
{
|
||||
if(_txm_level2_external_page_pool[i][0] == (ULONG) TX_NULL)
|
||||
{
|
||||
pool_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i >= TXM_LEVEL2_EXTERNAL_POOL_PAGES)
|
||||
{
|
||||
status = TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(status == TX_SUCCESS)
|
||||
{
|
||||
/* Place page address in table slot. Return page address. */
|
||||
module_instance->txm_external_page_table[table_index] = _txm_level2_external_page_pool[pool_index];
|
||||
*page_addr = (ULONG)_txm_level2_external_page_pool[pool_index];
|
||||
}
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_level2_page_clear Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function clears the first entry in a L2 page table and clears */
|
||||
/* the table entry from the module external page table list. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Module instance pointer */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* TXM_MODULE_MANAGER_MODULE_UNLOAD */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _txm_level2_page_clear(TXM_MODULE_INSTANCE *module_instance)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
/* Clear table slots and zero out L2 entry. */
|
||||
for(i = 0; i < TXM_MODULE_LEVEL2_EXTERNAL_PAGES; i++)
|
||||
{
|
||||
if(module_instance->txm_external_page_table[i])
|
||||
{
|
||||
*(ULONG *)module_instance->txm_external_page_table[i] = (ULONG)TX_NULL;
|
||||
module_instance->txm_external_page_table[i] = TX_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_external_memory_enable Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function creates an entry in the MMU table for a shared */
|
||||
/* memory space. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Module instance pointer */
|
||||
/* start_address Start address of memory */
|
||||
/* length Length of external memory */
|
||||
/* attributes Memory attributes */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_mutex_get Get protection mutex */
|
||||
/* _tx_mutex_put Release protection mutex */
|
||||
/* TX_MEMSET Fill memory with constant */
|
||||
/* _txm_level2_page_get Get L2 page table */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _txm_module_manager_external_memory_enable( TXM_MODULE_INSTANCE *module_instance,
|
||||
VOID *start_address,
|
||||
ULONG length,
|
||||
UINT attributes)
|
||||
{
|
||||
|
||||
ULONG start_addr = (ULONG) start_address;
|
||||
ULONG end_addr;
|
||||
ULONG mmu_l1_entries;
|
||||
ULONG mmu_l2_entries = 0;
|
||||
ULONG level1_index;
|
||||
ULONG level2_index;
|
||||
ULONG temp_index;
|
||||
ULONG temp_addr;
|
||||
ULONG page_addr;
|
||||
ULONG asid;
|
||||
ULONG level1_attributes;
|
||||
ULONG level2_attributes;
|
||||
UINT status;
|
||||
UINT i;
|
||||
|
||||
/* Determine if the module manager has not been initialized yet. */
|
||||
if (_txm_module_manager_ready != TX_TRUE)
|
||||
{
|
||||
/* Module manager has not been initialized. */
|
||||
return(TX_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
/* Determine if the module is valid. */
|
||||
if (module_instance == TX_NULL)
|
||||
{
|
||||
/* Invalid module pointer. */
|
||||
return(TX_PTR_ERROR);
|
||||
}
|
||||
|
||||
/* Get module manager protection mutex. */
|
||||
_tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
|
||||
|
||||
/* Determine if the module instance is valid. */
|
||||
if (module_instance -> txm_module_instance_id != TXM_MODULE_ID)
|
||||
{
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Invalid module pointer. */
|
||||
return(TX_PTR_ERROR);
|
||||
}
|
||||
|
||||
/* Determine if the module instance is in the loaded state. */
|
||||
if (module_instance -> txm_module_instance_state != TXM_MODULE_LOADED)
|
||||
{
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Return error if the module is not ready. */
|
||||
return(TX_START_ERROR);
|
||||
}
|
||||
|
||||
/* Determine if the module instance is memory protected. */
|
||||
if (module_instance -> txm_module_instance_asid == 0)
|
||||
{
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Return error if the module is not protected. */
|
||||
return(TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR);
|
||||
}
|
||||
|
||||
/* Start address must be aligned to MMU block size (4 kB).
|
||||
Length will be rounded up to 4 kB alignment. */
|
||||
if(start_addr & ~TXM_MMU_LEVEL2_MASK)
|
||||
{
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Return alignment error. */
|
||||
return(TXM_MODULE_ALIGNMENT_ERROR);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* At this point, we have a valid address. Set up MMU. */
|
||||
/**************************************************************************/
|
||||
|
||||
/* Round length up to 4 kB alignment. */
|
||||
if(length & ~TXM_MMU_LEVEL2_MASK)
|
||||
{
|
||||
length = ((length + TXM_MODULE_MEMORY_ALIGNMENT - 1)/TXM_MODULE_MEMORY_ALIGNMENT) * TXM_MODULE_MEMORY_ALIGNMENT;
|
||||
}
|
||||
|
||||
/* Get end address. */
|
||||
end_addr = start_addr + length - 1;
|
||||
|
||||
/* How many level 1 table entries does data span? */
|
||||
mmu_l1_entries = (end_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1;
|
||||
|
||||
/* Add 1 to align. */
|
||||
end_addr++;
|
||||
|
||||
/* How many level 2 table entries does data need?
|
||||
* 0: start and end addresses both aligned.
|
||||
* 1: either start or end address aligned.
|
||||
* 2: start and end addresses both not aligned. */
|
||||
if(start_addr & ~TXM_MMU_LEVEL1_MASK)
|
||||
{
|
||||
/* If start address is not aligned, increment. */
|
||||
mmu_l2_entries++;
|
||||
}
|
||||
if(end_addr & ~TXM_MMU_LEVEL1_MASK)
|
||||
{
|
||||
/* If end address is not aligned, increment. */
|
||||
mmu_l2_entries++;
|
||||
}
|
||||
|
||||
/* Get index into L1 table. */
|
||||
level1_index = (start_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT);
|
||||
|
||||
/* Get module ASID. */
|
||||
asid = module_instance -> txm_module_instance_asid;
|
||||
|
||||
/* Do start and end entries need level 2 pages? */
|
||||
if(mmu_l2_entries > 0)
|
||||
{
|
||||
/* Build L2 attributes. */
|
||||
level2_attributes = ((attributes & TXM_MMU_ATTRIBUTE_XN) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_XN_SHIFT) |
|
||||
((attributes & TXM_MMU_ATTRIBUTE_B) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_B_SHIFT) |
|
||||
((attributes & TXM_MMU_ATTRIBUTE_C) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_C_SHIFT) |
|
||||
((attributes & TXM_MMU_ATTRIBUTE_AP) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_AP_SHIFT) |
|
||||
((attributes & TXM_MMU_ATTRIBUTE_TEX) << TXM_MMU_LEVEL2_USER_ATTRIBUTE_TEX_SHIFT) |
|
||||
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
|
||||
|
||||
/* If start_addr is not aligned, we need a L2 page. */
|
||||
if(start_addr & ~TXM_MMU_LEVEL1_MASK)
|
||||
{
|
||||
|
||||
/* Is there already an L2 page in the L1 table? */
|
||||
if((_txm_ttbr1_page_table[asid][level1_index] & ~TXM_MMU_LEVEL1_SECOND_MASK) == TXM_MMU_LEVEL1_SECOND_ATTRIBUTES)
|
||||
{
|
||||
page_addr = _txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_SECOND_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get L2 table from pool. */
|
||||
status = _txm_level2_page_get(module_instance, &page_addr);
|
||||
|
||||
if(status != TX_SUCCESS)
|
||||
{
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
return(TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR);
|
||||
}
|
||||
|
||||
/* Clear L2 table. */
|
||||
TX_MEMSET((void *)page_addr, 0, TXM_LEVEL_2_PAGE_TABLE_ENTRIES);
|
||||
|
||||
/* Put L2 page in L1 table. */
|
||||
_txm_ttbr1_page_table[asid][level1_index] = (page_addr & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
|
||||
}
|
||||
|
||||
/* Decrement number of L1 entries remaining. */
|
||||
mmu_l1_entries--;
|
||||
|
||||
/* Set up L2 start table. */
|
||||
/* Determine how many entries in L2 table. */
|
||||
if((end_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT))
|
||||
{
|
||||
/* End address goes to next L1 page (or beyond). */
|
||||
temp_addr = ((start_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1) << (TXM_MMU_LEVEL1_PAGE_SHIFT);
|
||||
mmu_l2_entries = (temp_addr - start_addr) >> TXM_MMU_LEVEL2_PAGE_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* End address is on the same L1 page. */
|
||||
mmu_l2_entries = (end_addr >> TXM_MMU_LEVEL2_PAGE_SHIFT) - (start_addr >> TXM_MMU_LEVEL2_PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/* Insert module settings into start table. */
|
||||
level2_index = ((start_addr & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
|
||||
for(i = 0; i < mmu_l2_entries; i++, level2_index++)
|
||||
{
|
||||
((ULONG *) page_addr)[level2_index] = (start_addr & TXM_MMU_LEVEL1_MASK) | (level2_index << TXM_MMU_LEVEL2_PAGE_SHIFT) | level2_attributes;
|
||||
}
|
||||
|
||||
level1_index++;
|
||||
}
|
||||
|
||||
/* Does last entry need a level 2 page? */
|
||||
/* If end_address is not aligned, we need a L2 page. */
|
||||
if((end_addr & ~TXM_MMU_LEVEL1_MASK) && (mmu_l1_entries != 0))
|
||||
{
|
||||
/* Get index into L1 table. */
|
||||
temp_index = (end_addr >> TXM_MMU_LEVEL1_PAGE_SHIFT);
|
||||
|
||||
/* Is there already an L2 page in the L1 table? */
|
||||
if((_txm_ttbr1_page_table[asid][temp_index] & ~TXM_MMU_LEVEL1_SECOND_MASK) == TXM_MMU_LEVEL1_SECOND_ATTRIBUTES)
|
||||
{
|
||||
page_addr = _txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_SECOND_MASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get L2 table from pool. */
|
||||
status = _txm_level2_page_get(module_instance, &page_addr);
|
||||
|
||||
if(status != TX_SUCCESS)
|
||||
{
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
return(TXM_MODULE_EXTERNAL_MEMORY_ENABLE_ERROR);
|
||||
}
|
||||
|
||||
/* Clear L2 table. */
|
||||
TX_MEMSET((void *)page_addr, 0, TXM_LEVEL_2_PAGE_TABLE_ENTRIES);
|
||||
|
||||
/* Put L2 page in L1 table. */
|
||||
_txm_ttbr1_page_table[asid][temp_index] = (page_addr & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
|
||||
}
|
||||
|
||||
/* Decrement number of L1 entries remaining. */
|
||||
mmu_l1_entries--;
|
||||
|
||||
/* Determine how many entries in L2 table. */
|
||||
mmu_l2_entries = ((end_addr & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
|
||||
|
||||
/* Set up L2 end table. */
|
||||
for(i = 0; i < mmu_l2_entries; i++)
|
||||
{
|
||||
((ULONG *) page_addr)[i] = (end_addr & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | level2_attributes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill any L1 entries between start and end pages of module data range. */
|
||||
for(i = 0; i < mmu_l1_entries; i++, level1_index++)
|
||||
{
|
||||
/* Build L1 attributes. */
|
||||
level1_attributes = ((attributes & TXM_MMU_ATTRIBUTE_XN) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_XN_SHIFT) |
|
||||
((attributes & TXM_MMU_ATTRIBUTE_B) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_B_SHIFT) |
|
||||
((attributes & TXM_MMU_ATTRIBUTE_C) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_C_SHIFT) |
|
||||
((attributes & TXM_MMU_ATTRIBUTE_AP) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_AP_SHIFT) |
|
||||
((attributes & TXM_MMU_ATTRIBUTE_TEX) << TXM_MMU_LEVEL1_USER_ATTRIBUTE_TEX_SHIFT) |
|
||||
TXM_MMU_LEVEL1_USER_ATTRIBUTE_BASE;
|
||||
|
||||
/* Place address and attributes in table. */
|
||||
_txm_ttbr1_page_table[asid][level1_index] = (level1_index << TXM_MMU_LEVEL1_PAGE_SHIFT) | level1_attributes;
|
||||
}
|
||||
|
||||
|
||||
/* Release the protection mutex. */
|
||||
_tx_mutex_put(&_txm_module_manager_mutex);
|
||||
|
||||
/* Return success. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
@@ -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 */
|
||||
/** */
|
||||
/** Module Manager */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "txm_module.h"
|
||||
|
||||
|
||||
/* Define the user's fault notification callback function pointer. This is
|
||||
setup via the txm_module_manager_memory_fault_notify API. */
|
||||
|
||||
VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
|
||||
|
||||
|
||||
/* Define a macro that can be used to allocate global variables useful to
|
||||
store information about the last fault. This macro is defined in
|
||||
txm_module_port.h and is usually populated in the assembly language
|
||||
fault handling prior to the code calling _txm_module_manager_memory_fault_handler. */
|
||||
|
||||
TXM_MODULE_MANAGER_FAULT_INFO
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_memory_fault_handler Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function handles a fault associated with a memory protected */
|
||||
/* module. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_terminate Terminate thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Fault handler */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _txm_module_manager_memory_fault_handler(VOID)
|
||||
{
|
||||
|
||||
TXM_MODULE_INSTANCE *module_instance_ptr;
|
||||
TX_THREAD *thread_ptr;
|
||||
|
||||
|
||||
/* Pickup the current thread. */
|
||||
thread_ptr = _tx_thread_current_ptr;
|
||||
|
||||
/* Initialize the module instance pointer to NULL. */
|
||||
module_instance_ptr = TX_NULL;
|
||||
|
||||
/* Is there a thread? */
|
||||
if (thread_ptr)
|
||||
{
|
||||
/* Pickup the module instance. */
|
||||
module_instance_ptr = thread_ptr -> tx_thread_module_instance_ptr;
|
||||
|
||||
/* Terminate the current thread. */
|
||||
_tx_thread_terminate(_tx_thread_current_ptr);
|
||||
}
|
||||
|
||||
/* Determine if there is a user memory fault notification callback. */
|
||||
if (_txm_module_manager_fault_notify)
|
||||
{
|
||||
/* Yes, call the user's notification memory fault callback. */
|
||||
(_txm_module_manager_fault_notify)(thread_ptr, module_instance_ptr);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/** Module Manager */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "txm_module.h"
|
||||
|
||||
|
||||
/* Define the external user's fault notification callback function pointer. This is
|
||||
setup via the txm_module_manager_memory_fault_notify API. */
|
||||
|
||||
extern VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
|
||||
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_memory_fault_notify Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function registers an application callback when/if a memory */
|
||||
/* fault occurs. The supplied thread is automatically terminated, but */
|
||||
/* any other threads in the same module may still execute. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* notify_function Memory fault notification */
|
||||
/* function, NULL disables. */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _txm_module_manager_memory_fault_notify(VOID (*notify_function)(TX_THREAD *, TXM_MODULE_INSTANCE *))
|
||||
{
|
||||
/* Setup notification function. */
|
||||
_txm_module_manager_fault_notify = notify_function;
|
||||
|
||||
/* Return success. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/** Module Manager */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "txm_module.h"
|
||||
|
||||
#define CACHE_DISABLED 0x12
|
||||
#define SDRAM_START 0x00000000
|
||||
#define SDRAM_END 0x1fffffff
|
||||
#define CACHE_WRITEBACK 0x1e
|
||||
|
||||
#define SECTION_DESCRIPTOR 0x00000002
|
||||
#define DACR_CLIENT_MODE 0x55555555
|
||||
|
||||
|
||||
/*** Page table attributes TTBR0 ***********************************************
|
||||
* IRGN = 01 - Normal memory, Inner Write-Back Write-Allocate Cacheable
|
||||
* S - non-shareable
|
||||
* RGN = 01 - Normal memory, Outer Write-Back Write-Allocate Cacheable
|
||||
* NOS - outer-shareable
|
||||
*******************************************************************************/
|
||||
#define TTBR0_ATTRIBUTES 0x48
|
||||
|
||||
|
||||
|
||||
/* ASID table, index is ASID number and contents hold pointer to module. */
|
||||
TXM_MODULE_INSTANCE *_txm_asid_table[TXM_ASID_TABLE_LENGTH];
|
||||
|
||||
/* Master page table, 2^14 (16kB) alignment.
|
||||
* First table is the master level 1 table, the rest are for each module. */
|
||||
__align(16384) ULONG _txm_ttbr1_page_table[TXM_MAXIMUM_MODULES][TXM_MASTER_PAGE_TABLE_ENTRIES];
|
||||
|
||||
/* Module start and end level 2 page tables, 2^10 (1kB) alignment.
|
||||
* First set of 4 tables are the master level 2 tables, the rest are for each module.
|
||||
* Each module needs two L2 tables for code and two L2 tables for data. */
|
||||
__align(1024) ULONG _txm_level2_module_page_table[TXM_MAXIMUM_MODULES * 4][TXM_LEVEL_2_PAGE_TABLE_ENTRIES];
|
||||
|
||||
/* Module external memory level 2 page tables, 2^10 (1kB) alignment. */
|
||||
__align(1024) ULONG _txm_level2_external_page_pool[TXM_LEVEL2_EXTERNAL_POOL_PAGES][TXM_LEVEL_2_PAGE_TABLE_ENTRIES];
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_mm_initialize Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function performs the initial set up of the the A7 MMU. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _txm_module_manager_mm_initialize(VOID)
|
||||
{
|
||||
|
||||
#ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
|
||||
UINT i;
|
||||
ULONG cp15reg;
|
||||
UINT user_mode_index;
|
||||
UINT counter_limit;
|
||||
|
||||
/* Clear ASID table. */
|
||||
for (i = 0; i < TXM_ASID_TABLE_LENGTH; i++)
|
||||
{
|
||||
_txm_asid_table[i] = 0;
|
||||
}
|
||||
_txm_asid_table[0] = (TXM_MODULE_INSTANCE *)TXM_ASID_RESERVED;
|
||||
|
||||
|
||||
/********************************************************************************/
|
||||
/* This is an example showing how to set up the cache attributes. */
|
||||
/********************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* PAGE TABLE generation
|
||||
* Generate the page tables
|
||||
* Build a flat translation table for the whole address space.
|
||||
* ie: Create 4096 1MB sections from 0x000xxxxx to 0xFFFxxxxx
|
||||
* 31 20|19 18|17|16| 15|14 12|11 10|9|8 5|4 |3 2|1 0|
|
||||
* |base address | 0 0|nG| S|AP2|TEX |AP |P|Domain|XN|CB |1 0|
|
||||
*
|
||||
* Bits[31:20] - Top 12 bits of VA is pointer into table
|
||||
* nG[17]=0 - Non global, enables matching against ASID in the TLB when set.
|
||||
* S[16]=0 - Indicates normal memory is shared when set.
|
||||
* AP2[15]=0
|
||||
* TEX[14:12]=000
|
||||
* AP[11:10]=11 - Configure for full read/write access in all modes
|
||||
* IMPP[9]=0 - Ignored
|
||||
* Domain[5:8]=1111 - Set all pages to use domain 15
|
||||
* XN[4]=0 - Execute never disabled
|
||||
* CB[3:2]= 00 - Set attributes to Strongly-ordered memory.
|
||||
* (except for the descriptor where code segment is based,
|
||||
* see below)
|
||||
* Bits[1:0]=10 - Indicate entry is a 1MB section
|
||||
*******************************************************************************/
|
||||
|
||||
/* ---- Parameter setting to level1 descriptor (bits 19:0) ---- */
|
||||
/* setting for Strongly-ordered memory
|
||||
B-00000000000000000000010111100010 */
|
||||
#define TTB_PARA_STRGLY 0x05E2
|
||||
|
||||
/* setting for Outer and inner not cache normal memory
|
||||
B-00000000000000000001010111100010 */
|
||||
#define TTB_PARA_NORMAL_NOT_CACHE 0x15E2
|
||||
|
||||
/* setting for Outer and inner write back, write allocate normal memory
|
||||
(Cacheable)
|
||||
B-00000000000000000001010111101110 */
|
||||
#define TTB_PARA_NORMAL_CACHE 0x15EE //0x15EE
|
||||
|
||||
/* In this chip (RZA1) there are the following 12 sections with the defined memory size (MB) */
|
||||
#define M_SIZE_NOR 128 /* [Area00] CS0, CS1 area (for NOR flash) */
|
||||
#define M_SIZE_SDRAM 128 /* [Area01] CS2, CS3 area (for SDRAM) */
|
||||
#define M_SIZE_CS45 128 /* [Area02] CS4, CS5 area */
|
||||
#define M_SIZE_SPI 128 /* [Area03] SPI, SP2 area (for Serial flash) */
|
||||
#define M_SIZE_RAM 10 /* [Area04] Internal RAM */
|
||||
#define M_SIZE_IO_1 502 /* [Area05] I/O area 1 */
|
||||
#define M_SIZE_NOR_M 128 /* [Area06] CS0, CS1 area (for NOR flash) (mirror) */
|
||||
#define M_SIZE_SDRAM_M 128 /* [Area07] CS2, CS3 area (for SDRAM) (mirror) */
|
||||
#define M_SIZE_CS45_M 128 /* [Area08] CS4, CS5 area (mirror) */
|
||||
#define M_SIZE_SPI_M 128 /* [Area09] SPI, SP2 area (for Serial flash) (mirror) */
|
||||
#define M_SIZE_RAM_M 10 /* [Area10] Internal RAM (mirror) */
|
||||
#define M_SIZE_IO_2 2550 /* [Area11] I/O area 2 */
|
||||
/* Should add to: 4096 */
|
||||
|
||||
counter_limit = M_SIZE_NOR;
|
||||
for (i = 0; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_CACHE;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_SDRAM;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_CACHE;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_CS45;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_STRGLY;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_SPI;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_CACHE;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_RAM;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_CACHE;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_IO_1;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_STRGLY;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_NOR_M;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_NOT_CACHE;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_SDRAM_M;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_NOT_CACHE;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_CS45_M;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_STRGLY;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_SPI_M;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_NOT_CACHE;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_RAM_M;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_NORMAL_NOT_CACHE;
|
||||
}
|
||||
|
||||
counter_limit += M_SIZE_IO_2;
|
||||
for (; i < counter_limit; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = (i << TXM_MMU_LEVEL1_PAGE_SHIFT) | TTB_PARA_STRGLY;
|
||||
}
|
||||
|
||||
/********************************************************************************/
|
||||
/* This is the end of the example showing how to set up the cache attributes. */
|
||||
/********************************************************************************/
|
||||
|
||||
|
||||
/* Clear ASID. */
|
||||
cp15reg = 0;
|
||||
__asm("mcr p15, 0, cp15reg, c13, c0, 1");
|
||||
__asm("isb");
|
||||
|
||||
/* Put the page table address in TTBR. */
|
||||
cp15reg = (int)(VOID*)_txm_ttbr1_page_table;
|
||||
cp15reg |= TTBR0_ATTRIBUTES;
|
||||
__asm("mcr p15, 0, cp15reg, c2, c0, 0");
|
||||
|
||||
/* Set the domain to client mode. */
|
||||
cp15reg = DACR_CLIENT_MODE;
|
||||
__asm("mcr p15, 0, cp15reg, c3, c0, 0");
|
||||
|
||||
|
||||
/* Level 2 small page attributes: normal memory, cache & buffer enabled, priviledged access. */
|
||||
#define TTB_LEVEL2_NORMAL_CACHE 0x05E
|
||||
|
||||
/* Level 2 clear AP attributes mask. */
|
||||
#define TTB_LEVEL2_AP_CLEAR_MASK 0xFFFFFFCF
|
||||
|
||||
/* Attributes for user mode table entry in level 2 table. */
|
||||
#define TTB_LEVEL2_USER_MODE_ENTRY 0x06E
|
||||
|
||||
/* Set up Level 2 table for user to kernel mode entry trampoline. */
|
||||
/* Find which table entry _txm_module_manager_user_mode_entry is in. */
|
||||
user_mode_index = (ULONG)_txm_module_manager_user_mode_entry >> TXM_MMU_LEVEL1_PAGE_SHIFT;
|
||||
/* Fill table. */
|
||||
for (i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i] = ((ULONG)_txm_module_manager_user_mode_entry & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | TTB_LEVEL2_NORMAL_CACHE;
|
||||
}
|
||||
|
||||
/* Enter Level 2 table in to master table. */
|
||||
_txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][user_mode_index] = ((ULONG)_txm_level2_module_page_table & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
|
||||
|
||||
/* Find level 2 entry that holds _txm_module_manager_user_mode_entry. */
|
||||
user_mode_index = ((ULONG)_txm_module_manager_user_mode_entry & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT;
|
||||
|
||||
/* Set attribute bits for the user mode entry page. */
|
||||
_txm_level2_module_page_table[TXM_MASTER_PAGE_TABLE_INDEX][user_mode_index] = (_txm_level2_module_page_table[TXM_MASTER_PAGE_TABLE_INDEX][user_mode_index] & TTB_LEVEL2_AP_CLEAR_MASK) | TTB_LEVEL2_USER_MODE_ENTRY;
|
||||
|
||||
/* Enable the MMU. */
|
||||
__asm("mrc p15, 0, cp15reg, c1, c0, 0");
|
||||
cp15reg |= 0x1;
|
||||
__asm("mcr p15, 0, cp15reg, c1, c0, 0");
|
||||
|
||||
return(TX_SUCCESS);
|
||||
|
||||
#else
|
||||
return(TX_FEATURE_NOT_ENABLED);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,589 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* 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 */
|
||||
/** */
|
||||
/** Module Manager */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "txm_module.h"
|
||||
|
||||
|
||||
extern TXM_MODULE_INSTANCE *_txm_asid_table[TXM_ASID_TABLE_LENGTH];
|
||||
extern ULONG _txm_level2_module_page_table[TXM_MAXIMUM_MODULES][TXM_LEVEL_2_PAGE_TABLE_ENTRIES];
|
||||
extern ULONG _txm_ttbr1_page_table[TXM_MAXIMUM_MODULES][TXM_MASTER_PAGE_TABLE_ENTRIES];
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_inside_data_check Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function determines if pointer is within the module's data or */
|
||||
/* shared memory. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* pointer Data pointer */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* TXM_MODULE_MANAGER_DATA_POINTER_CHECK */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _txm_module_manager_inside_data_check(ULONG pointer)
|
||||
{
|
||||
|
||||
ULONG translation;
|
||||
|
||||
/* ATS1CUR operation on address supplied in pointer, Stage 1 unprivileged read. */
|
||||
__asm("MCR p15, 0, pointer, c7, c8, 2");
|
||||
__asm("ISB"); /* Ensure completion of the MCR write to CP15. */
|
||||
__asm("MRC p15, 0, translation, c7, c4, 0"); /* Read result from 32-bit PAR into translation. */
|
||||
|
||||
if (translation & TXM_ADDRESS_TRANSLATION_FAULT_BIT)
|
||||
{
|
||||
return(TX_FALSE);
|
||||
}
|
||||
|
||||
return(TX_TRUE);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_assign_asid Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function assigns an Application Specific ID (ASID) to a */
|
||||
/* module. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Pointer to module instance */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* Completion Status */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _txm_module_manager_mm_register_setup */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _txm_module_manager_assign_asid(TXM_MODULE_INSTANCE *module_instance)
|
||||
{
|
||||
UINT i = 1;
|
||||
|
||||
/* Find first non-zero ASID, starting at index 1. */
|
||||
while(i < TXM_ASID_TABLE_LENGTH)
|
||||
{
|
||||
if(_txm_asid_table[i] != 0)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
module_instance -> txm_module_instance_asid = i;
|
||||
_txm_asid_table[i] = module_instance;
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
return(TXM_MODULE_ASID_ERROR);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_remove_asid Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function removes a module from the ASID list. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Pointer to module instance */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* TXM_MODULE_MANAGER_MODULE_UNLOAD */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _txm_module_manager_remove_asid(TXM_MODULE_INSTANCE *module_instance)
|
||||
{
|
||||
if(module_instance -> txm_module_instance_asid)
|
||||
{
|
||||
_txm_asid_table[module_instance -> txm_module_instance_asid] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _txm_module_manager_mm_register_setup Cortex-A7/MMU/AC5 */
|
||||
/* 6.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* Scott Larson, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function sets up the Cortex-A7 MMU register definitions based */
|
||||
/* on the module's memory characteristics. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* module_instance Pointer to module instance */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _txm_module_manager_assign_asid */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* TXM_MODULE_MANAGER_MODULE_SETUP */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
|
||||
{
|
||||
#ifdef TXM_MODULE_MEMORY_PROTECTION_ENABLED
|
||||
|
||||
ULONG start_address;
|
||||
ULONG end_address;
|
||||
ULONG mmu_l1_entries;
|
||||
ULONG mmu_l2_entries = 0;
|
||||
ULONG level1_index;
|
||||
ULONG level2_index;
|
||||
ULONG temp_index;
|
||||
ULONG temp_address;
|
||||
ULONG l2_address;
|
||||
ULONG attributes = 0;
|
||||
ULONG asid;
|
||||
UINT i;
|
||||
|
||||
|
||||
/* Assign an ASID to this module. */
|
||||
_txm_module_manager_assign_asid(module_instance);
|
||||
|
||||
asid = module_instance -> txm_module_instance_asid;
|
||||
|
||||
/* Copy master level 1 page table to module's page table. */
|
||||
for(i = 0; i < TXM_MASTER_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_ttbr1_page_table[asid][i] = _txm_ttbr1_page_table[TXM_MASTER_PAGE_TABLE_INDEX][i];
|
||||
}
|
||||
|
||||
/* Clear level 2 tables. */
|
||||
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET][i] = 0;
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET][i] = 0;
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET][i] = 0;
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET][i] = 0;
|
||||
}
|
||||
|
||||
/* Get code start and end addresses. */
|
||||
start_address = (ULONG)module_instance -> txm_module_instance_code_start;
|
||||
/* Extend end address to end of page (TXM_MODULE_MEMORY_ALIGNMENT-1). */
|
||||
end_address = ((((ULONG)module_instance -> txm_module_instance_code_end) + TXM_MODULE_MEMORY_ALIGNMENT-1) & ~((ULONG)TXM_MODULE_MEMORY_ALIGNMENT-1)) - 1;
|
||||
|
||||
/* How many level 1 table entries does code span? */
|
||||
mmu_l1_entries = (end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1;
|
||||
|
||||
/* Add 1 to align. */
|
||||
end_address++;
|
||||
|
||||
/* How many level 2 table entries does code need?
|
||||
* 0: start and end addresses both aligned.
|
||||
* 1: either start or end address aligned.
|
||||
* 2: start and end addresses both not aligned. */
|
||||
if(start_address & ~TXM_MMU_LEVEL1_MASK)
|
||||
{
|
||||
/* If start address is not aligned, increment. */
|
||||
mmu_l2_entries++;
|
||||
}
|
||||
if(end_address & ~TXM_MMU_LEVEL1_MASK)
|
||||
{
|
||||
/* If end address is not aligned, increment. */
|
||||
mmu_l2_entries++;
|
||||
}
|
||||
|
||||
/* Get index into L1 table. */
|
||||
level1_index = (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT);
|
||||
|
||||
/* Set up level 1 table. */
|
||||
/* Do start and end entries need level 2 pages? */
|
||||
if(mmu_l2_entries > 0)
|
||||
{
|
||||
/* If start_address is not aligned, we need a L2 page. */
|
||||
if(start_address & ~TXM_MMU_LEVEL1_MASK)
|
||||
{
|
||||
/* Is there already a pointer to an L2 page in the L1 table? If bit 0 is set, there is. */
|
||||
if(_txm_ttbr1_page_table[asid][level1_index] & 0x01)
|
||||
{
|
||||
/* Get L2 page address from L1 table. */
|
||||
l2_address = _txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_SECOND_MASK;
|
||||
|
||||
/* Copy the existing L2 page into the module L2 page. */
|
||||
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET][i] = ((ULONG *) l2_address)[i] | TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Translate attributes from L1 entry to an L2 entry. */
|
||||
attributes = (((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT) |
|
||||
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
|
||||
|
||||
/* Build L2 page with attributes inherited from L1 entry. */
|
||||
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET][i] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | attributes;
|
||||
}
|
||||
}
|
||||
|
||||
/* Put L2 page in L1 table. */
|
||||
_txm_ttbr1_page_table[asid][level1_index] = ((ULONG)_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET] & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
|
||||
|
||||
/* Decrement number of L1 entries remaining. */
|
||||
mmu_l1_entries--;
|
||||
|
||||
/* Set up L2 start table. */
|
||||
/* Determine how many entries in L2 table. */
|
||||
if((end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT))
|
||||
{
|
||||
/* End address goes to next L1 page (or beyond). */
|
||||
temp_address = ((start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1) << (TXM_MMU_LEVEL1_PAGE_SHIFT);
|
||||
mmu_l2_entries = (temp_address - start_address) >> TXM_MMU_LEVEL2_PAGE_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* End address is on the same L1 page. */
|
||||
mmu_l2_entries = (end_address >> TXM_MMU_LEVEL2_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL2_PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/* Insert module settings into start table. */
|
||||
level2_index = ((start_address & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
|
||||
for(i = 0; i < mmu_l2_entries; i++, level2_index++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_START_OFFSET][level2_index] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (level2_index << TXM_MMU_LEVEL2_PAGE_SHIFT) | TXM_MMU_LEVEL2_CODE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
level1_index++;
|
||||
}
|
||||
|
||||
/* Does last entry need a level 2 page? */
|
||||
/* If end_address is not aligned, we need a L2 page. */
|
||||
if((end_address & ~TXM_MMU_LEVEL1_MASK) && (mmu_l1_entries != 0))
|
||||
{
|
||||
/* Get index into L1 table. */
|
||||
temp_index = (end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT);
|
||||
|
||||
/* Is there already a pointer to an L2 page in the L1 table? If bit 0 is set, there is. */
|
||||
if(_txm_ttbr1_page_table[asid][temp_index] & 0x01)
|
||||
{
|
||||
/* Get L2 page address from L1 table. */
|
||||
l2_address = _txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_SECOND_MASK;
|
||||
|
||||
/* Copy the existing L2 page into the module L2 page. */
|
||||
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET][i] = ((ULONG *) l2_address)[i] | TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Translate attributes from L1 entry to an L2 entry. */
|
||||
attributes = (((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT) |
|
||||
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
|
||||
|
||||
/* Build L2 page with attributes inherited from L1 entry. */
|
||||
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET][i] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | attributes;
|
||||
}
|
||||
}
|
||||
|
||||
/* Put L2 page in L1 table. */
|
||||
_txm_ttbr1_page_table[asid][temp_index] = ((ULONG)_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET] & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
|
||||
|
||||
/* Decrement number of L1 entries remaining. */
|
||||
mmu_l1_entries--;
|
||||
|
||||
/* Determine how many entries in L2 table. */
|
||||
mmu_l2_entries = ((end_address & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
|
||||
|
||||
/* Set up L2 end table. */
|
||||
for(i = 0; i < mmu_l2_entries; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_CODE_PAGE_TABLE_END_OFFSET][i] = ((ULONG)end_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | TXM_MMU_LEVEL2_CODE_ATTRIBUTES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill any L1 entries between start and end pages of module code range. */
|
||||
for(i = 0; i < mmu_l1_entries; i++, level1_index++)
|
||||
{
|
||||
/* Place address and attributes in table. */
|
||||
_txm_ttbr1_page_table[asid][level1_index] = (level1_index << TXM_MMU_LEVEL1_PAGE_SHIFT) | TXM_MMU_LEVEL1_CODE_ATTRIBUTES;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/* At this point, code protection is set up. */
|
||||
/* Data protection is set up below. */
|
||||
/**************************************************************************/
|
||||
|
||||
/* Get data start and end addresses. */
|
||||
start_address = (ULONG)module_instance -> txm_module_instance_data_start;
|
||||
end_address = (ULONG)module_instance -> txm_module_instance_data_end;
|
||||
|
||||
/* How many level 1 table entries does data span? */
|
||||
mmu_l1_entries = (end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1;
|
||||
|
||||
/* Add 1 to align. */
|
||||
end_address++;
|
||||
|
||||
/* How many level 2 table entries does data need?
|
||||
* 0: start and end addresses both aligned.
|
||||
* 1: either start or end address aligned.
|
||||
* 2: start and end addresses both not aligned. */
|
||||
if(start_address & ~TXM_MMU_LEVEL1_MASK)
|
||||
{
|
||||
/* If start address is not aligned, increment. */
|
||||
mmu_l2_entries++;
|
||||
}
|
||||
if(end_address & ~TXM_MMU_LEVEL1_MASK)
|
||||
{
|
||||
/* If end address is not aligned, increment. */
|
||||
mmu_l2_entries++;
|
||||
}
|
||||
|
||||
/* Get index into L1 table. */
|
||||
level1_index = (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT);
|
||||
|
||||
/* Set up level 1 table. */
|
||||
/* Do start and end entries need level 2 pages? */
|
||||
if(mmu_l2_entries > 0)
|
||||
{
|
||||
/* If start_address is not aligned, we need a L2 page. */
|
||||
if(start_address & ~TXM_MMU_LEVEL1_MASK)
|
||||
{
|
||||
/* Is there already a pointer to an L2 page in the L1 table? If bit 0 is set, there is. */
|
||||
if(_txm_ttbr1_page_table[asid][level1_index] & 0x01)
|
||||
{
|
||||
/* Get L2 page address from L1 table. */
|
||||
l2_address = _txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_SECOND_MASK;
|
||||
|
||||
/* Copy the existing L2 page into the module L2 page. */
|
||||
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET][i] = ((ULONG *) l2_address)[i] | TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Translate attributes from L1 entry to an L2 entry. */
|
||||
attributes = (((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][level1_index] & TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT) |
|
||||
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
|
||||
|
||||
/* Build L2 page with attributes inherited from L1 entry. */
|
||||
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET][i] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | attributes;
|
||||
}
|
||||
}
|
||||
|
||||
/* Put L2 page in L1 table. */
|
||||
_txm_ttbr1_page_table[asid][level1_index] = ((ULONG)_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET] & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
|
||||
|
||||
/* Decrement number of L1 entries remaining. */
|
||||
mmu_l1_entries--;
|
||||
|
||||
/* Set up L2 start table. */
|
||||
/* Determine how many entries in L2 table. */
|
||||
if((end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT))
|
||||
{
|
||||
/* End address goes to next L1 page (or beyond). */
|
||||
temp_address = ((start_address >> TXM_MMU_LEVEL1_PAGE_SHIFT) + 1) << (TXM_MMU_LEVEL1_PAGE_SHIFT);
|
||||
mmu_l2_entries = (temp_address - start_address) >> TXM_MMU_LEVEL2_PAGE_SHIFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* End address is on the same L1 page. */
|
||||
mmu_l2_entries = (end_address >> TXM_MMU_LEVEL2_PAGE_SHIFT) - (start_address >> TXM_MMU_LEVEL2_PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/* Insert module settings into start table. */
|
||||
level2_index = ((start_address & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
|
||||
for(i = 0; i < mmu_l2_entries; i++, level2_index++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_START_OFFSET][level2_index] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (level2_index << TXM_MMU_LEVEL2_PAGE_SHIFT) | TXM_MMU_LEVEL2_DATA_ATTRIBUTES;
|
||||
}
|
||||
|
||||
level1_index++;
|
||||
}
|
||||
|
||||
/* Does last entry need a level 2 page? */
|
||||
/* If end_address is not aligned, we need a L2 page. */
|
||||
if((end_address & ~TXM_MMU_LEVEL1_MASK) && (mmu_l1_entries != 0))
|
||||
{
|
||||
/* Get index into L1 table. */
|
||||
temp_index = (end_address >> TXM_MMU_LEVEL1_PAGE_SHIFT);
|
||||
|
||||
/* Is there already a pointer to an L2 page in the L1 table? If bit 0 is set, there is. */
|
||||
if(_txm_ttbr1_page_table[asid][temp_index] & 0x01)
|
||||
{
|
||||
/* Get L2 page address from L1 table. */
|
||||
l2_address = _txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_SECOND_MASK;
|
||||
|
||||
/* Copy the existing L2 page into the module L2 page. */
|
||||
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET][i] = ((ULONG *) l2_address)[i] | TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Translate attributes from L1 entry to an L2 entry. */
|
||||
attributes = (((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_XN_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_XN_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_XN_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_B_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_B_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_B_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_C_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_C_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_C_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_AP_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_AP_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_AP_SHIFT) |
|
||||
(((_txm_ttbr1_page_table[asid][temp_index] & TXM_MMU_LEVEL1_ATTRIBUTE_TEX_MASK) >> TXM_MMU_LEVEL1_ATTRIBUTE_TEX_SHIFT) << TXM_MMU_LEVEL2_ATTRIBUTE_TEX_SHIFT) |
|
||||
TXM_MMU_LEVEL2_USER_ATTRIBUTE_BASE;
|
||||
|
||||
/* Build L2 page with attributes inherited from L1 entry. */
|
||||
for(i = 0; i < TXM_LEVEL_2_PAGE_TABLE_ENTRIES; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET][i] = ((ULONG)start_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | attributes;
|
||||
}
|
||||
}
|
||||
|
||||
/* Put L2 page in L1 table. */
|
||||
_txm_ttbr1_page_table[asid][temp_index] = ((ULONG)_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET] & TXM_MMU_LEVEL1_SECOND_MASK) | TXM_MMU_LEVEL1_SECOND_ATTRIBUTES;
|
||||
|
||||
/* Decrement number of L1 entries remaining. */
|
||||
mmu_l1_entries--;
|
||||
|
||||
/* Determine how many entries in L2 table. */
|
||||
mmu_l2_entries = ((end_address & ~TXM_MMU_LEVEL1_MASK) >> TXM_MMU_LEVEL2_PAGE_SHIFT);
|
||||
|
||||
/* Set up L2 end table. */
|
||||
for(i = 0; i < mmu_l2_entries; i++)
|
||||
{
|
||||
_txm_level2_module_page_table[asid + TXM_MODULE_DATA_PAGE_TABLE_END_OFFSET][i] = ((ULONG)end_address & TXM_MMU_LEVEL1_MASK) | (i << TXM_MMU_LEVEL2_PAGE_SHIFT) | TXM_MMU_LEVEL2_DATA_ATTRIBUTES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill any L1 entries between start and end pages of module data range. */
|
||||
for(i = 0; i < mmu_l1_entries; i++, level1_index++)
|
||||
{
|
||||
/* Place address and attributes in table. */
|
||||
_txm_ttbr1_page_table[asid][level1_index] = (level1_index << TXM_MMU_LEVEL1_PAGE_SHIFT) | TXM_MMU_LEVEL1_DATA_ATTRIBUTES;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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 */
|
||||
;/** */
|
||||
;/** Module Manager */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
;
|
||||
;#define TX_SOURCE_CODE
|
||||
;
|
||||
;
|
||||
;/* Include necessary system files. */
|
||||
;
|
||||
;#include "tx_api.h"
|
||||
;#include "tx_thread.h"
|
||||
;
|
||||
;
|
||||
THUMB_MASK EQU 0x20 ; Thumb bit (5) of CPSR/SPSR
|
||||
USR_MODE EQU 0x10 ; USR mode
|
||||
SYS_MODE EQU 0x1F ; SYS 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 */
|
||||
;/* */
|
||||
;/* _txm_module_manager_thread_stack_build Cortex-A7/MMU/AC5 */
|
||||
;/* 6.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* Scott Larson, 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 */
|
||||
;/* */
|
||||
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
;VOID _txm_module_manager_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(TX_THREAD *, TXM_MODULE_INSTANCE *))
|
||||
;{
|
||||
EXPORT _txm_module_manager_thread_stack_build
|
||||
_txm_module_manager_thread_stack_build
|
||||
;
|
||||
;
|
||||
; /* Build a fake interrupt frame. The form of the fake interrupt stack
|
||||
; on the Cortex-A7 should look like the following after it is built:
|
||||
;
|
||||
; Stack Top: 1 Interrupt stack frame type
|
||||
; CPSR Initial value for CPSR
|
||||
; r0 Initial value for r0
|
||||
; r1 Initial value for r1
|
||||
; r2 Initial value for r2
|
||||
; r3 Initial value for r3
|
||||
; r4 Initial value for r4
|
||||
; r5 Initial value for r5
|
||||
; r6 Initial value for r6
|
||||
; r7 Initial value for r7
|
||||
; r8 Initial value for r8
|
||||
; r9 Initial value for r9
|
||||
; r10 Initial value for r10
|
||||
; r11 Initial value for r11
|
||||
; r12 Initial value for r12
|
||||
; lr Initial value for lr (r14)
|
||||
; pc Initial value for pc (r15)
|
||||
; 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
|
||||
STR r0, [r2, #8] ; Store initial r0 (thread pointer)
|
||||
LDR r3, [r0, #8] ; Pickup thread info pointer (it's in the stack pointer location right now)
|
||||
STR r3, [r2, #12] ; Store initial r1
|
||||
LDR r3, [r3, #8] ; Pickup data base register
|
||||
STR r3, [r2, #44] ; Store initial r9
|
||||
MOV r3, #0 ; Build initial register value
|
||||
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
|
||||
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 r3, CPSR ; Pickup CPSR
|
||||
BIC r3, r3, #CPSR_MASK ; Mask mode bits of CPSR
|
||||
TST r1, #1 ; Test if THUMB bit set in initial PC
|
||||
ORRNE r3, r3, #THUMB_MASK ; Set T bit if set
|
||||
LDR r1, [r0, #156] ; Load tx_thread_module_current_user_mode
|
||||
TST r1, #1 ; Test if the flag is set
|
||||
ORREQ r3, r3, #SYS_MODE ; Flag not set: Build CPSR, SYS mode, IRQ enabled
|
||||
ORRNE r3, r3, #USR_MODE ; Flag set: Build CPSR, USR mode, IRQ 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
|
||||
BX lr ; Return to caller
|
||||
;}
|
||||
END
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* 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 */
|
||||
;/** */
|
||||
;/** Module Manager */
|
||||
;/** */
|
||||
;/**************************************************************************/
|
||||
;/**************************************************************************/
|
||||
;
|
||||
IMPORT _tx_thread_current_ptr
|
||||
IMPORT _txm_module_manager_kernel_dispatch
|
||||
|
||||
|
||||
AREA ||.text||, CODE, READONLY, ALIGN=12
|
||||
PRESERVE8
|
||||
;/**************************************************************************/
|
||||
;/* */
|
||||
;/* FUNCTION RELEASE */
|
||||
;/* */
|
||||
;/* _txm_module_manager_user_mode_entry Cortex-A7/MMU/AC5 */
|
||||
;/* 6.1 */
|
||||
;/* AUTHOR */
|
||||
;/* */
|
||||
;/* Scott Larson, Microsoft Corporation */
|
||||
;/* */
|
||||
;/* DESCRIPTION */
|
||||
;/* */
|
||||
;/* This function allows modules to enter kernel mode. */
|
||||
;/* */
|
||||
;/* INPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* OUTPUT */
|
||||
;/* */
|
||||
;/* None */
|
||||
;/* */
|
||||
;/* CALLS */
|
||||
;/* */
|
||||
;/* SVC 1 Enter kernel mode */
|
||||
;/* SVC 2 Exit kernel mode */
|
||||
;/* */
|
||||
;/* CALLED BY */
|
||||
;/* */
|
||||
;/* Modules in user mode */
|
||||
;/* */
|
||||
;/* RELEASE HISTORY */
|
||||
;/* */
|
||||
;/* DATE NAME DESCRIPTION */
|
||||
;/* */
|
||||
;/* 09-30-2020 Scott Larson Initial Version 6.1 */
|
||||
;/* */
|
||||
;/**************************************************************************/
|
||||
EXPORT _txm_module_manager_user_mode_entry
|
||||
EXPORT _txm_system_mode_enter
|
||||
_txm_module_manager_user_mode_entry
|
||||
_txm_system_mode_enter
|
||||
SVC 1 ; Get out of user mode
|
||||
_txm_module_priv
|
||||
; At this point, we are in system mode.
|
||||
; Save LR (and r3 for 8 byte aligned stack) and call the kernel dispatch function.
|
||||
PUSH {r3, lr}
|
||||
BL _txm_module_manager_kernel_dispatch
|
||||
POP {r3, lr}
|
||||
|
||||
EXPORT _txm_system_mode_exit
|
||||
_txm_system_mode_exit
|
||||
; Trap to restore user mode while inside of ThreadX
|
||||
SVC 2
|
||||
|
||||
BX lr ; Return to the caller
|
||||
NOP
|
||||
NOP
|
||||
|
||||
; Fill up 4kB page.
|
||||
ALIGN 4096
|
||||
_txm_module_manager_user_mode_end
|
||||
|
||||
END
|
||||
Reference in New Issue
Block a user