6.1 minor release

This commit is contained in:
Scott Larson
2020-09-30 15:42:41 -07:00
parent 7287542cc8
commit 1b5816a206
3038 changed files with 377204 additions and 8606 deletions

View File

@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* */
/* AUTHOR */
/* */
@@ -47,7 +47,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
@@ -418,7 +418,7 @@ VOID tx_thread_fp_disable(VOID);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) 1996-2019 Express Logic Inc. * ThreadX Cortex-A5x-SMP/AC6 Version 6.0.1 *";
"Copyright (c) 1996-2019 Express Logic Inc. * ThreadX Cortex-A5x-SMP/AC6 Version 6.1 *";
#else
extern CHAR _tx_version_id[];
#endif

View File

@@ -247,7 +247,7 @@ For generic code revision information, please refer to the readme_threadx_generi
file, which is included in your distribution. The following details the revision
information associated with this specific port of ThreadX:
06/30/2020 Initial ThreadX 6.0.1 version for Cortex-A5x using AC6 tools.
09/30/2020 Initial ThreadX 6.1 version for Cortex-A5x using AC6 tools.
Copyright(c) 1996-2020 Microsoft Corporation

View File

@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -73,7 +73,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_initialize_low_level(VOID)

View File

@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -74,7 +74,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_restore(VOID)
@@ -97,10 +97,17 @@ _tx_thread_context_restore:
/* Pickup the CPU ID. */
MRS x8, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x8, #16, #8 // Isolate cluster ID
#endif
UBFX x8, x8, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x8, #8, #8 // Isolate cluster ID
#endif
UBFX x8, x8, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x8, x8, x2, LSL #2 // Calculate CPU ID
#endif

View File

@@ -38,7 +38,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -69,7 +69,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_save(VOID)
@@ -92,10 +92,17 @@ _tx_thread_context_save:
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x2, LSL #2 // Calculate CPU ID
#endif
@@ -198,10 +205,17 @@ __tx_thread_not_nested_save:
LDR x3, =_tx_thread_system_stack_ptr // Pickup address of system stack
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x2, LSL #2 // Calculate CPU ID
#endif

View File

@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fp_disable Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -63,7 +63,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_fp_disable(VOID)

View File

@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fp_enable Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -63,7 +63,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_fp_enable(VOID)

View File

@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -67,7 +67,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_control(UINT new_posture)

View File

@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -66,7 +66,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_disable(void)

View File

@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_restore Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -67,7 +67,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_restore(UINT old_posture)

View File

@@ -39,7 +39,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -72,7 +72,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_schedule(VOID)
@@ -88,10 +88,17 @@ _tx_thread_schedule:
/* Pickup the CPU ID. */
MRS x20, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x1, x20, #16, #8 // Isolate cluster ID
#endif
UBFX x20, x20, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x1, x20, #8, #8 // Isolate cluster ID
#endif
UBFX x20, x20, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x20, x20, x1, LSL #2 // Calculate CPU ID
#endif

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_core_get Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,17 +70,24 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_core_get
.type _tx_thread_smp_core_get, @function
_tx_thread_smp_core_get:
MRS x0, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x1, x0, #16, #8 // Isolate cluster ID
#endif
UBFX x0, x0, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x1, x0, #8, #8 // Isolate cluster ID
#endif
UBFX x0, x0, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x0, x0, x1, LSL #2 // Calculate CPU ID
#endif

View File

@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_core_preempt Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -73,15 +73,21 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_core_preempt
.type _tx_thread_smp_core_preempt, @function
_tx_thread_smp_core_preempt:
DSB ISH
#ifdef TX_ARMV8_2
MOV x2, #0x1 // Build the target list field
LSL x3, x0, #16 // Build the affinity1 field
ORR x2, x2, x3 // Combine the fields
#else
MOV x2, #0x1 //
LSL x2, x2, x0 // Shift by the core ID
#endif
MSR ICC_SGI1R_EL1, x2 // Issue inter-core interrupt
RET

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_current_state_get Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,7 +70,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_current_state_get
@@ -80,10 +80,17 @@ _tx_thread_smp_current_state_get:
MRS x1, DAIF // Pickup current interrupt posture
MSR DAIFSet, 0x3 // Lockout interrupts
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x2, x2, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_current_thread_get Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,7 +70,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_current_thread_get
@@ -80,10 +80,17 @@ _tx_thread_smp_current_thread_get:
MRS x1, DAIF // Pickup current interrupt posture
MSR DAIFSet, 0x3 // Lockout interrupts
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x2, x2, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_initialize_wait Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -72,7 +72,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_initialize_wait
@@ -86,10 +86,17 @@ _tx_thread_smp_initialize_wait:
/* Pickup the Core ID. */
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x2, x2, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_low_level_initialize Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,7 +70,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_low_level_initialize

View File

@@ -44,7 +44,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_protect Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -75,7 +75,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_protect
@@ -90,10 +90,17 @@ _tx_thread_smp_protect:
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
#endif
@@ -248,10 +255,17 @@ _try_to_get_lock:
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
#endif

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_time_get Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -71,7 +71,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_time_get

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_unprotect Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -73,7 +73,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_unprotect
@@ -82,10 +82,17 @@ _tx_thread_smp_unprotect:
MSR DAIFSet, 0x3 // Lockout interrupts
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x2, LSL #2 // Calculate CPU ID
#endif

View File

@@ -39,7 +39,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -71,7 +71,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))

View File

@@ -38,7 +38,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,7 +70,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_system_return(VOID)
@@ -90,10 +90,17 @@ _tx_thread_system_return:
STP x25, x26, [sp, #-16]! // Save x25, x26
STP x27, x28, [sp, #-16]! // Save x27, x28
MRS x8, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x8, #16, #8 // Isolate cluster ID
#endif
UBFX x8, x8, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x8, #8, #8 // Isolate cluster ID
#endif
UBFX x8, x8, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x8, x8, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_timeout Cortex-A5x-SMP */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -71,7 +71,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_timeout(ULONG timeout_input)

View File

@@ -38,7 +38,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt Cortex-A5x-SMP/AC6 */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -72,7 +72,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_timer_interrupt(VOID)
@@ -82,10 +82,17 @@
_tx_timer_interrupt:
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x2, x2, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* */
/* AUTHOR */
/* */
@@ -47,7 +47,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
@@ -418,7 +418,7 @@ VOID tx_thread_fp_disable(VOID);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-A5x-SMP/GNU Version 6.0.1 *";
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-A5x-SMP/GNU Version 6.1 *";
#else
extern CHAR _tx_version_id[];
#endif

View File

@@ -247,7 +247,7 @@ For generic code revision information, please refer to the readme_threadx_generi
file, which is included in your distribution. The following details the revision
information associated with this specific port of ThreadX SMP:
06/30/2020 Initial ThreadX 6.0.1 version for Cortex-A5x using ARM GCC and DS-5 tools.
09-30-2020 Initial ThreadX 6.1 version for Cortex-A5x using ARM GCC and DS-5 tools.
Copyright(c) 1996-2020 Microsoft Corporation

View File

@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -73,7 +73,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_initialize_low_level(VOID)

View File

@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -74,7 +74,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_restore(VOID)
@@ -97,10 +97,17 @@ _tx_thread_context_restore:
/* Pickup the CPU ID. */
MRS x8, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x8, #16, #8 // Isolate cluster ID
#endif
UBFX x8, x8, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x8, #8, #8 // Isolate cluster ID
#endif
UBFX x8, x8, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x8, x8, x2, LSL #2 // Calculate CPU ID
#endif

View File

@@ -38,7 +38,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -69,7 +69,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_save(VOID)
@@ -92,10 +92,17 @@ _tx_thread_context_save:
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x2, LSL #2 // Calculate CPU ID
#endif
@@ -198,10 +205,17 @@ __tx_thread_not_nested_save:
LDR x3, =_tx_thread_system_stack_ptr // Pickup address of system stack
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x2, LSL #2 // Calculate CPU ID
#endif

View File

@@ -34,7 +34,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fp_disable Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -63,7 +63,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_fp_disable(VOID)

View File

@@ -33,7 +33,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fp_enable Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -62,7 +62,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_fp_enable(VOID)

View File

@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -67,7 +67,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_control(UINT new_posture)

View File

@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -66,7 +66,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_disable(void)

View File

@@ -37,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_restore Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -67,7 +67,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* UINT _tx_thread_interrupt_restore(UINT old_posture)

View File

@@ -39,7 +39,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -72,7 +72,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_schedule(VOID)
@@ -88,10 +88,17 @@ _tx_thread_schedule:
/* Pickup the CPU ID. */
MRS x20, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x1, x20, #16, #8 // Isolate cluster ID
#endif
UBFX x20, x20, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x1, x20, #8, #8 // Isolate cluster ID
#endif
UBFX x20, x20, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x20, x20, x1, LSL #2 // Calculate CPU ID
#endif

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_core_get Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,17 +70,24 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_core_get
.type _tx_thread_smp_core_get, @function
_tx_thread_smp_core_get:
MRS x0, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x1, x0, #16, #8 // Isolate cluster ID
#endif
UBFX x0, x0, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x1, x0, #8, #8 // Isolate cluster ID
#endif
UBFX x0, x0, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x0, x0, x1, LSL #2 // Calculate CPU ID
#endif

View File

@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_core_preempt Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -75,15 +75,21 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_core_preempt
.type _tx_thread_smp_core_preempt, @function
_tx_thread_smp_core_preempt:
DSB ISH
DSB ISH
#ifdef TX_ARMV8_2
MOV x2, #0x1 // Build the target list field
LSL x3, x0, #16 // Build the affinity1 field
ORR x2, x2, x3 // Combine the fields
#else
MOV x2, #0x1 //
LSL x2, x2, x0 // Shift by the core ID
#endif
MSR ICC_SGI1R_EL1, x2 // Issue inter-core interrupt
RET

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_current_state_get Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,7 +70,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_current_state_get
@@ -80,10 +80,17 @@ _tx_thread_smp_current_state_get:
MRS x1, DAIF // Pickup current interrupt posture
MSR DAIFSet, 0x3 // Lockout interrupts
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x2, x2, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_current_thread_get Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,7 +70,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_current_thread_get
@@ -80,10 +80,17 @@ _tx_thread_smp_current_thread_get:
MRS x1, DAIF // Pickup current interrupt posture
MSR DAIFSet, 0x3 // Lockout interrupts
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x2, x2, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_initialize_wait Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -72,7 +72,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_initialize_wait
@@ -86,10 +86,17 @@ _tx_thread_smp_initialize_wait:
/* Pickup the Core ID. */
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x2, x2, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_low_level_initialize Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,7 +70,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_low_level_initialize

View File

@@ -44,7 +44,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_protect Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -75,7 +75,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_protect
@@ -90,10 +90,17 @@ _tx_thread_smp_protect:
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
#endif
@@ -248,10 +255,17 @@ _try_to_get_lock:
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x7, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
#endif

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_time_get Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -71,7 +71,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_time_get

View File

@@ -41,7 +41,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_unprotect Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -73,7 +73,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_unprotect
@@ -82,10 +82,17 @@ _tx_thread_smp_unprotect:
MSR DAIFSet, 0x3 // Lockout interrupts
MRS x1, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #16, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x2, x1, #8, #8 // Isolate cluster ID
#endif
UBFX x1, x1, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x1, x1, x2, LSL #2 // Calculate CPU ID
#endif

View File

@@ -39,7 +39,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -71,7 +71,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))

View File

@@ -38,7 +38,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return Cortex-A5x-SMP/ARM */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -70,7 +70,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_system_return(VOID)
@@ -90,10 +90,17 @@ _tx_thread_system_return:
STP x25, x26, [sp, #-16]! // Save x25, x26
STP x27, x28, [sp, #-16]! // Save x27, x28
MRS x8, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x8, #16, #8 // Isolate cluster ID
#endif
UBFX x8, x8, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x8, #8, #8 // Isolate cluster ID
#endif
UBFX x8, x8, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x8, x8, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -35,7 +35,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_timeout Cortex-A5x-SMP */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -71,7 +71,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_timeout(ULONG timeout_input)

View File

@@ -38,7 +38,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt Cortex-A5x-SMP/GNU */
/* 6.0.1 */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -72,7 +72,7 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_timer_interrupt(VOID)
@@ -82,10 +82,17 @@
_tx_timer_interrupt:
MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #16, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
UBFX x3, x2, #8, #8 // Isolate cluster ID
#endif
UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
ADDS x2, x2, x3, LSL #2 // Calculate CPU ID
#endif

View File

@@ -0,0 +1,12 @@
#!gbuild
defineConfig ("Debug" "DBG" "tgt\debug.gpc")
defineConfig ("Release" "REL" "tgt\release.gpc")
primaryTarget=arm64_standalone.tgt
#component top_level_project
[Project]
-bsp generic
-cpu=cortexa53
:sourceDir=.
tx\libtx.gpj [Library]
sample_threadx\sample_threadx.gpj [Program]
tgt\resources.gpj [Project]

View File

@@ -0,0 +1,388 @@
/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
byte pool, and block pool. */
#include "tx_api.h"
#include <stdio.h>
#define DEMO_STACK_SIZE 1024
#define DEMO_BYTE_POOL_SIZE 9120
#define DEMO_BLOCK_POOL_SIZE 100
#define DEMO_QUEUE_SIZE 100
/* Define the ThreadX object control blocks... */
TX_THREAD thread_0;
TX_THREAD thread_1;
TX_THREAD thread_2;
TX_THREAD thread_3;
TX_THREAD thread_4;
TX_THREAD thread_5;
TX_THREAD thread_6;
TX_THREAD thread_7;
TX_QUEUE queue_0;
TX_SEMAPHORE semaphore_0;
TX_MUTEX mutex_0;
TX_EVENT_FLAGS_GROUP event_flags_0;
TX_BYTE_POOL byte_pool_0;
TX_BLOCK_POOL block_pool_0;
/* Define the counters used in the demo application... */
ULONG thread_0_counter;
ULONG thread_1_counter;
ULONG thread_1_messages_sent;
ULONG thread_2_counter;
ULONG thread_2_messages_received;
ULONG thread_3_counter;
ULONG thread_4_counter;
ULONG thread_5_counter;
ULONG thread_6_counter;
ULONG thread_7_counter;
UCHAR memory_pool[DEMO_BYTE_POOL_SIZE];
/* Define thread prototypes. */
void thread_0_entry(ULONG thread_input);
void thread_1_entry(ULONG thread_input);
void thread_2_entry(ULONG thread_input);
void thread_3_and_4_entry(ULONG thread_input);
void thread_5_entry(ULONG thread_input);
void thread_6_and_7_entry(ULONG thread_input);
/* Define main entry point. */
int main()
{
/* Enter the ThreadX kernel. */
tx_kernel_enter();
}
/* Define what the initial system looks like. */
void tx_application_define(void *first_unused_memory)
{
CHAR *pointer = TX_NULL;
/* Create a byte memory pool from which to allocate the thread stacks. */
tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_pool, DEMO_BYTE_POOL_SIZE);
/* Put system definition stuff in here, e.g. thread creates and other assorted
create information. */
/* Allocate the stack for thread 0. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create the main thread. */
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
pointer, DEMO_STACK_SIZE,
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 1. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create threads 1 and 2. These threads pass information through a ThreadX
message queue. It is also interesting to note that these threads have a time
slice. */
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
pointer, DEMO_STACK_SIZE,
16, 16, 4, TX_AUTO_START);
/* Allocate the stack for thread 2. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
pointer, DEMO_STACK_SIZE,
16, 16, 4, TX_AUTO_START);
/* Allocate the stack for thread 3. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
An interesting thing here is that both threads share the same instruction area. */
tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 4. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 5. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create thread 5. This thread simply pends on an event flag which will be set
by thread_0. */
tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
pointer, DEMO_STACK_SIZE,
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 6. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the stack for thread 7. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
pointer, DEMO_STACK_SIZE,
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
/* Allocate the message queue. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
/* Create the message queue shared by threads 1 and 2. */
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
/* Create the semaphore used by threads 3 and 4. */
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
/* Create the event flags group used by threads 1 and 5. */
tx_event_flags_create(&event_flags_0, "event flags 0");
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
/* Allocate the memory for a small block pool. */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
/* Create a block memory pool to allocate a message buffer from. */
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
/* Allocate a block and release the block memory. */
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
/* Release the block back to the pool. */
tx_block_release(pointer);
}
/* Define the test threads. */
void thread_0_entry(ULONG thread_input)
{
UINT status;
/* This thread simply sits in while-forever-sleep loop. */
while(1)
{
/* Increment the thread counter. */
thread_0_counter++;
/* Print results every second. */
if (thread_0_counter % 10 == 1)
{
printf("**** ThreadX SMP Zynq UltraScale+ MPSoC/Cortex-A53 Demonstration **** (c) 1996-2018 Express Logic, Inc.\n\n");
printf(" thread 0 events sent: %lu\n", thread_0_counter);
printf(" thread 1 messages sent: %lu\n", thread_1_counter);
printf(" thread 2 messages received: %lu\n", thread_2_counter);
printf(" thread 3 obtained semaphore: %lu\n", thread_3_counter);
printf(" thread 4 obtained semaphore: %lu\n", thread_4_counter);
printf(" thread 5 events received: %lu\n", thread_5_counter);
printf(" thread 6 mutex obtained: %lu\n", thread_6_counter);
printf(" thread 7 mutex obtained: %lu\n\n", thread_7_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;
}
}

View File

@@ -0,0 +1,16 @@
#!gbuild
[Program]
-object_dir=${%option_value(-object_dir)}/sample_threadx
-I../../../../../common_smp/inc
-I../../../../../ports_common_green/inc
-I../../inc
{config(DBG)} -L../bin/Debug
-ltx
-e _boot
-memory
--gnu_asm
tgt\standalone_ram.ld
sample_threadx.c
tx_boot.a64
stdio_ghs.c
tx_zynqmp_low_level.c

View File

@@ -0,0 +1,35 @@
#include <stdint.h>
/*
* Zynq Ultrascale+ MPSoC / GHS
*
* Implements standard I/O through UART
*
* XXX assume the UART has already been initialized by bootloader
*/
#define UART_BASE 0xff000000U /* UART0 */
#define UART_FIFO *((volatile uint32_t *)(UART_BASE+0x0030U))
#define UART_SR *((volatile uint32_t *)(UART_BASE+0x002CU))
#define UART_SR_TXFULL 0x00000010U
long write(int fno, const void *buf, long size)
{
if (fno != 1) return -1;
const char *p = buf;
const char *pmax = p + size;
while (p < pmax) {
char c = *p++;
if (c == '\n') {
/* expand LF to CR+LF */
while ((UART_SR & UART_SR_TXFULL) != 0);
UART_FIFO = '\r';
}
while ((UART_SR & UART_SR_TXFULL) != 0);
UART_FIFO = c;
}
return size;
}

View File

@@ -0,0 +1,276 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** bootstrap for Zynq UltraScale+ MPSoC / Cortex-A53-SMP */
/** */
/**************************************************************************/
/**************************************************************************/
/* generic timer clock frequency */
#define GENERIC_TIMER_FREQ 99990000
/* Zynq registers */
#define RVBAR_BASE 0xFD5C0040
#define RST_FPD_APU 0xFD1A0104
/* global symbols */
.global _boot
.global _vector_table
.global _start
.global __tx_irq_handler
.global _tx_platform_smp_initialize_low_level
.global _tx_thread_smp_initialize_wait
.global __el3_stack
.global __el3_1_stack
.global __el3_2_stack
.global __el3_3_stack
/* exception vector table */
.section .vectors, "ax"
.align 0x800 // 0x000
_vector_table:
b _boot
.align 0x80 // 0x080
b .
.align 0x80 // 0x100
b .
.align 0x80 // 0x180
b .
.align 0x80 // 0x200
b .
.align 0x80 // 0x280
b __tx_irq_handler
.align 0x80 // 0x300
b .
.align 0x80 // 0x380
b .
.align 0x80 // 0x400
b .
.align 0x80 // 0x480
b .
.align 0x80 // 0x500
b .
.align 0x80 // 0x580
b .
.align 0x80 // 0x600
b .
.align 0x80 // 0x680
b .
.align 0x80 // 0x700
b .
.align 0x80 // 0x780
b .
.align 0x80 // 0x800
.section .boot, "ax"
_boot:
// check that it is core 0 running
mrs x0, MPIDR_EL1
ands x0, x0, #0xFF
b.eq core0
not_core0:
wfi
b not_core0
core0:
// set cores 1-3 in reset state
ldr x0, =RST_FPD_APU
ldr w1, [x0]
orr w1, w1, #(7 << 1) // Hold cores 1-3 in reset
str w1, [x0]
and w1, w1, #~(7 << 11) // Remove the power-on reset on cores 1-3
str w1, [x0]
// set reset vector for cores 0-3
ldr x0, =RVBAR_BASE
ldr x1, =_boot
str x1, [x0]
ldr x1, =_boot_smp
str x1, [x0, #8]
str x1, [x0, #16]
str x1, [x0, #24]
/* common boot code */
_boot_smp:
// reset all registers
mov x3, #0
mov x4, #0
mov x5, #0
mov x6, #0
mov x7, #0
mov x8, #0
mov x9, #0
mov x10, #0
mov x11, #0
mov x12, #0
mov x13, #0
mov x14, #0
mov x15, #0
mov x16, #0
mov x17, #0
mov x18, #0
mov x19, #0
mov x20, #0
mov x21, #0
mov x22, #0
mov x23, #0
mov x24, #0
mov x25, #0
mov x26, #0
mov x27, #0
mov x28, #0
mov x29, #0
mov x30, #0
// go to error if current exception level not EL3
mrs x0, CurrentEL
cmp x0, #0xC
b.ne error
// set vector table base address
ldr x0, =_vector_table
msr VBAR_EL3, x0
// get core id in x0
mrs x0, MPIDR_EL1
and x0, x0, #0xFF
// set stack pointer for current core
ldr x2, =EL3_stacks
lsl x1, x0, #3 // coreid * 8
ldr x2, [x2, x1]
mov sp, x2
// disable trapping of SIMD/FPU registers
mov x1, #0
msr CPTR_EL3, x1
// set SCR_EL3
ldr x1, =0xC0E
msr SCR_EL3, x1
// set CPUACTLR_EL1
ldr x1, =0x1000080CA000
msr S3_1_C15_C2_0, x1
// set the generic timer frequency
ldr x1, =GENERIC_TIMER_FREQ
msr CNTFRQ_EL0, x1
// enable hardware coherency between cores
mrs x1, S3_1_C15_C2_1
orr x1, x1, #(1 << 6)
msr S3_1_C15_C2_1, x1
isb
// invalidate caches
tlbi ALLE3
ic IALLU
bl invalidate_dcaches
dsb sy
isb
// jump to main only from core 0
mrs x0, MPIDR_EL1
ands x0, x0, #0xFF
b.ne cores_1_3_init
mov x2, 0 // Clear envp reg
mov x1, 0 // Clear argv reg
b _start // go to C land
cores_1_3_init:
// low level initialization for cores 1-3
bl _tx_platform_smp_initialize_low_level
// continue to threadx smp initialization
b _tx_thread_smp_initialize_wait
error:
b error
.align 8
EL3_stacks:
.quad __el3_stack
.quad __el3_1_stack
.quad __el3_2_stack
.quad __el3_3_stack
invalidate_dcaches:
mrs x0, CLIDR_EL1
and w3, w0, #0x07000000 // Get 2 x Level of Coherence
lsr w3, w3, #23
cbz w3, Finished
mov w10, #0 // w10 = 2 x cache level
mov w8, #1 // w8 = constant 0b1
Loop1:
add w2, w10, w10, lsr #1 // Calculate 3 x cache level
lsr w1, w0, w2 // extract 3-bit cache type for this level
and w1, w1, #0x7
cmp W1, #2
b.lt Skip // No data or unified cache at this level
msr CSSELR_EL1, x10 // Select this cache level
isb // Synchronize change of CSSELR
mrs x1, CCSIDR_EL1 // Read CCSIDR
and w2, w1, #7 // w2 = log2(linelen)-4
add w2, w2, #4 // w2 = log2(linelen)
ubfx w4, w1, #3, #10 // w4 = max way number, right aligned
clz w5, w4 // w5 = 32-log2(ways), bit position of way in DC operand
lsl w9, w4, w5 // w9 = max way number, aligned to position in DC operand
lsl w16, w8, w5 // w16 = amount to decrement way number per iteration
Loop2:
ubfx w7, w1, #13, #15 // w7 = max set number, right aligned
lsl w7, w7, w2 // w7 = max set number, aligned to position in DC operand
lsl w17, w8, w2 // w17 = amount to decrement set number per iteration
Loop3:
orr w11, w10, w9 // w11 = combine way number and cache number...
orr w11, w11, w7 // ... and set number for DC operand
dc csw, x11 // Do data cache clean by set and way
subs w7, w7, w17 // Decrement set number
b.ge Loop3
subs x9, x9, x16 // Decrement way number
b.ge Loop2
Skip:
add w10, w10, #2 // Increment 2 x cache level
cmp w3, w10
dsb sy // Ensure completion of previous cache maintenance operation
b.gt Loop1
Finished:
ret
.end

View File

@@ -0,0 +1,109 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Zynq UltraScale+ MPSoC / Cortex-A53-SMP - Low-level functions */
/** */
/**************************************************************************/
/**************************************************************************/
#ifndef TX_ZYNQMP_H
#define TX_ZYNQMP_H
#include <stdint.h>
#include <stdlib.h>
#ifdef __cplusplus
/* Yes, C++ compiler is present. Use standard C. */
extern "C" {
#endif
/* Define Interrupt Handling Interface functions. */
void tx_zynqmp_irq_enable(unsigned id, void (*handler)(void *), void *data);
void tx_zynqmp_irq_disable(unsigned id);
void tx_zynqmp_irq_priority(unsigned id, unsigned prio);
void tx_zynqmp_irq_config(unsigned id, int edge);
/* ThreadX SMP Extensions */
void tx_zynqmp_irq_smp_core(unsigned irq_id, unsigned core_id);
/* Wait for small pauses */
void tx_zynqmp_udelay(unsigned usecs);
#if 1 /* need compiler option -gnu_asm */
/* Define the size of a cache line */
#define TX_ZYNQMP_DCACHE_LINE_SIZE 64
/* Flush (Clean & Invalidate) memory region */
static inline void tx_zynqmp_dcache_flush(uintptr_t ptr, uintptr_t ptr_max)
{
while (ptr < ptr_max)
{
/* Clean & Invalidate data cache by VA to PoC */
asm volatile ( "DC CIVAC, %0" : : "r" (ptr));
ptr += TX_ZYNQMP_DCACHE_LINE_SIZE;
}
/* wait for completion */
asm volatile ( "DSB SY");
}
/* Invalidate memory region */
static inline void tx_zynqmp_dcache_invalidate(uintptr_t ptr, uintptr_t ptr_max)
{
while (ptr < ptr_max)
{
/* Invalidate data cache by VA to PoC */
asm volatile ( "DC IVAC, %0" : : "r" (ptr));
ptr += TX_ZYNQMP_DCACHE_LINE_SIZE;
}
/* wait for completion */
asm volatile ( "DSB SY");
}
/* Clean memory region (without Invalidate) */
static inline void tx_zynqmp_dcache_clean(uintptr_t ptr, uintptr_t ptr_max)
{
while (ptr < ptr_max)
{
/* Clean data cache by VA to PoC */
asm volatile ( "DC CVAC, %0" : : "r" (ptr));
ptr += TX_ZYNQMP_DCACHE_LINE_SIZE;
}
/* wait for completion */
asm volatile ( "DSB SY");
}
#endif
#ifdef __cplusplus
/* Yes, C++ compiler is present. Use standard C. */
}
#endif
#endif /* TX_ZYNQMP_H */

View File

@@ -0,0 +1,805 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** Zynq UltraScale+ MPSoC / Cortex-A53-SMP - Low-level functions */
/** */
/**************************************************************************/
/**************************************************************************/
#include "tx_api.h"
#include "tx_zynqmp.h"
#include <stdint.h>
#include <stdio.h>
#include <arm64_ghs.h>
/* Disable the data cache. By default the data cache is enabled. */
/*
#define TX_DCACHE_OFF
*/
/* GIC base address (CBAR register) */
#define INIT_CBAR uint64_t CBAR = __MRS(__GENERIC_SYS_REG(3,1,15,3,0));
/* GIC Distributor Registers */
#define GIC_BASEADDR (CBAR+0x10000ull)
#define GIC_REG(offset) *((volatile uint32_t *)(GIC_BASEADDR+offset))
#define GICD_CTLR GIC_REG(0x000)
#define GICD_ISENABLER(i) GIC_REG(0x100 + 4*(i))
#define GICD_ICENABLER(i) GIC_REG(0x180 + 4*(i))
#define GICD_ICPENDR(i) GIC_REG(0x280 + 4*(i))
#define GICD_ISACTIVER(i) GIC_REG(0x300 + 4*(i))
#define GICD_ICACTIVER(i) GIC_REG(0x380 + 4*(i))
#define GICD_IPRIORITY(i) GIC_REG(0x400 + 4*(i))
#define GICD_IPRIORITYB(i) *((volatile uint8_t *)(GIC_BASEADDR+0x400+(i)))
#define GICD_ITARGETSR(i) GIC_REG(0x800 + 4*(i))
#define GICD_ITARGETSRB(i) *((volatile uint8_t *)(GIC_BASEADDR+0x800+(i)))
#define GICD_ICFGR(i) GIC_REG(0xc00 + 4*(i))
/* GIC CPU Registers */
#define GIC_CPU_BASEADDR (CBAR+0x20000ull)
#define GIC_CPU_REG(offset) *((volatile uint32_t *)(GIC_CPU_BASEADDR+offset))
#define GICC_CTLR GIC_CPU_REG(0x000)
#define GICC_PMR GIC_CPU_REG(0x004)
#define GICC_IAR GIC_CPU_REG(0x00c)
#define GICC_EOIR GIC_CPU_REG(0x010)
/* CRF_APB Clock and Reset control registers */
#define RST_FPD_APU *((volatile uint32_t *) 0xfd1a0104ull)
/* Interrupt handler table */
#define IRQ_ID_MAX 192
uint64_t _tx_platform_irq_handlers[2*IRQ_ID_MAX];
/* default handler */
static void tx_irq_default_handler(uint64_t id)
{
INIT_CBAR
/* unexpected interrupt... disable it! */
GICD_ICENABLER(id>>5) = 1 << (id & 0x1f);
#if 0 /* debug */
while(1);
#endif
}
/* inter-processor software interrupt */
static void tx_core_interrupt(void *data)
{
/* nothing to do, just used to wakeup the core */
}
/* Generic Timer Registers */
static inline uint32_t CNTFRQ_READ(void)
{
return __MRS(__CNTFRQ_EL0);
}
static inline uint64_t CNTPCT_READ(void)
{
return __MRS(__CNTPCT_EL0);
}
static inline void CNTP_CTL_WRITE(uint32_t v)
{
__MSR(__CNTPS_CTL_EL1, v);
}
static inline uint64_t CNTP_CVAL_READ(void)
{
return __MRS(__CNTPS_CVAL_EL1);
}
static inline void CNTP_CVAL_WRITE(uint64_t v)
{
__MSR(__CNTPS_CVAL_EL1, v);
}
/* Generic Timer Interrupt */
#define GENERIC_TIMER_IRQ_ID 29
/* ThreadX timer interrupt */
extern void _tx_timer_interrupt(void);
static uint32_t tx_timer_delay;
static void tx_generic_timer_interrupt(void *data)
{
/* update next timer expiration */
CNTP_CVAL_WRITE(CNTP_CVAL_READ() + tx_timer_delay);
/* call ThreadX timer interrupt handler */
_tx_timer_interrupt();
}
#ifndef TX_DCACHE_OFF
/* MMU Tables */
#pragma ghs section bss=".mmu_tbl0"
static uint64_t mmu_tbl0[2];
#pragma ghs section bss=".mmu_tbl1"
static uint64_t mmu_tbl1[0x400];
#pragma ghs section bss=".mmu_tbl2"
static uint64_t mmu_tbl2[0x800];
#pragma ghs section bss=default
/* set MMU tables */
static void mmu_tbl_init(void)
{
int i;
uint64_t sect;
/*| | Memory Range | Definition in Translation Table |
*|-----------------------|-----------------------------|-----------------------------------|
*| DDR | 0x0000000000 - 0x007FFFFFFF | Normal write-back Cacheable |
*| PL | 0x0080000000 - 0x00BFFFFFFF | Strongly Ordered |
*| QSPI, lower PCIe | 0x00C0000000 - 0x00EFFFFFFF | Strongly Ordered |
*| Reserved | 0x00F0000000 - 0x00F7FFFFFF | Unassigned |
*| STM Coresight | 0x00F8000000 - 0x00F8FFFFFF | Strongly Ordered |
*| GIC | 0x00F9000000 - 0x00F91FFFFF | Strongly Ordered |
*| Reserved | 0x00F9200000 - 0x00FCFFFFFF | Unassigned |
*| FPS, LPS slaves | 0x00FD000000 - 0x00FFBFFFFF | Strongly Ordered |
*| CSU, PMU | 0x00FFC00000 - 0x00FFDFFFFF | Strongly Ordered |
*| TCM, OCM | 0x00FFE00000 - 0x00FFFFFFFF | Normal inner write-back cacheable |
*| Reserved | 0x0100000000 - 0x03FFFFFFFF | Unassigned |
*| PL, PCIe | 0x0400000000 - 0x07FFFFFFFF | Strongly Ordered |
*| DDR | 0x0800000000 - 0x0FFFFFFFFF | Normal inner write-back cacheable |
*| PL, PCIe | 0x1000000000 - 0xBFFFFFFFFF | Strongly Ordered |
*| Reserved | 0xC000000000 - 0xFFFFFFFFFF | Unassigned |*/
#define MMU_RESERVED 0
#define MMU_MEMORY 0x705
#define MMU_DEVICE (0x409 | (1ull << 53) | (1ull << 54))
/* 0x00_0000_0000 - 0x7F_FFFF_FFFF */
mmu_tbl0[0] = ((uint64_t) mmu_tbl1) + 0x3;
/* 0x80_0000_0000 - 0xFF_FFFF_FFFF */
mmu_tbl0[1] = ((uint64_t) mmu_tbl1) + 0x1000 + 0x3;
/* 0x00_0000_0000 - 0x00_FFFF_FFFF */
/* 2GB DDR, PL, other devices memory */
sect = (uint64_t) mmu_tbl2;
i = 0;
for (; i < 0x004; i++, sect += 0x1000) {
mmu_tbl1[i] = sect + 0x3;
}
/* 0x01_0000_0000 - 0x03_FFFF_FFFF */
/* 16GB Reserved */
sect = 0x100000000ull;
for (; i < 0x010; i++, sect += 0x40000000) {
mmu_tbl1[i] = sect + MMU_RESERVED;
}
/* 0x04_0000_0000 - 0x07_FFFF_FFFF */
/* 8GB PL, 8GB PCIe */
for (; i < 0x020; i++, sect += 0x40000000) {
mmu_tbl1[i] = sect + MMU_DEVICE;
}
/* 0x08_0000_0000 - 0x0F_7FFF_FFFF */
/* 2GB DDR */
#define DDR_1_SIZE 0x80000000u
#define DDR_1_REG (DDR_1_SIZE/0x40000000)
for (; i < (0x020 + DDR_1_REG); i++, sect += 0x40000000) {
mmu_tbl1[i] = sect + MMU_MEMORY;
}
#if DDR_1_REG < 0x20
/* reserved for region where DDR is absent */
for (; i < 0x040; i++, sect += 0x40000000) {
mmu_tbl1[i] = sect + MMU_RESERVED;
}
#endif
/* 0x10_0000_0000 - 0x7F_FFFF_FFFF */
/* 448GB PL */
for (; i < 0x200; i++, sect += 0x40000000) {
mmu_tbl1[i] = sect + MMU_DEVICE;
}
/* 0x80_0000_0000 - 0xBF_FFFF_FFFF */
/* 256GB PCIe */
for (; i < 0x300; i++, sect += 0x40000000) {
mmu_tbl1[i] = sect + MMU_DEVICE;
}
/* 0xC0_0000_0000 - 0xFF_FFFF_FFFF */
/* 256GB reserved */
for (; i < 0x400; i++, sect += 0x40000000) {
mmu_tbl1[i] = sect + MMU_RESERVED;
}
sect = 0;
i = 0;
/* 0x0000_0000 - 0x7FFF_FFFF */
/* 2GB DDR */
#define DDR_0_SIZE 0x80000000u
#define DDR_0_REG (DDR_0_SIZE/0x200000)
for (; i < DDR_0_REG; i++, sect += 0x200000) {
mmu_tbl2[i] = sect + MMU_MEMORY;
}
/* reserved for region where DDR is absent */
for (; i < 0x400; i++, sect += 0x200000) {
mmu_tbl2[i] = sect + MMU_RESERVED;
}
/* 0x8000_0000 - 0xBFFF_FFFF */
/* 1GB lower PL */
for (; i < 0x600; i++, sect += 0x200000) {
mmu_tbl2[i] = sect + MMU_DEVICE;
}
/* 0xC000_0000 - 0xDFFF_FFFF */
/* 512MB QSPI */
for (; i < 0x700; i++, sect += 0x200000) {
mmu_tbl2[i] = sect + MMU_DEVICE;
}
/* 0xE000_0000 - 0xEFFF_FFFF */
/* 256MB lower PCIe */
for (; i < 0x780; i++, sect += 0x200000) {
mmu_tbl2[i] = sect + MMU_DEVICE;
}
/* 0xF000_0000 - 0xF7FF_FFFF */
/* 128MB Reserved */
for (; i < 0x7c0; i++, sect += 0x200000) {
mmu_tbl2[i] = sect + MMU_RESERVED;
}
/* 0xF800_0000 - 0xFFDF_FFFF */
/* set all range as device */
for (; i < 0x7ff; i++, sect += 0x200000) {
mmu_tbl2[i] = sect + MMU_DEVICE;
}
/* 0xFFE0_0000 - 0xFFFF_FFFF*/
/* 2MB OCM/TCM */
for (; i < 0x800; i++, sect += 0x200000) {
mmu_tbl2[i] = sect + MMU_MEMORY;
}
}
#endif /* !TX_DCACHE_OFF */
/* enable MMU and caches */
static void tx_caches_enable(void)
{
#ifndef TX_DCACHE_OFF
/* set level 0 TTBR0_EL3 */
__DSB_OPT(__BARRIER_SY);
__MSR(__TTBR0_EL3, (uint64_t) mmu_tbl0);
/* set memory attributes */
__MSR(__MAIR_EL3, 0x000000BB0400FF44ull);
/* set TCR_EL3 */
__MSR(__TCR_EL3, 0x80823518ull);
/* set SCTLR_EL3: enable mmu and caches + SP alignment check */
__MSR(__SCTLR_EL3, __MRS(__SCTLR_EL3) | 0x100d);
__DSB_OPT(__BARRIER_SY);
__ISB();
#else
/* set SCTLR_EL3: enable instruction cache + SP alignment check */
__MSR(__SCTLR_EL3, __MRS(__SCTLR_EL3) | 0x1008);
#endif
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_platform_initialize_low_level */
/* Zynq UltraScale+ MPSoC Cortex-A53-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the Interrupt Controller and configures */
/* the Generic Timer for the ThreadX periodic timer interrupt source */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_low_level ThreadX low level initialization */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
void _tx_platform_initialize_low_level(void)
{
INIT_CBAR
int i;
#ifndef TX_DCACHE_OFF
/* initialize MMU tables */
mmu_tbl_init();
#endif
/* enable data and instruction caches */
tx_caches_enable();
/* set default interrupt handlers */
for (i=0; i<IRQ_ID_MAX; i++)
{
_tx_platform_irq_handlers[2*i] = (uint64_t) tx_irq_default_handler;
_tx_platform_irq_handlers[2*i+1] = (uint64_t) i;
}
/* initialize the interrupt controller: */
/* enable global distributor */
GICD_CTLR |= 1;
/* disable all interrupts */
for (i=0; i<(IRQ_ID_MAX + 31)/32; i++)
{
GICD_ICENABLER(i) = ~0;
GICD_ICPENDR(i) = ~0;
GICD_ICACTIVER(i) = ~0;
}
/* redirect all interrupts to cpu #0 */
for (i=8; i<(IRQ_ID_MAX + 3)/4; i++)
{
GICD_ITARGETSR(i) = 0x01010101;
}
/* set default priority to 0 */
for (i=0; i<(IRQ_ID_MAX + 3)/4; i++)
{
GICD_IPRIORITY(i) = 0x00000000;
}
/* set default configuration as level-sensitive */
for (i=2; i<(IRQ_ID_MAX + 15)/16; i++)
{
GICD_ICFGR(i) &= 0x55555555;
}
/* initialize the interrupt controller: */
/* enable physical cpu interface */
GICC_CTLR |= 1;
/* enable all priorities */
GICC_PMR = 0xff;
/* Use the Generic Timer for generating clock ticks: */
/* compute tick delay from counter frequency */
tx_timer_delay = CNTFRQ_READ() / TX_TIMER_TICKS_PER_SECOND;
/* set timer expiration from current counter value */
CNTP_CVAL_WRITE(CNTPCT_READ() + tx_timer_delay);
/* configure CNTP_CTL to enable timer interrupts */
CNTP_CTL_WRITE(1);
/* install timer interrupt handler */
tx_zynqmp_irq_enable(GENERIC_TIMER_IRQ_ID, tx_generic_timer_interrupt, NULL);
/* set handler for software interrupt 0 */
tx_zynqmp_irq_enable(0, tx_core_interrupt, NULL);
/* release reset for cores 1-(MAX_CORES-1) */
RST_FPD_APU &= ~((1 << TX_THREAD_SMP_MAX_CORES) - 2);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_platform_smp_initialize_low_level */
/* Zynq UltraScale+ MPSoC Cortex-A53-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the cores 1-3 for SMP processing */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _boot_smp cores 1-3 startup code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
void _tx_platform_smp_initialize_low_level(void)
{
INIT_CBAR
/* enable data and instruction caches */
tx_caches_enable();
/* initialize the interrupt controller: */
/* enable physical cpu interface */
GICC_CTLR |= 1;
/* enable all priorities */
GICC_PMR = 0xff;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* tx_zynqmp_irq_enable Zynq UltraScale+ MPSoC Cortex-A53-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function attachs a handler to an interrupt and enables */
/* the interrupt. */
/* */
/* INPUT */
/* */
/* id The ID of the interrupt */
/* handler The interrupt handler */
/* data The data to pass to the */
/* handler. */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
void tx_zynqmp_irq_enable(unsigned id, void (*handler)(void *), void *data)
{
INIT_CBAR
if (id >= IRQ_ID_MAX)
{
return;
}
/* set handler */
_tx_platform_irq_handlers[2*id] = (uint64_t) handler;
_tx_platform_irq_handlers[2*id+1] = (uint64_t) data;
__DSB_OPT(__BARRIER_SY); // ensure we're in sync...
/* enable interrupt */
GICD_ISENABLER(id>>5) = 1 << (id & 0x1f);
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* tx_zynqmp_irq_disable Zynq UltraScale+ MPSoC Cortex-A53-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function disables an interrupt and removes the previously */
/* attached handler */
/* */
/* INPUT */
/* */
/* id The ID of the interrupt */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
void tx_zynqmp_irq_disable(unsigned id)
{
INIT_CBAR
if (id >= IRQ_ID_MAX)
{
return;
}
/* disable interrupt */
GICD_ICENABLER(id>>5) = 1 << (id & 0x1f);
/* clear pending state */
GICD_ICPENDR(id>>5) = 1 << (id & 0x1f);
/* ensure the interrupt is not still active before returning */
while (GICD_ISACTIVER(id>>5) & (1 << (id & 0x1f)))
{
}
/* restore default handler */
_tx_platform_irq_handlers[2*id] = (uint64_t) tx_irq_default_handler;
_tx_platform_irq_handlers[2*id+1] = (uint64_t) id;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* tx_zynqmp_irq_priority Zynq UltraScale+ MPSoC Cortex-A53-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function sets the priority of an interrupt */
/* */
/* INPUT */
/* */
/* id The ID of the interrupt */
/* prio The interrupt priority 0-255 */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
void tx_zynqmp_irq_priority(unsigned id, unsigned prio)
{
INIT_CBAR
if (id >= IRQ_ID_MAX)
{
return;
}
/* set priority */
GICD_IPRIORITYB(id) = (uint8_t) prio;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* tx_zynqmp_irq_config Zynq UltraScale+ MPSoC Cortex-A53/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function configures an interrupt as level-sensitive or */
/* edge-triggered */
/* Only SPI interrupts (ID >= 32) can be configured */
/* */
/* INPUT */
/* */
/* id The ID of the interrupt */
/* edge Configure the interrupt as */
/* level-sensitive (0) or */
/* edge-triggered (non 0) */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
void tx_zynqmp_irq_config(unsigned id, int edge)
{
INIT_CBAR
TX_INTERRUPT_SAVE_AREA
uint32_t value;
if (id < 32 || id >= IRQ_ID_MAX)
{
return;
}
TX_DISABLE
/* set edge or level sensitive */
value = GICD_ICFGR(id>>4);
if (edge)
{
value |= 2 << (2*(id & 0xf));
}
else
{
value &= ~(2 << (2*(id & 0xf)));
}
GICD_ICFGR(id>>4) = value;
TX_RESTORE
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* tx_zynqmp_irq_smp_core Zynq UltraScale+ MPSoC Cortex-A53/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function selects on which core an interrupt will be handled */
/* Only SPI interrupts (ID >= 32) can be configured */
/* */
/* INPUT */
/* */
/* irq_id The ID of the interrupt */
/* core_id The ID of the core 0-3 */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
void tx_zynqmp_irq_smp_core(unsigned irq_id, unsigned core_id)
{
INIT_CBAR
if (irq_id < 32 || irq_id >= IRQ_ID_MAX || core_id >= TX_THREAD_SMP_MAX_CORES)
{
return;
}
/* set interrupt processor target */
GICD_ITARGETSRB(irq_id) = 1 << core_id;
}
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* tx_zynqmp_udelay Zynq UltraScale+ MPSoC Cortex-A53/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function waits for a given small delay expressed in */
/* microseconds. */
/* */
/* INPUT */
/* */
/* usecs The number of microseconds */
/* to wait for */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
void tx_zynqmp_udelay(unsigned usecs)
{
uint64_t t;
/* get current time */
t = CNTPCT_READ();
/* compute expiration time */
t += ((uint64_t) usecs * CNTFRQ_READ()) / 1000000U;
while ((int64_t) (t - CNTPCT_READ()) > 0) {}
}

View File

@@ -0,0 +1,8 @@
#!gbuild
macro __BINDIR=%expand_path(bin/debug)
[Build Configuration]
-G
-Odebug
-object_dir=objs/debug
:outputDir=objs/debug
:binDir=${__BINDIR}

View File

@@ -0,0 +1,16 @@
target_connection.0.type="Simulator for ARM64 (simarm64)"
target_connection.0.short_type="simarm64"
target_connection.0.args=" "
target_connection.0.title="Generic-ARM64 ARM Cortex-A53 with Simulator for ARM64 (simarm64)"
target_connection.0.command="simarm64 "
target_connection.0.logfile="simarm64"
target_connection.0.log=""
target_connection.0.sane="no"
target_connection.1.type="Green Hills Debug Probe (mpserv)"
target_connection.1.short_type="mpserv"
target_connection.1.args=" "
target_connection.1.title="Generic-ARM64 ARM Cortex-A53 with Green Hills Debug Probe (mpserv)"
target_connection.1.command="mpserv "
target_connection.1.logfile="mpserv"
target_connection.1.log=""
target_connection.1.sane="no"

View File

@@ -0,0 +1,9 @@
#!gbuild
macro __BINDIR=%expand_path(bin/release)
[Build Configuration]
-G
-O
-object_dir=objs/release
:outputDir=objs/release
:binDir=${__BINDIR}

View File

@@ -0,0 +1,61 @@
Project File (resource.gpj)
------------------------------------------------------------------------------
The files provided in this project are resources to help get your project
running on your target. You may use these files as is or use them as examples
to create your own.
Unless the files here are included in the project file for your executable,
they will not impact your build.
Board Setup Files (.mbs)
------------------------------------------------------------------------------
The board setup files (.mbs) are used by MULTI to initialize target hardware
before beginning a debugging session.
The automatically-created default.con connection file (located in
default.gpj) contains connection methods that reference the .mbs files
included in resource.gpj.
You can modify the scripts in the board setup files to suit your specific
hardware configuration and connection needs.
For more information about board setup files and connection files, see the
"MULTI: Configuring Connections" book for your target processor.
Linker Directive Files (.ld)
------------------------------------------------------------------------------
Linker directive files (.ld) are used when your program is linked to define
program sections and assign them to specific addresses in memory.
The linker directive file from the project file for your executable will
be used when linking.
If the .ld file included in the project for your executable does not suit
your hardware configuration or program layout needs, it can be modified or
replaced with a custom .ld file.
This resource.gpj contains example linker directives files:
** standalone_ram.ld -- For programs that are linked into and run
out of RAM.
** standalone_romcopy.ld -- For programs that are linked into ROM, but
run out of RAM.
** standalone_romrun.ld -- For programs that are linked into and run
out of ROM.
Some configurations also contain other linker directives files:
** standalone_romdebug.ld -- For programs that are linked into and run
out of ROM with enhanced debugging capabilities.
** standalone_pic.ld -- For programs built with position independent
code.
** standalone_pid.ld -- For programs built with position independent
data.
** standalone_picpid.ld -- For programs built with position independent
code and data.
For more information about linker directives files, see the "MULTI: Building
Applications" book for your processor.

View File

@@ -0,0 +1,10 @@
#!gbuild
#component target_resources
[Project]
default.con
resource_readme.txt
debug.gpc
release.gpc
standalone_ram.ld
standalone_romcopy.ld
standalone_romrun.ld

View File

@@ -0,0 +1,70 @@
//
// memory map for the Xilinx ZCU102 with 2GB or SDRAM
//
MEMORY {
dram_rsvd1 : ORIGIN = 0x0000000000, LENGTH = 0
dram_memory : ORIGIN = ., LENGTH = 2048M
dram_rsvd2 : ORIGIN = ., LENGTH = 0
}
DEFAULTS {
heap_reserve = 8M
stack_reserve = 16K
stack_1_3_reserve = 16K
}
//
// Program layout for running out of RAM.
//
//
SECTIONS
{
//
// The text segment
//
.vectors : > dram_memory
.boot : > .
.text : > .
.syscall : > .
.fixaddr : > .
.fixtype : > .
.rodata : > .
.secinfo : > .
//
// The data segment
//
.data : > .
.bss : > .
.ghcovfz CLEAR : > .
.ghcovcz CLEAR : > .
.ghcovdz CLEAR : > .
.mmu_tbl0 ALIGN(4096) : > .
.mmu_tbl1 ALIGN(4096) : > .
.mmu_tbl2 ALIGN(4096) : > .
.stack ALIGN(16) PAD(stack_reserve) : > .
__el3_stack = .;
.stack_1 ALIGN(16) PAD(stack_1_3_reserve) : > .
__el3_1_stack = .;
.stack_2 ALIGN(16) PAD(stack_1_3_reserve) : > .
__el3_2_stack = .;
.stack_3 ALIGN(16) PAD(stack_1_3_reserve) : > .
__el3_3_stack = .;
.heap ALIGN(16) PAD(heap_reserve) : > .
__ghsbegin_free_mem = .;
//
// These special symbols mark the bounds of RAM and ROM memory.
// They are used by the MULTI debugger.
//
// __ghs_romstart = MEMADDR(flash_rsvd1);
// __ghs_romend = MEMENDADDR(flash_rsvd2);
__ghs_ramstart = MEMADDR(dram_rsvd1);
__ghs_ramend = MEMENDADDR(dram_rsvd2);
}

View File

@@ -0,0 +1,90 @@
MEMORY {
flash_rsvd1 : ORIGIN = 0x10000000, LENGTH = 0
flash_memory : ORIGIN = ., LENGTH = 128M
flash_rsvd2 : ORIGIN = ., LENGTH = 0
dram_rsvd1 : ORIGIN = 0x20000000, LENGTH = 0
dram_memory : ORIGIN = ., LENGTH = 256M
dram_rsvd2 : ORIGIN = ., LENGTH = 0
}
DEFAULTS {
heap_reserve = 8M
stack_reserve = 1M
}
//
// Program layout for starting in ROM, copying test and data to RAM,
// and then running out of RAM.
//
SECTIONS
{
//
// ROM SECTIONS
//
// The order and relative offsets of these
// ROM startup code sections must be the
// same in both the ROM and RAM copies.
.ROM.boottext ROM(.boottext ) : > flash_memory
.ROM.syscall ROM(.syscall) : > .
.rodata : > flash_memory
.secinfo : > .
.fixaddr : > .
.fixtype : > .
.CROM.data CROM(.data) : > .
.CROM.text CROM(.text) : > .
//
// RAM SECTIONS
//
.boottext : {
// All .text which is reachable between
// _start and __ghs_ind_crt1 needs to be
// pulled into .boottext and left uncompressed.
crt0.o(.text)
libboardinit.a(*)(.text) // optional library
libstartup.a(*)(.text)
libsys.a(ind_crt1.o)(.text)
} > dram_memory
.syscall : > .
.text : > .
.data : > .
.bss : > .
.ghcovfz CLEAR : > .
.ghcovcz CLEAR : > .
.ghcovdz CLEAR : > .
.heap ALIGN(16) PAD(heap_reserve) : > .
.stack ALIGN(16) PAD(stack_reserve) : > .
//
// These special symbols mark the bounds of RAM and ROM images of boot code.
// They are used by the GHS startup code (_start and __ghs_ind_crt0).
//
__ghs_rombootcodestart = ADDR(.ROM.boottext);
__ghs_rombootcodeend = ENDADDR(.fixtype);
__ghs_rambootcodestart = ADDR(.boottext);
__ghs_rambootcodeend = ENDADDR(.stack);
//
// These special symbols mark the bounds of RAM and ROM memory.
// They are used by the MULTI debugger.
//
__ghs_romstart = MEMADDR(flash_rsvd1);
__ghs_romend = MEMENDADDR(flash_rsvd2);
__ghs_ramstart = MEMADDR(dram_rsvd1);
__ghs_ramend = MEMENDADDR(dram_rsvd2);
//
// This special symbol marks the the first address executed after the
// ROM to RAM copy is complete. It is used by the MULTI debugger.
//
__ghs_after_romcopy = __ghs_ind_crt1;
}

View File

@@ -0,0 +1,69 @@
MEMORY {
flash_rsvd1 : ORIGIN = 0x10000000, LENGTH = 0
flash_memory : ORIGIN = ., LENGTH = 128M
flash_rsvd2 : ORIGIN = ., LENGTH = 0
dram_rsvd1 : ORIGIN = 0x20000000, LENGTH = 0
dram_memory : ORIGIN = ., LENGTH = 256M
dram_rsvd2 : ORIGIN = ., LENGTH = 0
}
DEFAULTS {
heap_reserve = 8M
stack_reserve = 1M
}
//
// Program layout for starting in ROM, copying data to RAM,
// and continuing to execute out of ROM.
//
SECTIONS
{
//
// ROM SECTIONS
//
.text : > flash_memory
.syscall : > .
.rodata : > .
.secinfo : > .
.fixaddr : > .
.fixtype : > .
.CROM.data CROM(.data) : > .
//
// RAM SECTIONS
//
.data : > dram_memory
.bss : > .
.ghcovfz CLEAR : > .
.ghcovcz CLEAR : > .
.ghcovdz CLEAR : > .
.heap ALIGN(16) PAD(heap_reserve) : > .
.stack ALIGN(16) PAD(stack_reserve) : > .
//
// These special symbols mark the bounds of RAM and ROM memory.
// They are used by the MULTI debugger.
//
__ghs_romstart = MEMADDR(flash_rsvd1);
__ghs_romend = MEMENDADDR(flash_rsvd2);
__ghs_ramstart = MEMADDR(dram_rsvd1);
__ghs_ramend = MEMENDADDR(dram_rsvd2);
//
// These special symbols mark the bounds of RAM and ROM images of boot code.
// They are used by the GHS startup code (_start and __ghs_ind_crt0).
//
__ghs_rombootcodestart = ADDR(.text);
__ghs_rombootcodeend = ENDADDR(.fixtype);
__ghs_rambootcodestart = 0;
__ghs_rambootcodeend = 0;
}

View File

@@ -0,0 +1,235 @@
#!gbuild
[Library]
-object_dir=objs\libtx
-I../../../../../common_smp/inc
-I../../inc
..\..\..\..\..\common_smp\inc\tx_api.h
..\..\..\..\..\common_smp\inc\tx_block_pool.h
..\..\..\..\..\common_smp\inc\tx_byte_pool.h
..\..\..\..\..\common_smp\inc\tx_event_flags.h
..\..\..\..\..\common_smp\inc\tx_initialize.h
..\..\..\..\..\common_smp\inc\tx_mutex.h
..\..\..\..\..\common_smp\inc\tx_queue.h
..\..\..\..\..\common_smp\inc\tx_semaphore.h
..\..\..\..\..\common_smp\inc\tx_thread.h
..\..\..\..\..\common_smp\inc\tx_timer.h
..\..\..\..\..\common_smp\inc\tx_trace.h
..\..\..\..\..\common_smp\inc\tx_user.h
..\..\inc\tx_el.h
..\..\inc\tx_ghs.h
..\..\inc\tx_port.h
..\..\src\tx_ghs.c
..\..\src\tx_initialize_low_level.a64
..\..\src\tx_thread_context_restore.a64
..\..\src\tx_thread_context_save.a64
..\..\src\tx_thread_fp_disable.c
..\..\src\tx_thread_fp_enable.c
..\..\src\tx_thread_interrupt_control.a64
..\..\src\tx_thread_interrupt_disable.a64
..\..\src\tx_thread_interrupt_restore.a64
..\..\src\tx_thread_schedule.a64
..\..\src\tx_thread_smp_core_get.a64
..\..\src\tx_thread_smp_core_preempt.a64
..\..\src\tx_thread_smp_current_state_get.a64
..\..\src\tx_thread_smp_current_thread_get.a64
..\..\src\tx_thread_smp_initialize_wait.a64
..\..\src\tx_thread_smp_low_level_initialize.a64
..\..\src\tx_thread_smp_protect.a64
..\..\src\tx_thread_smp_time_get.a64
..\..\src\tx_thread_smp_unprotect.a64
..\..\src\tx_thread_stack_build.a64
..\..\src\tx_thread_system_return.a64
..\..\src\tx_thread_timeout.c
..\..\src\tx_timer_interrupt.a64
..\..\..\..\..\common_smp\src\tx_block_allocate.c
..\..\..\..\..\common_smp\src\tx_block_pool_cleanup.c
..\..\..\..\..\common_smp\src\tx_block_pool_create.c
..\..\..\..\..\common_smp\src\tx_block_pool_delete.c
..\..\..\..\..\common_smp\src\tx_block_pool_info_get.c
..\..\..\..\..\common_smp\src\tx_block_pool_initialize.c
..\..\..\..\..\common_smp\src\tx_block_pool_performance_info_get.c
..\..\..\..\..\common_smp\src\tx_block_pool_performance_system_info_get.c
..\..\..\..\..\common_smp\src\tx_block_pool_prioritize.c
..\..\..\..\..\common_smp\src\tx_block_release.c
..\..\..\..\..\common_smp\src\tx_byte_allocate.c
..\..\..\..\..\common_smp\src\tx_byte_pool_cleanup.c
..\..\..\..\..\common_smp\src\tx_byte_pool_create.c
..\..\..\..\..\common_smp\src\tx_byte_pool_delete.c
..\..\..\..\..\common_smp\src\tx_byte_pool_info_get.c
..\..\..\..\..\common_smp\src\tx_byte_pool_initialize.c
..\..\..\..\..\common_smp\src\tx_byte_pool_performance_info_get.c
..\..\..\..\..\common_smp\src\tx_byte_pool_performance_system_info_get.c
..\..\..\..\..\common_smp\src\tx_byte_pool_prioritize.c
..\..\..\..\..\common_smp\src\tx_byte_pool_search.c
..\..\..\..\..\common_smp\src\tx_byte_release.c
..\..\..\..\..\common_smp\src\tx_event_flags_cleanup.c
..\..\..\..\..\common_smp\src\tx_event_flags_create.c
..\..\..\..\..\common_smp\src\tx_event_flags_delete.c
..\..\..\..\..\common_smp\src\tx_event_flags_get.c
..\..\..\..\..\common_smp\src\tx_event_flags_info_get.c
..\..\..\..\..\common_smp\src\tx_event_flags_initialize.c
..\..\..\..\..\common_smp\src\tx_event_flags_performance_info_get.c
..\..\..\..\..\common_smp\src\tx_event_flags_performance_system_info_get.c
..\..\..\..\..\common_smp\src\tx_event_flags_set.c
..\..\..\..\..\common_smp\src\tx_event_flags_set_notify.c
..\..\..\..\..\common_smp\src\tx_initialize_high_level.c
..\..\..\..\..\common_smp\src\tx_initialize_kernel_enter.c
..\..\..\..\..\common_smp\src\tx_initialize_kernel_setup.c
..\..\..\..\..\common_smp\src\tx_mutex_cleanup.c
..\..\..\..\..\common_smp\src\tx_mutex_create.c
..\..\..\..\..\common_smp\src\tx_mutex_delete.c
..\..\..\..\..\common_smp\src\tx_mutex_get.c
..\..\..\..\..\common_smp\src\tx_mutex_info_get.c
..\..\..\..\..\common_smp\src\tx_mutex_initialize.c
..\..\..\..\..\common_smp\src\tx_mutex_performance_info_get.c
..\..\..\..\..\common_smp\src\tx_mutex_performance_system_info_get.c
..\..\..\..\..\common_smp\src\tx_mutex_prioritize.c
..\..\..\..\..\common_smp\src\tx_mutex_priority_change.c
..\..\..\..\..\common_smp\src\tx_mutex_put.c
..\..\..\..\..\common_smp\src\tx_queue_cleanup.c
..\..\..\..\..\common_smp\src\tx_queue_create.c
..\..\..\..\..\common_smp\src\tx_queue_delete.c
..\..\..\..\..\common_smp\src\tx_queue_flush.c
..\..\..\..\..\common_smp\src\tx_queue_front_send.c
..\..\..\..\..\common_smp\src\tx_queue_info_get.c
..\..\..\..\..\common_smp\src\tx_queue_initialize.c
..\..\..\..\..\common_smp\src\tx_queue_performance_info_get.c
..\..\..\..\..\common_smp\src\tx_queue_performance_system_info_get.c
..\..\..\..\..\common_smp\src\tx_queue_prioritize.c
..\..\..\..\..\common_smp\src\tx_queue_receive.c
..\..\..\..\..\common_smp\src\tx_queue_send.c
..\..\..\..\..\common_smp\src\tx_queue_send_notify.c
..\..\..\..\..\common_smp\src\tx_semaphore_ceiling_put.c
..\..\..\..\..\common_smp\src\tx_semaphore_cleanup.c
..\..\..\..\..\common_smp\src\tx_semaphore_create.c
..\..\..\..\..\common_smp\src\tx_semaphore_delete.c
..\..\..\..\..\common_smp\src\tx_semaphore_get.c
..\..\..\..\..\common_smp\src\tx_semaphore_info_get.c
..\..\..\..\..\common_smp\src\tx_semaphore_initialize.c
..\..\..\..\..\common_smp\src\tx_semaphore_performance_info_get.c
..\..\..\..\..\common_smp\src\tx_semaphore_performance_system_info_get.c
..\..\..\..\..\common_smp\src\tx_semaphore_prioritize.c
..\..\..\..\..\common_smp\src\tx_semaphore_put.c
..\..\..\..\..\common_smp\src\tx_semaphore_put_notify.c
..\..\..\..\..\common_smp\src\tx_thread_create.c
..\..\..\..\..\common_smp\src\tx_thread_delete.c
..\..\..\..\..\common_smp\src\tx_thread_entry_exit_notify.c
..\..\..\..\..\common_smp\src\tx_thread_identify.c
..\..\..\..\..\common_smp\src\tx_thread_info_get.c
..\..\..\..\..\common_smp\src\tx_thread_initialize.c
..\..\..\..\..\common_smp\src\tx_thread_performance_info_get.c
..\..\..\..\..\common_smp\src\tx_thread_performance_system_info_get.c
..\..\..\..\..\common_smp\src\tx_thread_preemption_change.c
..\..\..\..\..\common_smp\src\tx_thread_priority_change.c
..\..\..\..\..\common_smp\src\tx_thread_relinquish.c
..\..\..\..\..\common_smp\src\tx_thread_reset.c
..\..\..\..\..\common_smp\src\tx_thread_resume.c
..\..\..\..\..\common_smp\src\tx_thread_shell_entry.c
..\..\..\..\..\common_smp\src\tx_thread_sleep.c
..\..\..\..\..\common_smp\src\tx_thread_smp_core_exclude.c
..\..\..\..\..\common_smp\src\tx_thread_smp_core_exclude_get.c
..\..\..\..\..\common_smp\src\tx_thread_smp_current_state_set.c
..\..\..\..\..\common_smp\src\tx_thread_smp_debug_entry_insert.c
..\..\..\..\..\common_smp\src\tx_thread_smp_high_level_initialize.c
..\..\..\..\..\common_smp\src\tx_thread_smp_rebalance_execute_list.c
..\..\..\..\..\common_smp\src\tx_thread_smp_utilities.c
..\..\..\..\..\common_smp\src\tx_thread_stack_analyze.c
..\..\..\..\..\common_smp\src\tx_thread_stack_error_handler.c
..\..\..\..\..\common_smp\src\tx_thread_stack_error_notify.c
..\..\..\..\..\common_smp\src\tx_thread_suspend.c
..\..\..\..\..\common_smp\src\tx_thread_system_preempt_check.c
..\..\..\..\..\common_smp\src\tx_thread_system_resume.c
..\..\..\..\..\common_smp\src\tx_thread_system_suspend.c
..\..\..\..\..\common_smp\src\tx_thread_terminate.c
..\..\..\..\..\common_smp\src\tx_thread_time_slice.c
..\..\..\..\..\common_smp\src\tx_thread_time_slice_change.c
..\..\..\..\..\common_smp\src\tx_thread_wait_abort.c
..\..\..\..\..\common_smp\src\tx_time_get.c
..\..\..\..\..\common_smp\src\tx_time_set.c
..\..\..\..\..\common_smp\src\tx_timer_activate.c
..\..\..\..\..\common_smp\src\tx_timer_change.c
..\..\..\..\..\common_smp\src\tx_timer_create.c
..\..\..\..\..\common_smp\src\tx_timer_deactivate.c
..\..\..\..\..\common_smp\src\tx_timer_delete.c
..\..\..\..\..\common_smp\src\tx_timer_expiration_process.c
..\..\..\..\..\common_smp\src\tx_timer_info_get.c
..\..\..\..\..\common_smp\src\tx_timer_initialize.c
..\..\..\..\..\common_smp\src\tx_timer_performance_info_get.c
..\..\..\..\..\common_smp\src\tx_timer_performance_system_info_get.c
..\..\..\..\..\common_smp\src\tx_timer_smp_core_exclude.c
..\..\..\..\..\common_smp\src\tx_timer_smp_core_exclude_get.c
..\..\..\..\..\common_smp\src\tx_timer_system_activate.c
..\..\..\..\..\common_smp\src\tx_timer_system_deactivate.c
..\..\..\..\..\common_smp\src\tx_timer_thread_entry.c
..\..\..\..\..\common_smp\src\tx_trace_buffer_full_notify.c
..\..\..\..\..\common_smp\src\tx_trace_disable.c
..\..\..\..\..\common_smp\src\tx_trace_enable.c
..\..\..\..\..\common_smp\src\tx_trace_event_filter.c
..\..\..\..\..\common_smp\src\tx_trace_event_unfilter.c
..\..\..\..\..\common_smp\src\tx_trace_initialize.c
..\..\..\..\..\common_smp\src\tx_trace_interrupt_control.c
..\..\..\..\..\common_smp\src\tx_trace_isr_enter_insert.c
..\..\..\..\..\common_smp\src\tx_trace_isr_exit_insert.c
..\..\..\..\..\common_smp\src\tx_trace_object_register.c
..\..\..\..\..\common_smp\src\tx_trace_object_unregister.c
..\..\..\..\..\common_smp\src\tx_trace_user_event_insert.c
..\..\..\..\..\common_smp\src\txe_block_allocate.c
..\..\..\..\..\common_smp\src\txe_block_pool_create.c
..\..\..\..\..\common_smp\src\txe_block_pool_delete.c
..\..\..\..\..\common_smp\src\txe_block_pool_info_get.c
..\..\..\..\..\common_smp\src\txe_block_pool_prioritize.c
..\..\..\..\..\common_smp\src\txe_block_release.c
..\..\..\..\..\common_smp\src\txe_byte_allocate.c
..\..\..\..\..\common_smp\src\txe_byte_pool_create.c
..\..\..\..\..\common_smp\src\txe_byte_pool_delete.c
..\..\..\..\..\common_smp\src\txe_byte_pool_info_get.c
..\..\..\..\..\common_smp\src\txe_byte_pool_prioritize.c
..\..\..\..\..\common_smp\src\txe_byte_release.c
..\..\..\..\..\common_smp\src\txe_event_flags_create.c
..\..\..\..\..\common_smp\src\txe_event_flags_delete.c
..\..\..\..\..\common_smp\src\txe_event_flags_get.c
..\..\..\..\..\common_smp\src\txe_event_flags_info_get.c
..\..\..\..\..\common_smp\src\txe_event_flags_set.c
..\..\..\..\..\common_smp\src\txe_event_flags_set_notify.c
..\..\..\..\..\common_smp\src\txe_mutex_create.c
..\..\..\..\..\common_smp\src\txe_mutex_delete.c
..\..\..\..\..\common_smp\src\txe_mutex_get.c
..\..\..\..\..\common_smp\src\txe_mutex_info_get.c
..\..\..\..\..\common_smp\src\txe_mutex_prioritize.c
..\..\..\..\..\common_smp\src\txe_mutex_put.c
..\..\..\..\..\common_smp\src\txe_queue_create.c
..\..\..\..\..\common_smp\src\txe_queue_delete.c
..\..\..\..\..\common_smp\src\txe_queue_flush.c
..\..\..\..\..\common_smp\src\txe_queue_front_send.c
..\..\..\..\..\common_smp\src\txe_queue_info_get.c
..\..\..\..\..\common_smp\src\txe_queue_prioritize.c
..\..\..\..\..\common_smp\src\txe_queue_receive.c
..\..\..\..\..\common_smp\src\txe_queue_send.c
..\..\..\..\..\common_smp\src\txe_queue_send_notify.c
..\..\..\..\..\common_smp\src\txe_semaphore_ceiling_put.c
..\..\..\..\..\common_smp\src\txe_semaphore_create.c
..\..\..\..\..\common_smp\src\txe_semaphore_delete.c
..\..\..\..\..\common_smp\src\txe_semaphore_get.c
..\..\..\..\..\common_smp\src\txe_semaphore_info_get.c
..\..\..\..\..\common_smp\src\txe_semaphore_prioritize.c
..\..\..\..\..\common_smp\src\txe_semaphore_put.c
..\..\..\..\..\common_smp\src\txe_semaphore_put_notify.c
..\..\..\..\..\common_smp\src\txe_thread_create.c
..\..\..\..\..\common_smp\src\txe_thread_delete.c
..\..\..\..\..\common_smp\src\txe_thread_entry_exit_notify.c
..\..\..\..\..\common_smp\src\txe_thread_info_get.c
..\..\..\..\..\common_smp\src\txe_thread_preemption_change.c
..\..\..\..\..\common_smp\src\txe_thread_priority_change.c
..\..\..\..\..\common_smp\src\txe_thread_relinquish.c
..\..\..\..\..\common_smp\src\txe_thread_reset.c
..\..\..\..\..\common_smp\src\txe_thread_resume.c
..\..\..\..\..\common_smp\src\txe_thread_suspend.c
..\..\..\..\..\common_smp\src\txe_thread_terminate.c
..\..\..\..\..\common_smp\src\txe_thread_time_slice_change.c
..\..\..\..\..\common_smp\src\txe_thread_wait_abort.c
..\..\..\..\..\common_smp\src\txe_timer_activate.c
..\..\..\..\..\common_smp\src\txe_timer_change.c
..\..\..\..\..\common_smp\src\txe_timer_create.c
..\..\..\..\..\common_smp\src\txe_timer_deactivate.c
..\..\..\..\..\common_smp\src\txe_timer_delete.c
..\..\..\..\..\common_smp\src\txe_timer_info_get.c

View File

@@ -0,0 +1,764 @@
/**************************************************************************/
/* */
/* 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 */
/** */
/** ThreadX/GHS Event Log (EL) */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* tx_el.h PORTABLE SMP */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the ThreadX event log functions for the GHS MULTI */
/* EventAnalyzer. It is assumed that tx_api.h and tx_port.h have */
/* already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
#ifndef TX_EL_H
#define TX_EL_H
/* Define Event Log specific data definitions. */
#define TX_EL_VERSION_ID 2 /* Event log version ID */
#define TX_EL_HEADER_SIZE 24 /* Event log header size */
#define TX_EL_TNIS 16 /* Number of thread names supported */
/* If the application needs to */
/* track more thread names, just */
/* increase this number and re- */
/* build the ThreadX library. */
#define TX_EL_TNI_ENTRY_SIZE 44 /* Thread name entries are 44 bytes */
#define TX_EL_TNI_NAME_SIZE 34 /* Thread name size in TNI */
#define TX_EL_NO_MORE_TNI_ROOM 1 /* Error return from thread register*/
#define TX_EL_NAME_NOT_FOUND 2 /* Error return from un-register */
#define TX_EL_EVENT_SIZE 32 /* Number of bytes in each event */
#define TX_EL_VALID_ENTRY 1 /* Valid log entry */
#define TX_EL_INVALID_ENTRY 0 /* Invalid log entry */
/* Define necessary offsets. */
#define TX_EL_TNI_VALID_OFFSET 34
#define TX_EL_TNI_THREAD_ID_OFFSET 36
#define TX_EL_TNI_THREAD_PRIORITY_OFF 40
#define TX_EL_EVENT_TYPE_OFFSET 0
#define TX_EL_EVENT_SUBTYPE_OFFSET 2
#define TX_EL_EVENT_TIME_UPPER_OFFSET 4
#define TX_EL_EVENT_TIME_LOWER_OFFSET 8
#define TX_EL_EVENT_THREAD_OFFSET 12
#define TX_EL_EVENT_INFO_1_OFFSET 16
#define TX_EL_EVENT_INFO_2_OFFSET 20
#define TX_EL_EVENT_INFO_3_OFFSET 24
#define TX_EL_EVENT_INFO_4_OFFSET 28
/* Undefine constants that might be been defined previously by tx_api.h. */
#undef TX_EL_INITIALIZE
#undef TX_EL_THREAD_REGISTER
#undef TX_EL_THREAD_UNREGISTER
#undef TX_EL_THREAD_STATUS_CHANGE_INSERT
#undef TX_EL_BYTE_ALLOCATE_INSERT
#undef TX_EL_BYTE_POOL_CREATE_INSERT
#undef TX_EL_BYTE_POOL_DELETE_INSERT
#undef TX_EL_BYTE_RELEASE_INSERT
#undef TX_EL_BLOCK_ALLOCATE_INSERT
#undef TX_EL_BLOCK_POOL_CREATE_INSERT
#undef TX_EL_BLOCK_POOL_DELETE_INSERT
#undef TX_EL_BLOCK_RELEASE_INSERT
#undef TX_EL_EVENT_FLAGS_CREATE_INSERT
#undef TX_EL_EVENT_FLAGS_DELETE_INSERT
#undef TX_EL_EVENT_FLAGS_GET_INSERT
#undef TX_EL_EVENT_FLAGS_SET_INSERT
#undef TX_EL_INTERRUPT_CONTROL_INSERT
#undef TX_EL_QUEUE_CREATE_INSERT
#undef TX_EL_QUEUE_DELETE_INSERT
#undef TX_EL_QUEUE_FLUSH_INSERT
#undef TX_EL_QUEUE_RECEIVE_INSERT
#undef TX_EL_QUEUE_SEND_INSERT
#undef TX_EL_SEMAPHORE_CREATE_INSERT
#undef TX_EL_SEMAPHORE_DELETE_INSERT
#undef TX_EL_SEMAPHORE_GET_INSERT
#undef TX_EL_SEMAPHORE_PUT_INSERT
#undef TX_EL_THREAD_CREATE_INSERT
#undef TX_EL_THREAD_DELETE_INSERT
#undef TX_EL_THREAD_IDENTIFY_INSERT
#undef TX_EL_THREAD_PREEMPTION_CHANGE_INSERT
#undef TX_EL_THREAD_PRIORITY_CHANGE_INSERT
#undef TX_EL_THREAD_RELINQUISH_INSERT
#undef TX_EL_THREAD_RESUME_INSERT
#undef TX_EL_THREAD_SLEEP_INSERT
#undef TX_EL_THREAD_SUSPEND_INSERT
#undef TX_EL_THREAD_TERMINATE_INSERT
#undef TX_EL_THREAD_TIME_SLICE_CHANGE_INSERT
#undef TX_EL_TIME_GET_INSERT
#undef TX_EL_TIME_SET_INSERT
#undef TX_EL_TIMER_ACTIVATE_INSERT
#undef TX_EL_TIMER_CHANGE_INSERT
#undef TX_EL_TIMER_CREATE_INSERT
#undef TX_EL_TIMER_DEACTIVATE_INSERT
#undef TX_EL_TIMER_DELETE_INSERT
#undef TX_EL_BLOCK_POOL_INFO_GET_INSERT
#undef TX_EL_BLOCK_POOL_PRIORITIZE_INSERT
#undef TX_EL_BYTE_POOL_INFO_GET_INSERT
#undef TX_EL_BYTE_POOL_PRIORITIZE_INSERT
#undef TX_EL_EVENT_FLAGS_INFO_GET_INSERT
#undef TX_EL_MUTEX_CREATE_INSERT
#undef TX_EL_MUTEX_DELETE_INSERT
#undef TX_EL_MUTEX_GET_INSERT
#undef TX_EL_MUTEX_INFO_GET_INSERT
#undef TX_EL_MUTEX_PRIORITIZE_INSERT
#undef TX_EL_MUTEX_PUT_INSERT
#undef TX_EL_QUEUE_INFO_GET_INSERT
#undef TX_EL_QUEUE_FRONT_SEND_INSERT
#undef TX_EL_QUEUE_PRIORITIZE_INSERT
#undef TX_EL_SEMAPHORE_INFO_GET_INSERT
#undef TX_EL_SEMAPHORE_PRIORITIZE_INSERT
#undef TX_EL_THREAD_INFO_GET_INSERT
#undef TX_EL_THREAD_WAIT_ABORT_INSERT
#undef TX_EL_TIMER_INFO_GET_INSERT
#undef TX_EL_BLOCK_POOL_PERFORMANCE_INFO_GET_INSERT
#undef TX_EL_BLOCK_POOL_PERFORMANCE_SYSTEM_INFO_GET_INSERT
#undef TX_EL_BYTE_POOL_PERFORMANCE_INFO_GET_INSERT
#undef TX_EL_BYTE_POOL_PERFORMANCE_SYSTEM_INFO_GET_INSERT
#undef TX_EL_EVENT_FLAGS_PERFORMANCE_INFO_GET_INSERT
#undef TX_EL_EVENT_FLAGS_PERFORMANCE_SYSTEM_INFO_GET_INSERT
#undef TX_EL_EVENT_FLAGS_SET_NOTIFY_INSERT
#undef TX_EL_MUTEX_PERFORMANCE_INFO_GET_INSERT
#undef TX_EL_MUTEX_PERFORMANCE_SYSTEM_INFO_GET_INSERT
#undef TX_EL_QUEUE_PERFORMANCE_INFO_GET_INSERT
#undef TX_EL_QUEUE_PERFORMANCE_SYSTEM_INFO_GET_INSERT
#undef TX_EL_QUEUE_SEND_NOTIFY_INSERT
#undef TX_EL_SEMAPHORE_CEILING_PUT_INSERT
#undef TX_EL_SEMAPHORE_PERFORMANCE_INFO_GET_INSERT
#undef TX_EL_SEMAPHORE_PERFORMANCE_SYSTEM_INFO_GET_INSERT
#undef TX_EL_SEMAPHORE_PUT_NOTIFY_INSERT
#undef TX_EL_THREAD_ENTRY_EXIT_NOTIFY_INSERT
#undef TX_EL_THREAD_RESET_INSERT
#undef TX_EL_THREAD_PERFORMANCE_INFO_GET_INSERT
#undef TX_EL_THREAD_PERFORMANCE_SYSTEM_INFO_GET_INSERT
#undef TX_EL_THREAD_STACK_ERROR_NOTIFY_INSERT
#undef TX_EL_TIMER_PERFORMANCE_INFO_GET_INSERT
#undef TX_EL_TIMER_PERFORMANCE_SYSTEM_INFO_GET_INSERT
/* Define Event Types. */
#define TX_EL_THREAD_CHANGE 1
#define TX_EL_INTERRUPT 2
#define TX_EL_THREADX_CALL 3
#define TX_EL_USER_EVENT 4
#define TX_EL_THREAD_STATUS_CHANGE 5
#define TX_EL_REFRESH 6 /* Not implemented */
#define TX_EL_TIMER 7 /* Not implemented */
#define TX_EL_TIMESOURCE_DELTA 8 /* Not implemented */
/* Define TX_EL_THREADX_CALL event sub-types. */
#define TX_EL_BYTE_ALLOCATE 0
#define TX_EL_BYTE_POOL_CREATE 1
#define TX_EL_BYTE_POOL_DELETE 2
#define TX_EL_BYTE_RELEASE 3
#define TX_EL_BLOCK_ALLOCATE 4
#define TX_EL_BLOCK_POOL_CREATE 5
#define TX_EL_BLOCK_POOL_DELETE 6
#define TX_EL_BLOCK_RELEASE 7
#define TX_EL_EVENT_FLAGS_CREATE 8
#define TX_EL_EVENT_FLAGS_DELETE 9
#define TX_EL_EVENT_FLAGS_GET 10
#define TX_EL_EVENT_FLAGS_SET 11
#define TX_EL_INTERRUPT_CONTROL 12
#define TX_EL_QUEUE_CREATE 13
#define TX_EL_QUEUE_DELETE 14
#define TX_EL_QUEUE_FLUSH 15
#define TX_EL_QUEUE_RECEIVE 16
#define TX_EL_QUEUE_SEND 17
#define TX_EL_SEMAPHORE_CREATE 18
#define TX_EL_SEMAPHORE_DELETE 19
#define TX_EL_SEMAPHORE_GET 20
#define TX_EL_SEMAPHORE_PUT 21
#define TX_EL_THREAD_CREATE 22
#define TX_EL_THREAD_DELETE 23
#define TX_EL_THREAD_IDENTIFY 24
#define TX_EL_THREAD_PREEMPTION_CHANGE 25
#define TX_EL_THREAD_PRIORITY_CHANGE 26
#define TX_EL_THREAD_RELINQUISH 27
#define TX_EL_THREAD_RESUME 28
#define TX_EL_THREAD_SLEEP 29
#define TX_EL_THREAD_SUSPEND 30
#define TX_EL_THREAD_TERMINATE 31
#define TX_EL_THREAD_TIME_SLICE_CHANGE 32
#define TX_EL_TIME_GET 33
#define TX_EL_TIME_SET 34
#define TX_EL_TIMER_ACTIVATE 35
#define TX_EL_TIMER_CHANGE 36
#define TX_EL_TIMER_CREATE 37
#define TX_EL_TIMER_DEACTIVATE 38
#define TX_EL_TIMER_DELETE 39
#define TX_EL_BLOCK_POOL_INFO_GET 40
#define TX_EL_BLOCK_POOL_PRIORITIZE 41
#define TX_EL_BYTE_POOL_INFO_GET 42
#define TX_EL_BYTE_POOL_PRIORITIZE 43
#define TX_EL_EVENT_FLAGS_INFO_GET 44
#define TX_EL_MUTEX_CREATE 45
#define TX_EL_MUTEX_DELETE 46
#define TX_EL_MUTEX_GET 47
#define TX_EL_MUTEX_INFO_GET 48
#define TX_EL_MUTEX_PRIORITIZE 49
#define TX_EL_MUTEX_PUT 50
#define TX_EL_QUEUE_INFO_GET 51
#define TX_EL_QUEUE_FRONT_SEND 52
#define TX_EL_QUEUE_PRIORITIZE 53
#define TX_EL_SEMAPHORE_INFO_GET 54
#define TX_EL_SEMAPHORE_PRIORITIZE 55
#define TX_EL_THREAD_INFO_GET 56
#define TX_EL_THREAD_WAIT_ABORT 57
#define TX_EL_TIMER_INFO_GET 58
#define TX_EL_BLOCK_POOL_PERFORMANCE_INFO_GET 59
#define TX_EL_BLOCK_POOL_PERFORMANCE_SYSTEM_INFO_GET 60
#define TX_EL_BYTE_POOL_PERFORMANCE_INFO_GET 61
#define TX_EL_BYTE_POOL_PERFORMANCE_SYSTEM_INFO_GET 62
#define TX_EL_EVENT_FLAGS_PERFORMANCE_INFO_GET 63
#define TX_EL_EVENT_FLAGS_PERFORMANCE_SYSTEM_INFO_GET 64
#define TX_EL_EVENT_FLAGS_SET_NOTIFY 65
#define TX_EL_MUTEX_PERFORMANCE_INFO_GET 66
#define TX_EL_MUTEX_PERFORMANCE_SYSTEM_INFO_GET 67
#define TX_EL_QUEUE_PERFORMANCE_INFO_GET 68
#define TX_EL_QUEUE_PERFORMANCE_SYSTEM_INFO_GET 69
#define TX_EL_QUEUE_SEND_NOTIFY 70
#define TX_EL_SEMAPHORE_CEILING_PUT 71
#define TX_EL_SEMAPHORE_PERFORMANCE_INFO_GET 72
#define TX_EL_SEMAPHORE_PERFORMANCE_SYSTEM_INFO_GET 73
#define TX_EL_SEMAPHORE_PUT_NOTIFY 74
#define TX_EL_THREAD_ENTRY_EXIT_NOTIFY 75
#define TX_EL_THREAD_RESET 76
#define TX_EL_THREAD_PERFORMANCE_INFO_GET 77
#define TX_EL_THREAD_PERFORMANCE_SYSTEM_INFO_GET 78
#define TX_EL_THREAD_STACK_ERROR_NOTIFY 79
#define TX_EL_TIMER_PERFORMANCE_INFO_GET 80
#define TX_EL_TIMER_PERFORMANCE_SYSTEM_INFO_GET 81
/* Define ThreadX sub-types. */
#define TX_EL_INTERRUPT_SUB_TYPE 1
#define TX_EL_END_OF_INTERRUPT 3
/* Define event logging filters, which may be used by the application program to
dynamically enable/disable events in run-time. */
#define TX_EL_FILTER_STATUS_CHANGE 0x0001
#define TX_EL_FILTER_INTERRUPTS 0x0002
#define TX_EL_FILTER_THREAD_CALLS 0x0004
#define TX_EL_FILTER_TIMER_CALLS 0x0008
#define TX_EL_FILTER_EVENT_FLAG_CALLS 0x0010
#define TX_EL_FILTER_SEMAPHORE_CALLS 0x0020
#define TX_EL_FILTER_QUEUE_CALLS 0x0040
#define TX_EL_FILTER_BLOCK_CALLS 0x0080
#define TX_EL_FILTER_BYTE_CALLS 0x0100
#define TX_EL_FILTER_MUTEX_CALLS 0x0200
#define TX_EL_FILTER_ALL_EVENTS 0xFFFF
#define TX_EL_ENABLE_ALL_EVENTS 0x0000
/* Define filter macros that are inserted in-line with the other macros below. */
#ifdef TX_ENABLE_EVENT_FILTERS
#define TX_EL_NO_STATUS_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_STATUS_CHANGE)) {
#define TX_EL_NO_INTERRUPT_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_INTERRUPTS)) {
#define TX_EL_NO_THREAD_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_THREAD_CALLS)) {
#define TX_EL_NO_TIMER_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_TIMER_CALLS)) {
#define TX_EL_NO_EVENT_FLAG_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_EVENT_FLAG_CALLS)) {
#define TX_EL_NO_SEMAPHORE_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_SEMAPHORE_CALLS)) {
#define TX_EL_NO_QUEUE_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_QUEUE_CALLS)) {
#define TX_EL_NO_BLOCK_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_BLOCK_CALLS)) {
#define TX_EL_NO_BYTE_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_BYTE_CALLS)) {
#define TX_EL_NO_MUTEX_EVENTS if (!(_tx_el_event_filter & TX_EL_FILTER_MUTEX_CALLS)) {
#define TX_EL_END_FILTER }
#else
#define TX_EL_NO_STATUS_EVENTS
#define TX_EL_NO_INTERRUPT_EVENTS
#define TX_EL_NO_THREAD_EVENTS
#define TX_EL_NO_TIMER_EVENTS
#define TX_EL_NO_EVENT_FLAG_EVENTS
#define TX_EL_NO_SEMAPHORE_EVENTS
#define TX_EL_NO_QUEUE_EVENTS
#define TX_EL_NO_BLOCK_EVENTS
#define TX_EL_NO_BYTE_EVENTS
#define TX_EL_NO_MUTEX_EVENTS
#define TX_EL_END_FILTER
#endif
/* Define externs and constants for non-event log source modules. This is for
the in-line macros below. */
#ifndef TX_EL_SOURCE_CODE
extern UCHAR *_tx_el_tni_start;
extern UCHAR **_tx_el_current_event;
extern UCHAR *_tx_el_event_area_start;
extern UCHAR *_tx_el_event_area_end;
extern UINT _tx_el_maximum_events;
extern ULONG _tx_el_total_events;
extern UINT _tx_el_event_filter;
extern ULONG _tx_el_time_base_upper;
extern ULONG _tx_el_time_base_lower;
/* Define macros for event logging functions. */
#define TX_EL_THREAD_CREATE_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO4(TX_EL_THREAD_CREATE, thread_ptr, stack_start, stack_size, priority); TX_EL_END_FILTER
#define TX_EL_EVENT_FLAGS_SET_INSERT TX_EL_NO_EVENT_FLAG_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_EVENT_FLAGS_SET, group_ptr, flags_to_set, set_option); TX_EL_END_FILTER
#define TX_EL_THREAD_DELETE_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_DELETE, thread_ptr); TX_EL_END_FILTER
#define TX_EL_THREAD_INFO_GET_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_INFO_GET, thread_ptr); TX_EL_END_FILTER
#define TX_EL_THREAD_TIME_SLICE_CHANGE_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_THREAD_TIME_SLICE_CHANGE, thread_ptr, thread_ptr -> tx_thread_new_time_slice, new_time_slice); TX_EL_END_FILTER
#define TX_EL_THREAD_TERMINATE_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_TERMINATE, thread_ptr); TX_EL_END_FILTER
#define TX_EL_THREAD_SLEEP_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_SLEEP, timer_ticks); TX_EL_END_FILTER
#define TX_EL_THREAD_SUSPEND_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_SUSPEND, thread_ptr); TX_EL_END_FILTER
#define TX_EL_THREAD_RELINQUISH_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_THREAD_RELINQUISH); TX_EL_END_FILTER
#define TX_EL_THREAD_RESUME_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_RESUME, thread_ptr); TX_EL_END_FILTER
#define TX_EL_THREAD_PRIORITY_CHANGE_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_THREAD_PRIORITY_CHANGE, thread_ptr, thread_ptr -> tx_thread_priority, new_priority); TX_EL_END_FILTER
#define TX_EL_THREAD_PREEMPTION_CHANGE_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_THREAD_PREEMPTION_CHANGE, thread_ptr, thread_ptr -> tx_thread_preempt_threshold, new_threshold); TX_EL_END_FILTER
#define TX_EL_THREAD_WAIT_ABORT_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_WAIT_ABORT, thread_ptr); TX_EL_END_FILTER
#define TX_EL_THREAD_ENTRY_EXIT_NOTIFY_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_THREAD_ENTRY_EXIT_NOTIFY, thread_ptr, thread_entry_exit_notify); TX_EL_END_FILTER
#define TX_EL_THREAD_RESET_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_RESET, thread_ptr); TX_EL_END_FILTER
#define TX_EL_THREAD_PERFORMANCE_INFO_GET_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_PERFORMANCE_INFO_GET, thread_ptr); TX_EL_END_FILTER
#define TX_EL_THREAD_PERFORMANCE_SYSTEM_INFO_GET_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_THREAD_PERFORMANCE_SYSTEM_INFO_GET); TX_EL_END_FILTER
#define TX_EL_THREAD_STACK_ERROR_NOTIFY_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_THREAD_STACK_ERROR_NOTIFY, stack_error_handler); TX_EL_END_FILTER
#define TX_EL_TIME_SET_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_TIME_SET, new_time); TX_EL_END_FILTER
#define TX_EL_TIME_GET_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_TIME_GET, _tx_timer_system_clock); TX_EL_END_FILTER
#define TX_EL_TIMER_DELETE_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_TIMER_DELETE, timer_ptr); TX_EL_END_FILTER
#define TX_EL_TIMER_CREATE_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO4(TX_EL_TIMER_CREATE, timer_ptr, initial_ticks, reschedule_ticks, auto_activate); TX_EL_END_FILTER
#define TX_EL_TIMER_CHANGE_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_TIMER_CHANGE, timer_ptr, initial_ticks, reschedule_ticks); TX_EL_END_FILTER
#define TX_EL_THREAD_IDENTIFY_INSERT TX_EL_NO_THREAD_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_THREAD_IDENTIFY); TX_EL_END_FILTER
#define TX_EL_TIMER_DEACTIVATE_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_TIMER_DEACTIVATE, timer_ptr); TX_EL_END_FILTER
#define TX_EL_TIMER_ACTIVATE_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_TIMER_ACTIVATE, timer_ptr); TX_EL_END_FILTER
#define TX_EL_TIMER_INFO_GET_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_TIMER_INFO_GET, timer_ptr); TX_EL_END_FILTER
#define TX_EL_TIMER_PERFORMANCE_INFO_GET_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_TIMER_PERFORMANCE_INFO_GET, timer_ptr); TX_EL_END_FILTER
#define TX_EL_TIMER_PERFORMANCE_SYSTEM_INFO_GET_INSERT TX_EL_NO_TIMER_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_TIMER_PERFORMANCE_SYSTEM_INFO_GET); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_PUT_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_SEMAPHORE_PUT, semaphore_ptr, semaphore_ptr -> tx_semaphore_count); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_GET_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_SEMAPHORE_GET, semaphore_ptr, semaphore_ptr -> tx_semaphore_count); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_DELETE_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_SEMAPHORE_DELETE, semaphore_ptr); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_CREATE_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_SEMAPHORE_CREATE, semaphore_ptr, initial_count); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_INFO_GET_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_SEMAPHORE_INFO_GET, semaphore_ptr); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_PRIORITIZE_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_SEMAPHORE_PRIORITIZE, semaphore_ptr); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_CEILING_PUT_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_SEMAPHORE_CEILING_PUT, semaphore_ptr, semaphore_ptr -> tx_semaphore_count, ceiling); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_PERFORMANCE_INFO_GET_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_SEMAPHORE_PERFORMANCE_INFO_GET, semaphore_ptr); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_PERFORMANCE_SYSTEM_INFO_GET_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_SEMAPHORE_PERFORMANCE_SYSTEM_INFO_GET); TX_EL_END_FILTER
#define TX_EL_SEMAPHORE_PUT_NOTIFY_INSERT TX_EL_NO_SEMAPHORE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_SEMAPHORE_PUT_NOTIFY, semaphore_ptr, semaphore_put_notify); TX_EL_END_FILTER
#define TX_EL_QUEUE_FRONT_SEND_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_QUEUE_FRONT_SEND, queue_ptr, source_ptr); TX_EL_END_FILTER
#define TX_EL_QUEUE_SEND_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_QUEUE_SEND, queue_ptr, source_ptr); TX_EL_END_FILTER
#define TX_EL_QUEUE_RECEIVE_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_QUEUE_RECEIVE, queue_ptr, destination_ptr); TX_EL_END_FILTER
#define TX_EL_QUEUE_FLUSH_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_QUEUE_FLUSH, queue_ptr); TX_EL_END_FILTER
#define TX_EL_QUEUE_DELETE_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_QUEUE_DELETE, queue_ptr); TX_EL_END_FILTER
#define TX_EL_QUEUE_CREATE_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO4(TX_EL_QUEUE_CREATE, queue_ptr, queue_start, queue_size, message_size); TX_EL_END_FILTER
#define TX_EL_QUEUE_INFO_GET_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_QUEUE_INFO_GET, queue_ptr); TX_EL_END_FILTER
#define TX_EL_QUEUE_PRIORITIZE_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_QUEUE_PRIORITIZE, queue_ptr); TX_EL_END_FILTER
#define TX_EL_QUEUE_PERFORMANCE_INFO_GET_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_QUEUE_PERFORMANCE_INFO_GET, queue_ptr); TX_EL_END_FILTER
#define TX_EL_QUEUE_PERFORMANCE_SYSTEM_INFO_GET_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_QUEUE_PERFORMANCE_SYSTEM_INFO_GET); TX_EL_END_FILTER
#define TX_EL_QUEUE_SEND_NOTIFY_INSERT TX_EL_NO_QUEUE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_QUEUE_SEND_NOTIFY, queue_ptr, queue_send_notify); TX_EL_END_FILTER
#define TX_EL_EVENT_FLAGS_GET_INSERT TX_EL_NO_EVENT_FLAG_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_EVENT_FLAGS_GET, group_ptr, requested_flags, get_option); TX_EL_END_FILTER
#define TX_EL_EVENT_FLAGS_DELETE_INSERT TX_EL_NO_EVENT_FLAG_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_EVENT_FLAGS_DELETE, group_ptr); TX_EL_END_FILTER
#define TX_EL_EVENT_FLAGS_CREATE_INSERT TX_EL_NO_EVENT_FLAG_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_EVENT_FLAGS_CREATE, group_ptr); TX_EL_END_FILTER
#define TX_EL_EVENT_FLAGS_INFO_GET_INSERT TX_EL_NO_EVENT_FLAG_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_EVENT_FLAGS_INFO_GET, group_ptr); TX_EL_END_FILTER
#define TX_EL_EVENT_FLAGS_PERFORMANCE_INFO_GET_INSERT TX_EL_NO_EVENT_FLAG_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_EVENT_FLAGS_PERFORMANCE_INFO_GET, group_ptr); TX_EL_END_FILTER
#define TX_EL_EVENT_FLAGS_PERFORMANCE_SYSTEM_INFO_GET_INSERT TX_EL_NO_EVENT_FLAG_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_EVENT_FLAGS_PERFORMANCE_SYSTEM_INFO_GET); TX_EL_END_FILTER
#define TX_EL_EVENT_FLAGS_SET_NOTIFY_INSERT TX_EL_NO_EVENT_FLAG_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_EVENT_FLAGS_SET_NOTIFY, group_ptr, events_set_notify); TX_EL_END_FILTER
#define TX_EL_BYTE_RELEASE_INSERT TX_EL_NO_BYTE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_BYTE_RELEASE, pool_ptr, memory_ptr); TX_EL_END_FILTER
#define TX_EL_BYTE_POOL_DELETE_INSERT TX_EL_NO_BYTE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_BYTE_POOL_DELETE, pool_ptr); TX_EL_END_FILTER
#define TX_EL_BYTE_POOL_CREATE_INSERT TX_EL_NO_BYTE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_BYTE_POOL_CREATE, pool_ptr, pool_start, pool_size); TX_EL_END_FILTER
#define TX_EL_BYTE_POOL_INFO_GET_INSERT TX_EL_NO_BYTE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_BYTE_POOL_INFO_GET, pool_ptr); TX_EL_END_FILTER
#define TX_EL_BYTE_POOL_PRIORITIZE_INSERT TX_EL_NO_BYTE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_BYTE_POOL_PRIORITIZE, pool_ptr); TX_EL_END_FILTER
#define TX_EL_BYTE_ALLOCATE_INSERT TX_EL_NO_BYTE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_BYTE_ALLOCATE, pool_ptr, memory_ptr, memory_size); TX_EL_END_FILTER
#define TX_EL_BYTE_POOL_PERFORMANCE_INFO_GET_INSERT TX_EL_NO_BYTE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_BYTE_POOL_PERFORMANCE_INFO_GET, pool_ptr); TX_EL_END_FILTER
#define TX_EL_BYTE_POOL_PERFORMANCE_SYSTEM_INFO_GET_INSERT TX_EL_NO_BYTE_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_BYTE_POOL_PERFORMANCE_SYSTEM_INFO_GET); TX_EL_END_FILTER
#define TX_EL_BLOCK_RELEASE_INSERT TX_EL_NO_BLOCK_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_BLOCK_RELEASE, pool_ptr, block_ptr); TX_EL_END_FILTER
#define TX_EL_BLOCK_POOL_DELETE_INSERT TX_EL_NO_BLOCK_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_BLOCK_POOL_DELETE, pool_ptr); TX_EL_END_FILTER
#define TX_EL_BLOCK_POOL_CREATE_INSERT TX_EL_NO_BLOCK_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO4(TX_EL_BLOCK_POOL_CREATE, pool_ptr, pool_start, pool_size, block_size); TX_EL_END_FILTER
#define TX_EL_BLOCK_POOL_INFO_GET_INSERT TX_EL_NO_BLOCK_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_BLOCK_POOL_INFO_GET, pool_ptr); TX_EL_END_FILTER
#define TX_EL_BLOCK_POOL_PRIORITIZE_INSERT TX_EL_NO_BLOCK_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_BLOCK_POOL_PRIORITIZE, pool_ptr); TX_EL_END_FILTER
#define TX_EL_BLOCK_ALLOCATE_INSERT TX_EL_NO_BLOCK_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_BLOCK_ALLOCATE, pool_ptr, block_ptr); TX_EL_END_FILTER
#define TX_EL_BLOCK_POOL_PERFORMANCE_INFO_GET_INSERT TX_EL_NO_BLOCK_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_BLOCK_POOL_PERFORMANCE_INFO_GET, pool_ptr); TX_EL_END_FILTER
#define TX_EL_BLOCK_POOL_PERFORMANCE_SYSTEM_INFO_GET_INSERT TX_EL_NO_BLOCK_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_BLOCK_POOL_PERFORMANCE_SYSTEM_INFO_GET); TX_EL_END_FILTER
#define TX_EL_MUTEX_CREATE_INSERT TX_EL_NO_MUTEX_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(TX_EL_MUTEX_CREATE, mutex_ptr, inherit); TX_EL_END_FILTER
#define TX_EL_MUTEX_DELETE_INSERT TX_EL_NO_MUTEX_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_MUTEX_DELETE, mutex_ptr); TX_EL_END_FILTER
#define TX_EL_MUTEX_GET_INSERT TX_EL_NO_MUTEX_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_MUTEX_GET, mutex_ptr, mutex_ptr -> tx_mutex_owner, mutex_ptr -> tx_mutex_ownership_count); TX_EL_END_FILTER
#define TX_EL_MUTEX_INFO_GET_INSERT TX_EL_NO_MUTEX_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_MUTEX_INFO_GET, mutex_ptr); TX_EL_END_FILTER
#define TX_EL_MUTEX_PRIORITIZE_INSERT TX_EL_NO_MUTEX_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_MUTEX_PRIORITIZE, mutex_ptr); TX_EL_END_FILTER
#define TX_EL_MUTEX_PUT_INSERT TX_EL_NO_MUTEX_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(TX_EL_MUTEX_PUT, mutex_ptr, mutex_ptr -> tx_mutex_owner, mutex_ptr -> tx_mutex_ownership_count); TX_EL_END_FILTER
#define TX_EL_MUTEX_PERFORMANCE_INFO_GET_INSERT TX_EL_NO_MUTEX_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(TX_EL_MUTEX_PERFORMANCE_INFO_GET, mutex_ptr); TX_EL_END_FILTER
#define TX_EL_MUTEX_PERFORMANCE_SYSTEM_INFO_GET_INSERT TX_EL_NO_MUTEX_EVENTS TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(TX_EL_MUTEX_PERFORMANCE_SYSTEM_INFO_GET); TX_EL_END_FILTER
#endif
/* Define Event Log function prototypes. */
VOID _tx_el_initialize(VOID);
UINT _tx_el_thread_register(TX_THREAD *thread_ptr);
UINT _tx_el_thread_unregister(TX_THREAD *thread_ptr);
VOID _tx_el_user_event_insert(UINT sub_type, ULONG info_1, ULONG info_2,
ULONG info_3, ULONG info_4);
VOID _tx_el_thread_running(TX_THREAD *thread_ptr);
VOID _tx_el_thread_preempted(TX_THREAD *thread_ptr);
VOID _tx_el_interrupt(UINT interrupt_number);
VOID _tx_el_interrupt_end(UINT interrupt_number);
VOID _tx_el_interrupt_control_call(void);
VOID _tx_el_event_log_on(void);
VOID _tx_el_event_log_off(void);
VOID _tx_el_event_filter_set(UINT filter);
/* Define macros that are used inside the ThreadX source code.
If event logging is disabled, these macros will be defined
as white space. */
#ifdef TX_ENABLE_EVENT_LOGGING
#ifndef TX_NO_EVENT_INFO
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO4(a, b, c, d, e) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_1_OFFSET)) =\
(ULONG) b;\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_2_OFFSET)) =\
(ULONG) c;\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_3_OFFSET)) =\
(ULONG) d;\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_4_OFFSET)) =\
(ULONG) e;\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(a, b, c, d) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_1_OFFSET)) =\
(ULONG) b;\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_2_OFFSET)) =\
(ULONG) c;\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_3_OFFSET)) =\
(ULONG) d;\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(a, b, c) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_1_OFFSET)) =\
(ULONG) b;\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_2_OFFSET)) =\
(ULONG) c;\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(a, b) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
*((ULONG *) (entry_ptr + TX_EL_EVENT_INFO_1_OFFSET)) =\
(ULONG) b;\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(a) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_THREAD_STATUS_CHANGE_INSERT(a, b) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
TX_EL_NO_STATUS_EVENTS \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREAD_STATUS_CHANGE; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) b; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) a;\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
TX_EL_END_FILTER \
}
#define TX_EL_THREAD_REGISTER(a) \
_tx_el_thread_register(a);
#define TX_EL_THREAD_UNREGISTER(a) \
_tx_el_thread_unregister(a);
#define TX_EL_INITIALIZE _tx_el_initialize();
#else
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO4(a, b, c, d, e) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(a, b, c, d) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(a, b, c) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(a, b) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(a) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREADX_CALL; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) a; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) _tx_thread_smp_current_thread_get();\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
}
#define TX_EL_THREAD_STATUS_CHANGE_INSERT(a, b) \
{ \
UCHAR *entry_ptr; \
ULONG upper_tbu; \
TX_EL_NO_STATUS_EVENTS \
entry_ptr = *_tx_el_current_event; \
*((unsigned short *) entry_ptr) = TX_EL_THREAD_STATUS_CHANGE; \
*((unsigned short *) (entry_ptr + TX_EL_EVENT_SUBTYPE_OFFSET)) = (unsigned short) b; \
do { \
upper_tbu = read_tbu(); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) = upper_tbu; \
*((ULONG *) (entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) =\
(ULONG) read_tbl();\
} while (upper_tbu != read_tbu()); \
*((ULONG *) (entry_ptr + TX_EL_EVENT_THREAD_OFFSET)) =\
(ULONG) a;\
entry_ptr = entry_ptr + TX_EL_EVENT_SIZE;\
if (entry_ptr >= _tx_el_event_area_end) \
{\
entry_ptr = _tx_el_event_area_start;\
}\
*_tx_el_current_event = entry_ptr;\
TX_EL_END_FILTER \
}
#define TX_EL_THREAD_REGISTER(a) \
_tx_el_thread_register(a);
#define TX_EL_THREAD_UNREGISTER(a) \
_tx_el_thread_unregister(a);
#define TX_EL_INITIALIZE _tx_el_initialize();
#endif
#else
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO4(a, b, c, d, e)
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO3(a, b, c, d)
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO2(a, b, c)
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO1(a, b)
#define TX_EL_KERNEL_CALL_EVENT_INSERT_INFO0(a)
#define TX_EL_THREAD_STATUS_CHANGE_INSERT(a, b)
#define TX_EL_THREAD_REGISTER(a)
#define TX_EL_THREAD_UNREGISTER(a)
#define TX_EL_INITIALIZE
#endif
#endif

View File

@@ -0,0 +1,77 @@
/*
* ThreadX C/C++ Library Support
*
* Copyright 1983-2019 Green Hills Software LLC.
*
* This program is the property of Green Hills Software LLC.,
* its contents are proprietary information and no part of it
* is to be disclosed to anyone except employees of Green Hills
* Software LLC., or as agreed in writing signed by the President
* of Green Hills Software LLC.
*/
#ifndef _TX_GHS_H_
#define _TX_GHS_H_
#include <signal.h>
#include <stdio.h>
#include <time.h>
#include <setjmp.h>
#if defined(__ghs) && (__GHS_VERSION_NUMBER >= 500)
extern void *__ghs_GetThreadLocalStorageItem(int specifier);
/* Thread-local storage routines for Green Hills releases 5.x and beyond.
The following specifiers are used when calling
__ghs_GetThreadLocalStorageItem.
If __ghs_GetThreadLocalStorageItem is customized to
return a per-thread errno value, define the preprocessor symbol
USE_THREAD_LOCAL_ERRNO in ind_errn.c.
*/
enum __ghs_ThreadLocalStorage_specifier {
__ghs_TLS_asctime_buff,
__ghs_TLS_tmpnam_space,
__ghs_TLS_strtok_saved_pos,
__ghs_TLS_Errno,
__ghs_TLS_gmtime_temp,
__ghs_TLS___eh_globals,
__ghs_TLS_SignalHandlers
};
#else
/* Thread-local storage routines for Green Hills releases 4.x and 3.x . */
typedef void (*SignalHandler)(int);
typedef struct
{
int Errno; /* errno. */
SignalHandler SignalHandlers[_SIGMAX]; /* signal() buffer. */
char tmpnam_space[L_tmpnam]; /* tmpnam(NULL) buffer. */
char asctime_buff[30]; /* . */
char *strtok_saved_pos; /* strtok() position. */
struct tm gmtime_temp; /* gmtime() and localtime() buffer. */
void *__eh_globals; /* Pointer for C++ exception handling. */
} ThreadLocalStorage;
ThreadLocalStorage *GetThreadLocalStorage(void);
#endif
void __ghsLock(void);
void __ghsUnlock(void);
int __ghs_SaveSignalContext(jmp_buf);
void __ghs_RestoreSignalContext(jmp_buf);
/* prototypes for FILE lock routines. */
void __ghs_flock_file(void *);
void __ghs_funlock_file(void *);
int __ghs_ftrylock_file(void *);
void __ghs_flock_create(void **);
void __ghs_flock_destroy(void *);
/* prototype for GHS/ThreadX error shell checking. */
void __ghs_rnerr(char *errMsg, int stackLevels, int stackTraceDisplay, void *hexVal);
#endif /* _TX_GHS_H_ */

View File

@@ -0,0 +1,452 @@
/**************************************************************************/
/* */
/* 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-A5x-SMP/GHS */
/* 6.1 */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains data type definitions that make the ThreadX */
/* real-time kernel function identically on a variety of different */
/* processor architectures. For example, the size or number of bits */
/* in an "int" data type vary between microprocessor architectures and */
/* even C compilers for the same microprocessor. ThreadX does not */
/* directly use native C data types. Instead, ThreadX creates its */
/* own special types that can be mapped to actual data types by this */
/* file to guarantee consistency in the interface and functionality. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
#ifndef TX_PORT_H
#define TX_PORT_H
/************* Define ThreadX SMP constants. *************/
/* Define the ThreadX SMP maximum number of cores. */
#ifndef TX_THREAD_SMP_MAX_CORES
#define TX_THREAD_SMP_MAX_CORES 4
#endif
/* Define the ThreadX SMP core mask. */
#ifndef TX_THREAD_SMP_CORE_MASK
#define TX_THREAD_SMP_CORE_MASK 0xF /* Where bit 0 represents Core 0, bit 1 represents Core 1, etc. */
#endif
/* Define INLINE_DECLARE macro. */
#define INLINE_DECLARE inline
/* Define the TX_MEMSET macro to remove library reference. */
#define TX_MEMSET(a,b,c) _tx_memset(a,b,c)
static inline void _tx_memset(void * ptr, int value, unsigned num)
{
char *p = ptr;
char *pmax = p + num;
while (p < pmax) *p++ = (char) value;
}
/* Define ThreadX SMP initialization macro. */
#define TX_PORT_SPECIFIC_PRE_INITIALIZATION
/* Define ThreadX SMP pre-scheduler initialization. */
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
/* Enable the inter-core interrupt logic. */
#define TX_THREAD_SMP_INTER_CORE_INTERRUPT
/* Determine if there is customer-specific wakeup logic needed. */
#ifdef TX_THREAD_SMP_WAKEUP_LOGIC
/* Include customer-specific wakeup code. */
#include "tx_thread_smp_core_wakeup.h"
#else
#ifdef TX_THREAD_SMP_DEFAULT_WAKEUP_LOGIC
/* Default wakeup code. */
#define TX_THREAD_SMP_WAKEUP_LOGIC
#define TX_THREAD_SMP_WAKEUP(i) _tx_thread_smp_core_preempt(i)
#endif
#endif
/* Ensure that the in-line resume/suspend define is not allowed. */
#ifdef TX_INLINE_THREAD_RESUME_SUSPEND
#undef TX_INLINE_THREAD_RESUME_SUSPEND
#endif
/************* End ThreadX SMP constants. *************/
/* 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 int LONG;
typedef unsigned int ULONG;
typedef unsigned long long ULONG64;
typedef short SHORT;
typedef unsigned short USHORT;
typedef unsigned long long ULONG_PTR;
/* Override the alignment type to use 64-bit alignment and storage for pointers. */
#define ALIGN_TYPE_DEFINED
typedef unsigned long long ALIGN_TYPE;
/* Override the free block marker for byte pools to be a 64-bit constant. */
#define TX_BYTE_BLOCK_FREE ((ALIGN_TYPE) 0xFFFFEEEEFFFFEEEE)
/* 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 4096 /* 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. */
#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */
#define TX_INT_ENABLE 0x00 /* Enable IRQ & FIQ interrupts */
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
source constants would be:
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
*/
#ifndef TX_MISRA_ENABLE
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE _tx_thread_smp_time_get()
#endif
#else
#ifndef TX_TRACE_TIME_SOURCE
ULONG _tx_misra_time_stamp_get(VOID);
#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get()
#endif
#endif
#ifndef TX_TRACE_TIME_MASK
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
#endif
/* Define the port specific options for the _tx_build_options variable. This variable indicates
how the ThreadX library was built. */
#ifdef TX_ENABLE_FIQ_SUPPORT
#define TX_FIQ_ENABLED 1
#else
#define TX_FIQ_ENABLED 0
#endif
#ifdef TX_ENABLE_IRQ_NESTING
#define TX_IRQ_NESTING_ENABLED 2
#else
#define TX_IRQ_NESTING_ENABLED 0
#endif
#ifdef TX_ENABLE_FIQ_NESTING
#define TX_FIQ_NESTING_ENABLED 4
#else
#define TX_FIQ_NESTING_ENABLED 0
#endif
#define TX_PORT_SPECIFIC_BUILD_OPTIONS (TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED)
/* Define the in-line initialization constant so that modules with in-line
initialization capabilities can prevent their initialization from being
a function call. */
#ifdef TX_MISRA_ENABLE
#define TX_DISABLE_INLINE
#else
#define TX_INLINE_INITIALIZATION
#endif
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
define is negated, thereby forcing the stack fill which is necessary for the stack checking
logic. */
#ifndef TX_MISRA_ENABLE
#ifdef TX_ENABLE_STACK_CHECKING
#undef TX_DISABLE_STACK_FILLING
#endif
#endif
/* Define the TX_THREAD control block extensions for this port. The main reason
for the multiple macros is so that backward compatibility can be maintained with
existing ThreadX kernel awareness modules. */
#define TX_THREAD_EXTENSION_0
#define TX_THREAD_EXTENSION_1
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_fp_enable;
#define TX_THREAD_EXTENSION_3 VOID * tx_thread_eh_globals; \
int Errno; \
char * strtok_saved_pos; \
VOID *tx_thread_extension_ptr;
/* Define the port extensions of the remaining ThreadX objects. */
#define TX_BLOCK_POOL_EXTENSION
#define TX_BYTE_POOL_EXTENSION
#define TX_EVENT_FLAGS_GROUP_EXTENSION
#define TX_MUTEX_EXTENSION
#define TX_QUEUE_EXTENSION
#define TX_SEMAPHORE_EXTENSION
#define TX_TIMER_EXTENSION
/* Define the user extension field of the thread control block. Nothing
additional is needed for this port so it is defined as white space. */
#ifndef TX_THREAD_USER_EXTENSION
#define TX_THREAD_USER_EXTENSION
#endif
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
tx_thread_shell_entry, and tx_thread_terminate. */
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
/* Define the ThreadX object creation extensions for the remaining objects. */
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
/* Define the ThreadX object deletion extensions for the remaining objects. */
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
/* Determine if the ARM architecture has the CLZ instruction. This is available on
architectures v5 and above. If available, redefine the macro for calculating the
lowest bit set. */
#ifndef TX_DISABLE_INLINE
#include <arm64_ghs.h>
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \
b = (UINT) __CLZ32((ULONG) m); \
b = 31 - b;
#endif
/* Define the internal timer extension to also hold the thread pointer such that _tx_thread_timeout
can figure out what thread timeout to process. */
#define TX_TIMER_INTERNAL_EXTENSION VOID *tx_timer_internal_extension_ptr;
/* Define the thread timeout setup logic in _tx_thread_create. */
#define TX_THREAD_CREATE_TIMEOUT_SETUP(t) (t) -> tx_thread_timer.tx_timer_internal_timeout_function = &(_tx_thread_timeout); \
(t) -> tx_thread_timer.tx_timer_internal_timeout_param = 0; \
(t) -> tx_thread_timer.tx_timer_internal_extension_ptr = (VOID *) (t);
/* Define the thread timeout pointer setup in _tx_thread_timeout. */
#define TX_THREAD_TIMEOUT_POINTER_SETUP(t) (t) = (TX_THREAD *) _tx_timer_expired_timer_ptr -> tx_timer_internal_extension_ptr;
/************* Define ThreadX SMP data types and function prototypes. *************/
struct TX_THREAD_STRUCT;
/* Define the ThreadX SMP protection structure. */
typedef struct TX_THREAD_SMP_PROTECT_STRUCT
{
ULONG tx_thread_smp_protect_in_force;
ULONG tx_thread_smp_protect_core;
ULONG tx_thread_smp_protect_count;
ULONG tx_thread_smp_protect_pad_0;
ULONG tx_thread_smp_protect_pad_1;
ULONG tx_thread_smp_protect_pad_2;
ULONG tx_thread_smp_protect_pad_3;
} TX_THREAD_SMP_PROTECT;
/* 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. */
#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
#define TX_DISABLE interrupt_save = _tx_thread_smp_protect();
#define TX_RESTORE _tx_thread_smp_unprotect(interrupt_save);
/************* End ThreadX SMP data type and function prototype definitions. *************/
/* 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 VFP extension for the Cortex-A5x. Each is assumed to be called in the context of the executing
thread. */
#ifndef TX_SOURCE_CODE
#define tx_thread_fp_enable _tx_thread_fp_enable
#define tx_thread_fp_disable _tx_thread_fp_disable
#endif
VOID tx_thread_fp_enable(VOID);
VOID tx_thread_fp_disable(VOID);
/* 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-A5x-SMP/GHS Version 6.1 *";
#else
extern CHAR _tx_version_id[];
#endif
#endif

View File

@@ -0,0 +1,264 @@
Microsoft's Azure RTOS ThreadX SMP for Cortex-A5x
Using the Green Hills Software Tools
1. Open the ThreadX SMP Project Workspace
In order to build the ThreadX SMP library and the ThreadX SMP demonstration
first load the ThreadX SMP project workspace azure_rtos_workspace.gpj, which is
located inside your ThreadX SMP directory.
2. Building the ThreadX SMP run-time Library
Building the ThreadX SMP library is easy; simply select the MULTI project file
tx.gpj and then select the build button. You should now observe the
compilation and assembly of the ThreadX SMP library. This project build produces
the ThreadX SMP library file tx.a.
3. Demonstration System
The ThreadX SMP demonstration is designed to execute under the MULTI environment
on the Xilinx UltraScale+ ZCU102 evaluation board.
Building the demonstration is easy; simply select the MULTI project file
sample_threadx.gpj. At this point, select the "Project Build" button and observe
the compilation, assembly, and linkage of the ThreadX SMP demonstration application.
You are now ready to download the ELF image using the Xilinx tools on the ZCU102
evaluation board.
4. System Initialization
The system entry point using the Green Hills tools is at the label _boot.
This is defined within the tx_boot.a64 file. In addition, this is where all static
and global preset C variable initialization processing is called from.
After the Green Hills startup function returns, ThreadX SMP initialization is
called. The main initialization function is _tx_initialize_low_level and
is located in the file tx_initialize_low_level.a64. This function is responsible
for setting up various system data structures, interrupt vectors, and the
periodic timer interrupt source of ThreadX SMP.
In addition, _tx_initialize_low_level determines where the first available
RAM memory address is located. This address is supplied to tx_application_define.
By default, the first available RAM memory address is assumed to start at the
beginning of the ThreadX SMP section .free_mem. If changes are made to the
sample_threadx.ld file, the .free_mem section should remain the last allocated
section in the main RAM area. The starting address of this section is passed
to tx_application_define.
5. Register Usage and Stack Frames
The 64-bit Green Hills compiler assumes that registers x0-x18 are scratch
registers for each function. All other registers used by a C function must
be preserved by the function. ThreadX SMP takes advantage of this in
situations where a context switch happens as a result of making a ThreadX SMP
service call (which is itself a C function). In such cases, the saved
context of a thread is only the non-scratch registers.
The following defines the saved context stack frames for context switches
that occur as a result of interrupt handling or from thread-level API calls.
All suspended threads have one of these two types of stack frames. The top
of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
associated thread control block TX_THREAD.
FP not enabled and TX_THREAD.tx_thread_fp_enable == 0:
Offset Interrupted Stack Frame Non-Interrupt Stack Frame
0x000 SPSR DAIF
0x008 ELR 0
0x010 x28 x27
0x018 reserved x28
0x020 x26 x25
0x028 x27 x26
0x030 x24 x23
0x038 x25 x24
0x040 x22 x21
0x048 x23 x22
0x050 x20 x19
0x058 x21 x20
0x060 x18 x29
0x068 x19 x30
0x070 x16
0x078 x17
0x080 x14
0x088 x15
0x090 x12
0x098 x13
0x0A0 x10
0x0A8 x11
0x0B0 x8
0x0B8 x9
0x0C0 x6
0x0C8 x7
0x0D0 x4
0x0D8 x5
0x0E0 x2
0x0E8 x3
0x0F0 x0
0x0F8 x1
0x100 x29
0x108 x30
FP enabled and TX_THREAD.tx_thread_fp_enable == 1:
Offset Interrupted Stack Frame Non-Interrupt Stack Frame
0x000 SPSR DAIF
0x008 ELR 0
0x010 FPSR FPSR
0x018 FPCR FPCR
0x020 q30 q14
0x030 q31 q15
0x040 q28 q12
0x050 q29 q13
0x060 q26 q10
0x070 q27 q11
0x080 q24 q8
0x090 q25 q9
0x0A0 q22 x27
0x0A8 x28
0x0B0 q23 x25
0x0B8 x26
0x0C0 q20 x23
0x0C8 x24
0x0D0 q21 x21
0x0D8 x22
0x0E0 q18 x19
0x0E8 x20
0x0F0 q19 x29
0x0F8 x30
0x100 q16
0x110 q17
0x120 q14
0x130 q15
0x140 q12
0x150 q13
0x160 q10
0x170 q11
0x180 q8
0x190 q9
0x1A0 q6
0x1B0 q7
0x1C0 q4
0x1D0 q5
0x1E0 q2
0x1F0 q3
0x200 q0
0x210 q1
0x220 x28
0x228 reserved
0x230 x26
0x238 x27
0x240 x24
0x248 x25
0x250 x22
0x258 x23
0x260 x20
0x268 x21
0x270 x18
0x278 x19
0x280 x16
0x288 x17
0x290 x14
0x298 x15
0x2A0 x12
0x2A8 x13
0x2B0 x10
0x2B8 x11
0x2C0 x8
0x2C8 x9
0x2D0 x6
0x2D8 x7
0x2E0 x4
0x2E8 x5
0x2F0 x2
0x2F8 x3
0x300 x0
0x308 x1
0x310 x29
0x318 x30
6. Improving Performance
The distribution version of ThreadX SMP is built without any compiler
optimizations. This makes it easy to debug because you can trace or set
breakpoints inside of ThreadX SMP itself. Of course, this costs some
performance. To make ThreadX SMP run faster, you can change the tx.gpj project
to disable debug information and enable the desired optimizations.
In addition, you can eliminate the ThreadX SMP basic API error checking by
compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
defined before tx_api.h is included.
7. Interrupt Handling
ThreadX SMP provides complete and high-performance interrupt handling for Cortex-A5x
targets. Interrupts handlers for the 64-bit mode of the Cortex-A5x have the following
format:
.global __irq_handler
__irq_handler:
STP x29, x30, [sp, #-16]!
BL _tx_thread_context_save
/* Your ISR call goes here! */
BL application_isr_handler
B _tx_thread_context_restore
By default, ThreadX SMP assumes EL3 level of execution. Running and taking exceptions in EL1
and EL2 can be done by simply building the ThreadX library with either EL1 or EL2 defined.
8. ThreadX SMP Timer Interrupt
ThreadX SMP requires a periodic interrupt source to manage all time-slicing, thread sleeps,
timeouts, and application timers. Without such a timer interrupt source, these services are
not functional. However, all other ThreadX SMP services are operational without a periodic
timer source.
To add the timer interrupt processing, simply make a call to _tx_timer_interrupt in the IRQ
processing. An example of this can be found in the file tx_initialize_low_level.a64.
9. FP Support
By default, FP support is disabled for each thread. If saving the context of the FP registers
is needed, the following API call must be made from the context of the application thread - before
the FP usage:
void tx_thread_fp_enable(void);
After this API is called in the application, FP registers will be saved/restored for this thread if it
is preempted via an interrupt. All other suspension of the this thread will not require the FP registers
to be saved/restored.
To disable FP register context saving, simply call the following API:
void tx_thread_fp_disable(void);
10. Revision History
For generic code revision information, please refer to the readme_threadx_generic.txt
file, which is included in your distribution. The following details the revision
information associated with this specific port of ThreadX SMP:
09/30/2020 Initial ThreadX SMP version 6.1 of Cortex-A5x/Green Hills port.
Copyright(c) 1996-2020 Microsoft Corporation
https://azure.com/rtos

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,502 @@
/*
* ThreadX C/C++ Library Support
*
* Copyright 1983-2019 Green Hills Software LLC.
*
* This program is the property of Green Hills Software LLC.,
* its contents are proprietary information and no part of it
* is to be disclosed to anyone except employees of Green Hills
* Software LLC., or as agreed in writing signed by the President
* of Green Hills Software LLC.
*/
#define TX_THREAD_SMP_SOURCE_CODE
#include "tx_ghs.h"
#ifndef TX_DISABLE_ERROR_CHECKING
#define TX_DISABLE_ERROR_CHECKING
#endif
#include "tx_api.h"
#include <setjmp.h>
#include <string.h>
/* Allow these routines to access the following ThreadX global variables. */
extern ULONG _tx_thread_created_count;
extern TX_THREAD *_tx_thread_created_ptr;
/* extern TX_THREAD *_tx_thread_current_ptr[]; Not referenced directly in SMP. */
#if defined(__ghs) && (__GHS_VERSION_NUMBER >= 500)
/* Thread-local storage routines for Green Hills releases 5.x and above. */
/*
Thread-Local (Per-Thread) Library Data Retrieval
================================================
__ghs_ThreadLocalStorage_specifier defines all library data items
that the Green Hills libraries allow to be allocated per-thread.
An implementation can choose which of these data items to allocate
for each thread. For example, an implementation may choose to
allocate an errno value for each thread, but not the strtok_saved_pos
pointer. The application could then use strtok_r instead of strtok for
correct operation.
To add per-thread library data, define one of the
TX_THREAD_EXTENSION_* macros in tx_port.h to include the data item
or items in each thread control block TX_THREAD.
If C++ with exceptions is being used, the __eh_globals entry must be
allocated for each thread. This is typically done by default using
TX_THREAD_EXTENSION_1 in tx_port.h.
If __ghs_GetThreadLocalStorageItem is customized to return a
per-thread errno value, you should also:
* Customize the System Library for your project
* Define the preprocessor symbol USE_THREAD_LOCAL_ERRNO in
src/libsys/ind_errn.c
If you customize the System Library, you should remove ind_thrd.c
from the libsys.gpj subproject.
*/
/* Provide global __eh_globals value to support C++ exception handling
outside a thread context. This name also forces this module to be
included in the linked program instead of the ind_thrd.o module from
the System Library libsys.a.
*/
static void *__eh_globals;
#pragma ghs startnomisra
void *__ghs_GetThreadLocalStorageItem(int specifier)
{
void *ptlsitem = (void *)0;
TX_THREAD *current_thread_ptr;
/* Pickup current thread pointer. */
TX_THREAD_GET_CURRENT(current_thread_ptr)
switch (specifier) {
case (int)__ghs_TLS_Errno:
/* Set ptslsitem to the address of the per-thread errno value.
The per-thread errno value should have the type int.
If returning a per-thread errno value, follow the steps
above.
This item is used by numerous library functions.
*/
break;
case (int)__ghs_TLS_SignalHandlers:
/* Set ptslsitem to the address of the per-thread SignalHandlers
array. The per-thread SignalHandlers array should have the
array type as in the following declaration:
SignalHandler SignalHandlers[_SIGMAX];
The SignalHandler type and _SIGMAX constant are defined in
ind_thrd.h.
This item is used by the library functions signal() and
raise().
*/
break;
case (int)__ghs_TLS_asctime_buff:
/* Set ptslsitem to the address of the per-thread asctime_buff
array. The per-thread asctime_buff array should have the
array type as in the following declaration:
char asctime_buff[30];
This item is used by the library functions asctime() and
ctime(). The library provides asctime_r() and ctime_r(),
inherently thread-safe versions of these functions.
*/
break;
case (int)__ghs_TLS_tmpnam_space:
/* Set ptslsitem to the address of the per-thread tmpnam_space
array. The per-thread tmpnam_space array should have the
array type as in the following declaration:
char tmpnam_space[L_tmpnam];
The constant is defined in <stdio.h>
This item is used by the library function tmpnam() when
passed NULL. The library provides tmpnam_r(), an
inherently thread-safe version of tmpnam().
*/
break;
case (int)__ghs_TLS_strtok_saved_pos:
/* Set ptslsitem to the address of the per-thread
strtok_saved_pos pointer. The per-thread strtok_saved_pos
pointer should have the type "char *".
This item is used by the library function strtok().
The library provides strtok_r(), an inherently thread-safe
version of strtok().
*/
break;
case (int)__ghs_TLS_gmtime_temp:
/* Set ptslsitem to the address of the per-thread gmtime_temp
value. The per-thread gmtime_temp value should have the
type "struct tm" defined in time.h, included by indos.h.
This item is used by the library functions gmtime() and
localtime(). The library provides gmtime_r() and
localtime_r(), inherently thread-safe versions of these
functions.
*/
break;
case (int)__ghs_TLS___eh_globals:
/* Set ptslsitem to the address of the per-thread __eh_globals
value. The per-thread __eh_globals value should have the
type "void *".
This item is used by C++ exception handling.
*/
if (current_thread_ptr)
ptlsitem = (void *)&(current_thread_ptr->tx_thread_eh_globals);
else
/* Use the global __eh_globals pointer. */
ptlsitem = (void *)&__eh_globals;
break;
}
return ptlsitem;
}
// Force this file to be pulled into the program when linking with this
// library.
#pragma ghs alias __ghsautoimport_tx_ghs __ghs_GetThreadLocalStorageItem
#pragma ghs endnomisra
#else
/* Thread-local storage routines for Green Hills releases 4.x and 3.x . */
/*
* ThreadX C and C++ thread-safe library support routines.
*
* This implementation merely tries to guarantee thread safety within
* individual C library calls such as malloc() and free(), but it does
* not attempt to solve the problems associated with the following
* multithreaded issues:
*
* 1. Use of errno. This can be made thread-safe by adding errno
* to TX_THREAD_PORT_EXTENSION and using that within a modified
* version of libsys/ind_errno.c.
*
* 2. Thread safety ACROSS library calls. Certain C library calls either
* return pointers to statically-allocated data structures or maintain
* state across calls. These include strtok(), asctime(), gmtime(),
* tmpnam(NULL), signal(). To make such C library routines thread-safe
* would require adding a ThreadLocalStorage struct to the thread control
* block TX_THREAD. Since relatively few applications make use of these
* library routines, the implementation provided here uses a single, global
* ThreadLocalStorage data structure rather than greatly increasing the size
* of the thread control block TX_THREAD.
*
* The ThreadX global variable _tx_thread_current_ptr points to the
* current thread's control block TX_THREAD. If a ThreadLocalStorage struct
* called tx_tls is placed in TX_THREAD, the function GetThreadLocalStorage
* should be modified to return &(_tx_thread_current_ptr->tx_tls).
*/
static ThreadLocalStorage GlobalTLS;
ThreadLocalStorage *GetThreadLocalStorage()
{
return &GlobalTLS;
}
#endif
/*
* Use a global ThreadX mutex to implement thread safety within C and C++
* library routines.
*
*/
TX_MUTEX __ghLockMutex;
/*
* Acquire general lock. Blocks until the lock becomes available.
* Use tx_mutex_get to implement __ghsLock
*/
void __ghsLock(void)
{
tx_mutex_get(&__ghLockMutex, TX_WAIT_FOREVER);
}
/*
* Release general lock
* Use tx_mutex_put to implement __ghsUnlock
*/
void __ghsUnlock(void)
{
tx_mutex_put(&__ghLockMutex);
}
/* ThreadX Initialization function prototype. */
void _tx_initialize_kernel_setup(void);
void __gh_lock_init(void)
{
/* Initialize the low-level portions of ThreadX. */
_tx_initialize_kernel_setup();
/* Create the global thread lock mutex. */
tx_mutex_create(&__ghLockMutex, "__ghLockMutex", TX_NO_INHERIT);
}
/*
Saving State Across setjmp() Calls
==================================
These routines can be used to save and restore arbitrary state
across calls to setjmp() and longjmp().
*/
int __ghs_SaveSignalContext(jmp_buf jmpbuf)
{
return 0;
}
/* Restore arbitrary state across a longjmp() */
void __ghs_RestoreSignalContext(jmp_buf jmpbuf)
{
}
#if defined(__GHS_VERSION_NUMBER) && (__GHS_VERSION_NUMBER < 560)
/*
C++ Exception Handling
======================
These routines allow C++ exceptions to be used in multiple threads.
The default implementation uses __ghs_GetThreadLocalStorageItem
to return a thread-specific __eh_globals pointer.
*/
/* Must be called after __cpp_exception_init() is called to allocate
* and initialize the per-thread exception handling structure */
void *__get_eh_globals(void)
{
#if defined(__ghs) && (__GHS_VERSION_NUMBER >= 500)
return *(void **)__ghs_GetThreadLocalStorageItem(__ghs_TLS___eh_globals);
#else
TX_THREAD *current_thread_ptr;
/* Pickup current thread pointer. */
TX_THREAD_GET_CURRENT(current_thread_ptr)
if (current_thread_ptr)
/* Return thread-specific __eh_globals pointer. */
return current_thread_ptr->tx_thread_eh_globals;
else
/* Return the global __eh_globals pointer. */
return GlobalTLS.__eh_globals;
#endif
}
#endif
#if defined(__ghs) && (__GHS_VERSION_NUMBER >= 500)
#pragma weak __cpp_exception_init
extern void __cpp_exception_init(void **);
#pragma weak __cpp_exception_cleanup
extern void __cpp_exception_cleanup(void **);
/* __tx_cpp_exception_init retrieves the eh_globals field from
thread-local storage and calls __cpp_exception_init.
*/
void __tx_cpp_exception_init(TX_THREAD *thread_ptr) {
void **peh_globals;
if(__cpp_exception_init) {
if (thread_ptr)
peh_globals = &(thread_ptr->tx_thread_eh_globals);
else
/* Use the global __eh_globals pointer. */
peh_globals = &__eh_globals;
__cpp_exception_init(peh_globals);
}
}
/* __tx_cpp_exception_cleanup retrieves the eh_globals field from
thread-local storage and calls __cpp_exception_cleanup.
*/
void __tx_cpp_exception_cleanup(TX_THREAD *thread_ptr) {
void **peh_globals;
if(__cpp_exception_cleanup) {
if (thread_ptr)
peh_globals = &(thread_ptr->tx_thread_eh_globals);
else
/* Use the global __eh_globals pointer. */
peh_globals = &__eh_globals;
__cpp_exception_cleanup(peh_globals);
}
}
/* __ghs_cpp_exception_init is called from ind_crt1.o to initialize
exceptions for the global context.
*/
void __ghs_cpp_exception_init() {
__tx_cpp_exception_init((void *)0);
}
/* __ghs_cpp_exception_cleanup is called from ind_exit.o to clean up
exceptions for the global context.
*/
void __ghs_cpp_exception_cleanup(TX_THREAD *thread_ptr) {
__tx_cpp_exception_cleanup((void *)0);
}
#endif
/*
File Locks
======================
These routines can be customized to implement per-file locks to allow
thread-safe I/O.
*/
/* Acquire lock for FILE *addr */
void __ghs_flock_file(void *addr)
{
tx_mutex_get((TX_MUTEX *)addr, TX_WAIT_FOREVER);
}
/* Release lock for FILE *addr */
void __ghs_funlock_file(void *addr)
{
tx_mutex_put((TX_MUTEX *)addr);
}
/* Non blocking acquire lock for FILE *addr. May return -1 if */
/* not implemented. Returns 0 on success and nonzero otherwise. */
int __ghs_ftrylock_file(void *addr)
{
return -1;
}
/* Calls to initialize local lock data structures before they */
/* are used. */
void __ghs_flock_create(void **addr)
{
*addr = (void *)(&__ghLockMutex);
}
void __ghs_flock_destroy(void *addr) {}
/*
* ThreadX Peak Stack Checking support routines.
*
* All of these routines are called by MULTI's ThreadX-aware debugging
* package to determine the peak stack use for one thread or for all threads.
*
* These routines are included in this file in order to guarantee that they will
* be available while debugging with MULTI. These routines are not referenced by
* any other part of the ThreadX system.
*
* _txs_thread_stack_check: return the peak stack usage for a thread.
*
* _txs_thread_stack_check_2: store the peak stack usage for all threads
* in the tx_thread_stack_size field of each thread
* control block, TX_THREAD. This routine takes
* advantage of the redundancy within the TX_THREAD
* structure since tx_thread_stack_size can be computed
* from the tx_thread_stack_start and tx_thread_stack_end
* fields of TX_THREAD.
*
* _txs_thread_stack_check_2_fixup: clean up from the _txs_thread_stack_check_2
* call by computing the stack size for each
* thread and storing the result in the
* tx_thread_stack_size field of each thread control
* block TX_THREAD.
*
* These three routines do not support architectures such as i960 or StarCore
* where the stack grows up instead of down.
*
*/
#ifndef TX_DISABLE_STACK_CHECKING
ULONG _txs_thread_stack_check(TX_THREAD *thread_ptr)
{
CHAR *cp; /* Pointer inside thread's stack. */
/* Search through the thread's stack to find the highest address modified. */
for ( cp = (CHAR *)thread_ptr->tx_thread_stack_start;
cp <= (CHAR *)thread_ptr->tx_thread_stack_end; ++cp ) {
/* Check if this byte in the stack contains something other than TX_STACK_FILL. */
if (*cp != (char)TX_STACK_FILL) {
/* Assume cp points to the locating marking the peak stack use.
Return the number of bytes from cp up to and including the
end of the stack. */
return (((CHAR *)thread_ptr->tx_thread_stack_end) - (CHAR *)cp + 1);
}
}
return thread_ptr->tx_thread_stack_size;
}
int _txs_thread_stack_check_2(void) {
CHAR * cp; /* Pointer inside thread's stack. */
TX_THREAD * tp; /* Pointer to each thread. */
/* If no threads are created, return immediately. */
if (!_tx_thread_created_count)
return 0;
/* Start iterating through the threads in the system. Assume that we always
have at least one thread (the system timer thread) in the system. */
tp = _tx_thread_created_ptr;
do {
/* Search through the thread's stack to find the highest address modified. */
for ( cp = (CHAR *)tp->tx_thread_stack_start; cp <= (CHAR *)tp->tx_thread_stack_end;
++cp ) {
/* Check if this byte in the stack contains something other than TX_STACK_FILL. */
if (*cp != (char)TX_STACK_FILL) {
/* Assume cp points to the locating marking the peak stack use.
Store the number of bytes from cp up to and including the
end of the stack in the tx_thread_stack_size field. */
tp->tx_thread_stack_size = ((CHAR *)tp->tx_thread_stack_end) - (CHAR *)cp + 1;
break;
}
}
/* Continue with the next thread. */
tp = tp->tx_thread_created_next;
/* Loop until we point to the first thread again. */
} while ( tp != _tx_thread_created_ptr );
return 0;
}
int _txs_thread_stack_check_2_fixup(void) {
TX_THREAD * tp; /* Pointer to each thread. */
/* If no threads are created, return immediately. */
if (!_tx_thread_created_count)
return 0;
/* Start iterating through the threads in the system. Assume that we always
have at least one thread (the system timer thread) in the system. */
tp = _tx_thread_created_ptr;
do {
/* Compute the tx_thread_stack_size field by using the tx_thread_stack_end and
tx_thread_stack_start fields. */
tp->tx_thread_stack_size = (CHAR *)tp->tx_thread_stack_end-(CHAR *)tp->tx_thread_stack_start+1;
/* Continue with the next thread. */
tp = tp->tx_thread_created_next;
/* Loop until we point to the first thread again. */
} while ( tp != _tx_thread_created_ptr );
return 0;
}
#endif /* TX_DISABLE_STACK_CHECKING */

View File

@@ -0,0 +1,162 @@
/**************************************************************************/
/* */
/* 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"
*/
.global _tx_thread_system_stack_ptr
.global _tx_initialize_unused_memory
.global _tx_thread_context_save
.global _tx_thread_context_restore
.global __ghsbegin_free_mem
#ifndef TX_PLATFORM_IRQ_MAX
#define TX_PLATFORM_IRQ_MAX 192 // Size of IRQ handlers table
#endif
.global _tx_platform_initialize_low_level
.global _tx_platform_irq_handlers
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is responsible for any low-level processor */
/* initialization, including setting up interrupt vectors, setting */
/* up a periodic timer interrupt source, saving the system stack */
/* pointer for use in ISR processing later, and finding the first */
/* available RAM memory address for tx_application_define. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_initialize_low_level(VOID)
{ */
.global _tx_initialize_low_level
.type _tx_initialize_low_level, @function
_tx_initialize_low_level:
MSR DAIFSet, 0x3 // Lockout interrupts
/* Save the system stack pointer. */
/* _tx_thread_system_stack_ptr = (VOID_PTR) (sp); */
LDR x0, =_tx_thread_system_stack_ptr // Pickup address of system stack ptr
MOV x1, sp // Pickup SP
SUB x1, x1, #15 //
AND x1, x1, #~0xF // Get 16-bit alignment
STR x1, [x0] // Store system stack
/* Save the first available memory address. */
/* _tx_initialize_unused_memory = (VOID_PTR) _end; */
LDR x0, =_tx_initialize_unused_memory // Pickup address of unused memory ptr
LDR x1, =__ghsbegin_free_mem // Pickup unused memory address - A free
STR x1, [x0] // Store unused memory address
/* Call _tx_platform_initialize_low_level to initialize the interrupt controller and
setup a timer for periodic interrupts. */
STP x29, x30, [sp, #-16]!
BL _tx_platform_initialize_low_level
LDP x29, x30, [sp], #16
/* Done, return to caller. */
RET // Return to caller
/* } */
/* IRQ Handler */
.global __tx_irq_handler
__tx_irq_handler:
STP x29, x30, [sp, #-16]!
BL _tx_thread_context_save // save system context
STP x20, x21, [sp, #-16]! // save working registers
// acknowledge the interrupt
MRS x20, S3_1_C15_C3_0 // read CBAR
ADD x20, x20, #0x20000 // CPU interface base address
LDR w21, [x20, #0xc] // read interrupt ID from GICC_IAR
LDR w0, =0x3ff
AND w1, w0, w21 // keep only ACKINTID bits
LDR w0, =TX_PLATFORM_IRQ_MAX
CMP w1, w0
B.GE tx_irq_done // ignore spurious interrupts
// call interrupt handler
LDR x2, =_tx_platform_irq_handlers // irq_handlers table address
ADD x2, x2, w1, UXTW #4 // irq_handlers + irq_id * 16
LDR x1, [x2] // handler
LDR x0, [x2, #8] // data
BLR x1 // call handler
tx_irq_done:
// signal end of interrupt
STR w21, [x20, #0x10] // write interrupt ID to GICC_EOIR
LDP x20, x21, [sp], #16 // restore working registers
B _tx_thread_context_restore // restore system context

View File

@@ -0,0 +1,317 @@
/**************************************************************************/
/* */
/* 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"
*/
/* .set ENABLE_ARM_FP,1 */
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function restores the interrupt context if it is processing a */
/* nested interrupt. If not, it returns to the interrupt thread if no */
/* preemption is necessary. Otherwise, if preemption is necessary or */
/* if no thread was running, the function returns to the scheduler. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling routine */
/* */
/* CALLED BY */
/* */
/* ISRs Interrupt Service Routines */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_context_restore(VOID)
{ */
.global _tx_thread_context_restore
.type _tx_thread_context_restore, @function
_tx_thread_context_restore:
/* Lockout interrupts. */
MSR DAIFSet, 0x3 // Lockout interrupts
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR exit function to indicate an ISR is complete. */
BL _tx_execution_isr_exit // Call the ISR exit function
#endif
/* Pickup the CPU ID. */
MRS x8, MPIDR_EL1 // Pickup the core ID
UBFX x8, x8, #0, #8 // Isolate and right justify core ID
/* Determine if interrupts are nested. */
/* if (--_tx_thread_system_state)
{ */
LDR x3, =_tx_thread_system_state // Pickup address of system state var
LDR w2, [x3, x8, LSL #2] // Pickup system state
SUB w2, w2, #1 // Decrement the counter
STR w2, [x3, x8, LSL #2] // Store the counter
CMP w2, #0 // Was this the first interrupt?
B.EQ __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. */
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL
#ifdef EL1
MSR SPSR_EL1, x4 // Setup SPSR for return
MSR ELR_EL1, x5 // Setup point of interrupt
#else
#ifdef EL2
MSR SPSR_EL2, x4 // Setup SPSR for return
MSR ELR_EL2, x5 // Setup point of interrupt
#else
MSR SPSR_EL3, x4 // Setup SPSR for return
MSR ELR_EL3, x5 // Setup point of interrupt
#endif
#endif
LDP x18, x19, [sp], #16 // Recover x18, x19
LDP x16, x17, [sp], #16 // Recover x16, x17
LDP x14, x15, [sp], #16 // Recover x14, x15
LDP x12, x13, [sp], #16 // Recover x12, x13
LDP x10, x11, [sp], #16 // Recover x10, x11
LDP x8, x9, [sp], #16 // Recover x8, x9
LDP x6, x7, [sp], #16 // Recover x6, x7
LDP x4, x5, [sp], #16 // Recover x4, x5
LDP x2, x3, [sp], #16 // Recover x2, x3
LDP x0, x1, [sp], #16 // Recover x0, x1
LDP x29, x30, [sp], #16 // Recover x29, x30
ERET // 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 x1, =_tx_thread_current_ptr // Pickup address of current thread ptr
LDR x0, [x1, x8, LSL #3] // Pickup actual current thread pointer
CMP x0, #0 // Is it NULL?
B.EQ __tx_thread_idle_system_restore // Yes, idle system was interrupted
LDR x3, =_tx_thread_execute_ptr // Pickup address of execute thread ptr
LDR x2, [x3, x8, LSL #3] // Pickup actual execute thread pointer
CMP x0, x2 // Is the same thread highest priority?
B.EQ __tx_thread_no_preempt_restore // Same thread in the execute list,
// no preemption needs to happen
LDR x3, =_tx_thread_smp_protection // Build address to protection structure
LDR w3, [x3, #4] // Pickup the owning core
CMP w3, w8 // Is it this core?
B.NE __tx_thread_preempt_restore // No, proceed to preempt thread
LDR x3, =_tx_thread_preempt_disable // Pickup preempt disable address
LDR w2, [x3, #0] // Pickup actual preempt disable flag
CMP w2, #0 // Is it set?
B.EQ __tx_thread_preempt_restore // No, okay to preempt this thread
__tx_thread_no_preempt_restore:
/* Restore interrupted thread or ISR. */
/* Pickup the saved stack pointer. */
/* sp = _tx_thread_current_ptr -> tx_thread_stack_ptr; */
LDR x4, [x0, #8] // Switch to thread stack pointer
MOV sp, x4 //
/* Recover the saved context and return to the point of interrupt. */
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL1
#ifdef EL1
MSR SPSR_EL1, x4 // Setup SPSR for return
MSR ELR_EL1, x5 // Setup point of interrupt
#else
#ifdef EL2
MSR SPSR_EL2, x4 // Setup SPSR for return
MSR ELR_EL2, x5 // Setup point of interrupt
#else
MSR SPSR_EL3, x4 // Setup SPSR for return
MSR ELR_EL3, x5 // Setup point of interrupt
#endif
#endif
LDP x18, x19, [sp], #16 // Recover x18, x19
LDP x16, x17, [sp], #16 // Recover x16, x17
LDP x14, x15, [sp], #16 // Recover x14, x15
LDP x12, x13, [sp], #16 // Recover x12, x13
LDP x10, x11, [sp], #16 // Recover x10, x11
LDP x8, x9, [sp], #16 // Recover x8, x9
LDP x6, x7, [sp], #16 // Recover x6, x7
LDP x4, x5, [sp], #16 // Recover x4, x5
LDP x2, x3, [sp], #16 // Recover x2, x3
LDP x0, x1, [sp], #16 // Recover x0, x1
LDP x29, x30, [sp], #16 // Recover x29, x30
ERET // Return to point of interrupt
/* }
else
{ */
__tx_thread_preempt_restore:
LDR x4, [x0, #8] // Switch to thread stack pointer
MOV sp, x4 //
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL1
STP x20, x21, [sp, #-16]! // Save x20, x21
STP x22, x23, [sp, #-16]! // Save x22, x23
STP x24, x25, [sp, #-16]! // Save x24, x25
STP x26, x27, [sp, #-16]! // Save x26, x27
STP x28, x29, [sp, #-16]! // Save x28, x29
#ifdef ENABLE_ARM_FP
LDR w3, [x0, #268] // Pickup FP enable flag
CMP w3, #0 // Is FP enabled?
B.EQ _skip_fp_save // No, skip FP save
STP q0, q1, [sp, #-32]! // Save q0, q1
STP q2, q3, [sp, #-32]! // Save q2, q3
STP q4, q5, [sp, #-32]! // Save q4, q5
STP q6, q7, [sp, #-32]! // Save q6, q7
STP q8, q9, [sp, #-32]! // Save q8, q9
STP q10, q11, [sp, #-32]! // Save q10, q11
STP q12, q13, [sp, #-32]! // Save q12, q13
STP q14, q15, [sp, #-32]! // Save q14, q15
STP q16, q17, [sp, #-32]! // Save q16, q17
STP q18, q19, [sp, #-32]! // Save q18, q19
STP q20, q21, [sp, #-32]! // Save q20, q21
STP q22, q23, [sp, #-32]! // Save q22, q23
STP q24, q25, [sp, #-32]! // Save q24, q25
STP q26, q27, [sp, #-32]! // Save q26, q27
STP q28, q29, [sp, #-32]! // Save q28, q29
STP q30, q31, [sp, #-32]! // Save q30, q31
MRS x2, FPSR // Pickup FPSR
MRS x3, FPCR // Pickup FPCR
STP x2, x3, [sp, #-16]! // Save FPSR, FPCR
_skip_fp_save:
#endif
STP x4, x5, [sp, #-16]! // Save x4 (SPSR_EL3), x5 (ELR_E3)
MOV x3, sp // Move sp into x3
STR x3, [x0, #8] // Save stack pointer in thread control
// block
LDR x3, =_tx_thread_system_stack_ptr // Pickup address of system stack
LDR x4, [x3, x8, LSL #3] // Pickup system stack pointer
MOV sp, x4 // Setup system stack pointer
/* Save the remaining time-slice and disable it. */
/* if (_tx_timer_time_slice)
{ */
LDR x3, =_tx_timer_time_slice // Pickup time-slice variable address
LDR w2, [x3, x8, LSL #2] // Pickup time-slice
CMP w2, #0 // Is it active?
B.EQ __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 w2, [x0, #36] // Save thread's time-slice
MOV w2, #0 // Clear value
STR w2, [x3, x8, LSL #2] // Disable global time-slice flag
/* } */
__tx_thread_dont_save_ts:
/* Clear the current task pointer. */
/* _tx_thread_current_ptr = TX_NULL; */
MOV x2, #0 // NULL value
STR x2, [x1, x8, LSL #3] // Clear current thread pointer
/* Set bit indicating this thread is ready for execution. */
MOV x2, #1 // Build ready flag
DMB ISH // Ensure that accesses to shared resource have completed
STR w2, [x0, #260] // Set thread's ready flag
/* Return to the scheduler. */
/* _tx_thread_schedule(); */
/* } */
__tx_thread_idle_system_restore:
/* Just return back to the scheduler! */
LDR x1, =_tx_thread_schedule // Build address for _tx_thread_schedule
#ifdef EL1
MSR ELR_EL1, x1 // Setup point of interrupt
// MOV x1, #0x4 // Setup EL1 return
// MSR spsr_el1, x1 // Move into SPSR
#else
#ifdef EL2
MSR ELR_EL2, x1 // Setup point of interrupt
// MOV x1, #0x8 // Setup EL2 return
// MSR spsr_el2, x1 // Move into SPSR
#else
MSR ELR_EL3, x1 // Setup point of interrupt
// MOV x1, #0xC // Setup EL3 return
// MSR spsr_el3, x1 // Move into SPSR
#endif
#endif
ERET // Return to scheduler
/* } */

View File

@@ -0,0 +1,236 @@
/**************************************************************************/
/* */
/* 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"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save Cortex-A5x-SMP/GHS */
/* 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)
{ */
.global _tx_thread_context_save
.type _tx_thread_context_save, @function
_tx_thread_context_save:
/* Upon entry to this routine, it is assumed that IRQ/FIQ interrupts are locked
out, x29 (frame pointer), x30 (link register) are saved, we are in the proper EL,
and all other registers are intact. */
/* Check for a nested interrupt condition. */
/* if (_tx_thread_system_state++)
{ */
STP x0, x1, [sp, #-16]! // Save x0, x1
STP x2, x3, [sp, #-16]! // Save x2, x3
/* Pickup the CPU ID. */
MRS x1, MPIDR_EL1 // Pickup the core ID
UBFX x1, x1, #0, #8 // Isolate and right justify core ID
LDR x3, =_tx_thread_system_state // Pickup address of system state var
LDR w2, [x3, x1, LSL #2] // Pickup system state
CMP w2, #0 // Is this the first interrupt?
B.EQ __tx_thread_not_nested_save // Yes, not a nested context save
/* Nested interrupt condition. */
ADD w2, w2, #1 // Increment the nested interrupt counter
STR w2, [x3, x1, LSL #2] // Store it back in the variable
/* Save the rest of the scratch registers on the stack and return to the
calling ISR. */
STP x4, x5, [sp, #-16]! // Save x4, x5
STP x6, x7, [sp, #-16]! // Save x6, x7
STP x8, x9, [sp, #-16]! // Save x8, x9
STP x10, x11, [sp, #-16]! // Save x10, x11
STP x12, x13, [sp, #-16]! // Save x12, x13
STP x14, x15, [sp, #-16]! // Save x14, x15
STP x16, x17, [sp, #-16]! // Save x16, x17
STP x18, x19, [sp, #-16]! // Save x18, x19
#ifdef EL1
MRS x0, SPSR_EL1 // Pickup SPSR
MRS x1, ELR_EL1 // Pickup ELR (point of interrupt)
#else
#ifdef EL2
MRS x0, SPSR_EL2 // Pickup SPSR
MRS x1, ELR_EL2 // Pickup ELR (point of interrupt)
#else
MRS x0, SPSR_EL3 // Pickup SPSR
MRS x1, ELR_EL3 // Pickup ELR (point of interrupt)
#endif
#endif
STP x0, x1, [sp, #-16]! // Save SPSR, ELR
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
STP x29, x30, [sp, #-16]! // Save x29, x30
BL _tx_execution_isr_enter // Call the ISR enter function
LDP x29, x30, [sp], #16 // Recover x29, x30
#endif
/* Return to the ISR. */
RET // Return to ISR
__tx_thread_not_nested_save:
/* } */
/* Otherwise, not nested, check to see if a thread was running. */
/* else if (_tx_thread_current_ptr)
{ */
ADD w2, w2, #1 // Increment the interrupt counter
STR w2, [x3, x1, LSL #2] // Store it back in the variable
LDR x2, =_tx_thread_current_ptr // Pickup address of current thread ptr
LDR x0, [x2, x1, LSL #3] // Pickup current thread pointer
CMP x0, #0 // Is it NULL?
B.EQ __tx_thread_idle_system_save // If so, interrupt occurred in
// scheduling loop - nothing needs saving!
/* Save minimal context of interrupted thread. */
STP x4, x5, [sp, #-16]! // Save x4, x5
STP x6, x7, [sp, #-16]! // Save x6, x7
STP x8, x9, [sp, #-16]! // Save x8, x9
STP x10, x11, [sp, #-16]! // Save x10, x11
STP x12, x13, [sp, #-16]! // Save x12, x13
STP x14, x15, [sp, #-16]! // Save x14, x15
STP x16, x17, [sp, #-16]! // Save x16, x17
STP x18, x19, [sp, #-16]! // Save x18, x19
#ifdef EL1
MRS x4, SPSR_EL1 // Pickup SPSR
MRS x5, ELR_EL1 // Pickup ELR (point of interrupt)
#else
#ifdef EL2
MRS x4, SPSR_EL2 // Pickup SPSR
MRS x5, ELR_EL2 // Pickup ELR (point of interrupt)
#else
MRS x4, SPSR_EL3 // Pickup SPSR
MRS x5, ELR_EL3 // Pickup ELR (point of interrupt)
#endif
#endif
STP x4, x5, [sp, #-16]! // Save SPSR, ELR
/* Save the current stack pointer in the thread's control block. */
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */
MOV x4, sp //
STR x4, [x0, #8] // Save thread stack pointer
/* Switch to the system stack. */
/* sp = _tx_thread_system_stack_ptr; */
LDR x3, =_tx_thread_system_stack_ptr // Pickup address of system stack
MRS x1, MPIDR_EL1 // Pickup the core ID
UBFX x1, x1, #0, #8 // Isolate and right justify core ID
LDR x4, [x3, x1, LSL #3] // Pickup system stack pointer
MOV sp, x4 // Setup system stack pointer
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
STP x29, x30, [sp, #-16]! // Save x29, x30
BL _tx_execution_isr_enter // Call the ISR enter function
LDP x29, x30, [sp], #16 // Recover x29, x30
#endif
RET // Return to caller
/* }
else
{ */
__tx_thread_idle_system_save:
/* Interrupt occurred in the scheduling loop. */
/* Not much to do here, just adjust the stack pointer, and return to IRQ
processing. */
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the ISR enter function to indicate an ISR is executing. */
STP x29, x30, [sp, #-16]! // Save x29, x30
BL _tx_execution_isr_enter // Call the ISR enter function
LDP x29, x30, [sp], #16 // Recover x29, x30
#endif
ADD sp, sp, #48 // Recover saved registers
RET // Continue IRQ processing
/* }
} */

View File

@@ -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"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fp_disable Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function disables the FP for the currently executing thread. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_fp_disable(VOID)
{
TX_THREAD *thread_ptr;
ULONG system_state;
/* Pickup the current thread pointer. */
TX_THREAD_GET_CURRENT(thread_ptr);
/* Get the system state. */
system_state = TX_THREAD_GET_SYSTEM_STATE();
/* Make sure it is not NULL. */
if (thread_ptr != TX_NULL)
{
/* Thread is running... make sure the call is from the thread context. */
if (system_state == 0)
{
/* Yes, now set the FP enable flag to false in the TX_THREAD structure. */
thread_ptr -> tx_thread_fp_enable = TX_FALSE;
}
}
}

View File

@@ -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"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_fp_enable Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function enabled the FP for the currently executing thread. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_fp_enable(VOID)
{
TX_THREAD *thread_ptr;
ULONG system_state;
/* Pickup the current thread pointer. */
TX_THREAD_GET_CURRENT(thread_ptr);
/* Get the system state. */
system_state = TX_THREAD_GET_SYSTEM_STATE();
/* Make sure it is not NULL. */
if (thread_ptr != TX_NULL)
{
/* Thread is running... make sure the call is from the thread context. */
if (system_state == 0)
{
/* Yes, now setup the FP enable flag in the TX_THREAD structure. */
thread_ptr -> tx_thread_fp_enable = TX_TRUE;
}
}
}

View File

@@ -0,0 +1,89 @@
/**************************************************************************/
/* */
/* 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"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control Cortex-A5x-SMP/GHS */
/* 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)
{ */
.global _tx_thread_interrupt_control
.type _tx_thread_interrupt_control, @function
_tx_thread_interrupt_control:
/* Pickup current interrupt lockout posture. */
MRS x1, DAIF // Pickup current interrupt posture
/* Apply the new interrupt posture. */
MSR DAIF, x0 // Set new interrupt posture
MOV x0, x1 // Setup return value
RET // Return to caller
/* } */

View File

@@ -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"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable Cortex-A5x-SMP/GHS */
/* 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)
{ */
.global _tx_thread_interrupt_disable
.type _tx_thread_interrupt_disable, @function
_tx_thread_interrupt_disable:
/* Pickup current interrupt lockout posture. */
MRS x0, DAIF // Pickup current interrupt lockout posture
/* Mask interrupts. */
MSR DAIFSet, 0x3 // Lockout interrupts
RET // Return to caller
/* } */

View File

@@ -0,0 +1,85 @@
/**************************************************************************/
/* */
/* 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"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_restore Cortex-A5x-SMP/GHS */
/* 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)
{ */
.global _tx_thread_interrupt_restore
.type _tx_thread_interrupt_restore, @function
_tx_thread_interrupt_restore:
/* Restore the old interrupt posture. */
MSR DAIF, x0 // Setup the old posture
RET // Return to caller
/* } */

View File

@@ -0,0 +1,254 @@
/**************************************************************************/
/* */
/* 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"
*/
/* .set ENABLE_ARM_FP,1 */
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function waits for a thread control block pointer to appear in */
/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
/* in the variable, the corresponding thread is resumed. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_kernel_enter ThreadX entry function */
/* _tx_thread_system_return Return to system from thread */
/* _tx_thread_context_restore Restore thread's context */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_schedule(VOID)
{ */
.global _tx_thread_schedule
.type _tx_thread_schedule, @function
_tx_thread_schedule:
/* Enable interrupts. */
MSR DAIFClr, 0x3 // Enable interrupts
/* Pickup the CPU ID. */
MRS x20, MPIDR_EL1 // Pickup the core ID
UBFX x20, x20, #0, #8 // Isolate and right justify core ID
/* Wait for a thread to execute. */
/* do
{ */
LDR x1, =_tx_thread_execute_ptr // Address of thread execute ptr
#ifdef TX_ENABLE_WFI
__tx_thread_schedule_loop:
MSR DAIFSet, 0x3 // Lockout interrupts
LDR x0, [x1, x20, LSL #3] // Pickup next thread to execute
CMP x0, #0 // Is it NULL?
B.NE _tx_thread_schedule_thread //
MSR DAIFClr, 0x3 // Enable interrupts
WFI //
B __tx_thread_schedule_loop // Keep looking for a thread
_tx_thread_schedule_thread:
#else
MSR DAIFSet, 0x3 // Lockout interrupts
LDR x0, [x1, x20, LSL #3] // Pickup next thread to execute
CMP x0, #0 // Is it NULL?
B.EQ _tx_thread_schedule // Keep looking for a thread
#endif
/* }
while(_tx_thread_execute_ptr == TX_NULL); */
/* Now make sure the thread's ready bit is set. */
MOV x3, #0 // Build clear value
LDR w2, [x0, #260] // Pickup the ready bit
CMP w2, #1 // Is it set?
B.NE _tx_thread_schedule // If not, restart the scheduling loop
STR w3, [x0, #260] // Clear the ready bit
DMB ISH //
/* Yes! We have a thread to execute. Lockout interrupts and
transfer control to it. */
/* Setup the current thread pointer. */
/* _tx_thread_current_ptr = _tx_thread_execute_ptr; */
LDR x1, =_tx_thread_current_ptr // Pickup address of current thread
STR x0, [x1, x20, LSL #3] // Setup current thread pointer
/* Increment the run count for this thread. */
/* _tx_thread_current_ptr -> tx_thread_run_count++; */
LDR w2, [x0, #4] // Pickup run counter
LDR w3, [x0, #36] // Pickup time-slice for this thread
ADD w2, w2, #1 // Increment thread run-counter
STR w2, [x0, #4] // Store the new run counter
/* Setup time-slice, if present. */
/* _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; */
LDR x2, =_tx_timer_time_slice // Pickup address of time slice
// variable
LDR x4, [x0, #8] // Switch stack pointers
MOV sp, x4 //
STR w3, [x2, x20, LSL #2] // Setup time-slice
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the thread entry function to indicate the thread is executing. */
MOV x19, x0 // Save x0
BL _tx_execution_thread_enter // Call the thread execution enter function
MOV x0, x19 // Restore x0
#endif
/* Switch to the thread's stack. */
/* sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr; */
/* Determine if an interrupt frame or a synchronous task suspension frame
is present. */
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL1
CMP x5, #0 // Check for synchronous context switch (ELR_EL1 = NULL)
B.EQ _tx_solicited_return
#ifdef EL1
MSR SPSR_EL1, x4 // Setup SPSR for return
MSR ELR_EL1, x5 // Setup point of interrupt
#else
#ifdef EL2
MSR SPSR_EL2, x4 // Setup SPSR for return
MSR ELR_EL2, x5 // Setup point of interrupt
#else
MSR SPSR_EL3, x4 // Setup SPSR for return
MSR ELR_EL3, x5 // Setup point of interrupt
#endif
#endif
#ifdef ENABLE_ARM_FP
LDR w1, [x0, #268] // Pickup FP enable flag
CMP w1, #0 // Is FP enabled?
B.EQ _skip_interrupt_fp_restore // No, skip FP restore
LDP x0, x1, [sp], #16 // Pickup FPSR, FPCR
MSR FPSR, x0 // Recover FPSR
MSR FPCR, x1 // Recover FPCR
LDP q30, q31, [sp], #32 // Recover q30, q31
LDP q28, q29, [sp], #32 // Recover q28, q29
LDP q26, q27, [sp], #32 // Recover q26, q27
LDP q24, q25, [sp], #32 // Recover q24, q25
LDP q22, q23, [sp], #32 // Recover q22, q23
LDP q20, q21, [sp], #32 // Recover q20, q21
LDP q18, q19, [sp], #32 // Recover q18, q19
LDP q16, q17, [sp], #32 // Recover q16, q17
LDP q14, q15, [sp], #32 // Recover q14, q15
LDP q12, q13, [sp], #32 // Recover q12, q13
LDP q10, q11, [sp], #32 // Recover q10, q11
LDP q8, q9, [sp], #32 // Recover q8, q9
LDP q6, q7, [sp], #32 // Recover q6, q7
LDP q4, q5, [sp], #32 // Recover q4, q5
LDP q2, q3, [sp], #32 // Recover q2, q3
LDP q0, q1, [sp], #32 // Recover q0, q1
_skip_interrupt_fp_restore:
#endif
LDP x28, x29, [sp], #16 // Recover x28
LDP x26, x27, [sp], #16 // Recover x26, x27
LDP x24, x25, [sp], #16 // Recover x24, x25
LDP x22, x23, [sp], #16 // Recover x22, x23
LDP x20, x21, [sp], #16 // Recover x20, x21
LDP x18, x19, [sp], #16 // Recover x18, x19
LDP x16, x17, [sp], #16 // Recover x16, x17
LDP x14, x15, [sp], #16 // Recover x14, x15
LDP x12, x13, [sp], #16 // Recover x12, x13
LDP x10, x11, [sp], #16 // Recover x10, x11
LDP x8, x9, [sp], #16 // Recover x8, x9
LDP x6, x7, [sp], #16 // Recover x6, x7
LDP x4, x5, [sp], #16 // Recover x4, x5
LDP x2, x3, [sp], #16 // Recover x2, x3
LDP x0, x1, [sp], #16 // Recover x0, x1
LDP x29, x30, [sp], #16 // Recover x29, x30
ERET // Return to point of interrupt
_tx_solicited_return:
#ifdef ENABLE_ARM_FP
LDR w1, [x0, #268] // Pickup FP enable flag
CMP w1, #0 // Is FP enabled?
B.EQ _skip_solicited_fp_restore // No, skip FP restore
LDP x0, x1, [sp], #16 // Pickup FPSR, FPCR
MSR FPSR, x0 // Recover FPSR
MSR FPCR, x1 // Recover FPCR
LDP q14, q15, [sp], #32 // Recover q14, q15
LDP q12, q13, [sp], #32 // Recover q12, q13
LDP q10, q11, [sp], #32 // Recover q10, q11
LDP q8, q9, [sp], #32 // Recover q8, q9
_skip_solicited_fp_restore:
#endif
LDP x27, x28, [sp], #16 // Recover x27, x28
LDP x25, x26, [sp], #16 // Recover x25, x26
LDP x23, x24, [sp], #16 // Recover x23, x24
LDP x21, x22, [sp], #16 // Recover x21, x22
LDP x19, x20, [sp], #16 // Recover x19, x20
LDP x29, x30, [sp], #16 // Recover x29, x30
MSR DAIF, x4 // Recover DAIF
RET // Return to caller
/* } */

View File

@@ -0,0 +1,83 @@
/**************************************************************************/
/* */
/* 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 - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
/*
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
*/
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_core_get Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function gets the currently running core number and returns it.*/
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Core ID */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ThreadX Source */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_core_get
.type _tx_thread_smp_core_get, @function
_tx_thread_smp_core_get:
MRS x0, MPIDR_EL1 // Pickup the core ID
UBFX x0, x0, #0, #8 // Isolate and right justify core ID
RET

View File

@@ -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 */
/** */
/** Thread - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
/*
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
*/
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_core_preempt Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function preempts the specified core in situations where the */
/* thread corresponding to this core is no longer ready or when the */
/* core must be used for a higher-priority thread. If the specified is */
/* the current core, this processing is skipped since the will give up */
/* control subsequently on its own. */
/* */
/* INPUT */
/* */
/* core The core to preempt */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ThreadX Source */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_core_preempt
.type _tx_thread_smp_core_preempt, @function
_tx_thread_smp_core_preempt:
DSB ISH
MRS x1, S3_1_C15_C3_0 // read CBAR
LDR x2, =0x10F00 // Build address of GICD_BASE+GICD_SGIR
ADD x1, x1, x2
MOV x2, #0x10000 // Software Interrupt 0
LSL x2, x2, x0 // Shift by the core ID
STR x2, [x1, #0] // Issue inter-core interrupt
RET

View File

@@ -0,0 +1,89 @@
/**************************************************************************/
/* */
/* 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 - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
/*
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
*/
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_current_state_get Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is gets the current state of the calling core. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ThreadX Components */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_current_state_get
.type _tx_thread_smp_current_state_get, @function
_tx_thread_smp_current_state_get:
MRS x1, DAIF // Pickup current interrupt posture
MSR DAIFSet, 0x3 // Lockout interrupts
MRS x2, MPIDR_EL1 // Pickup the core ID
UBFX x2, x2, #0, #8 // Isolate and right justify core ID
LDR x3, =_tx_thread_system_state // Pickup the base of the current system state array
LDR w0, [x3, x2, LSL #2] // Pickup the current system state for this core
MSR DAIF, x1 // Restore interrupt posture
RET

View File

@@ -0,0 +1,88 @@
/**************************************************************************/
/* */
/* 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 - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
/*
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
*/
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_current_thread_get Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is gets the current thread of the calling core. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ThreadX Components */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_current_thread_get
.type _tx_thread_smp_current_thread_get, @function
_tx_thread_smp_current_thread_get:
MRS x1, DAIF // Pickup current interrupt posture
MSR DAIFSet, 0x3 // Lockout interrupts
MRS x2, MPIDR_EL1 // Pickup the core ID
UBFX x2, x2, #0, #8 // Isolate and right justify core ID
LDR x3, =_tx_thread_current_ptr // Pickup the base of the current thread pointer array
LDR x0, [x3, x2, LSL #3] // Pickup the current thread pointer for this core
MSR DAIF, x1 // Restore interrupt posture
RET

View File

@@ -0,0 +1,137 @@
/**************************************************************************/
/* */
/* 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 - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
/*
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
*/
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_initialize_wait Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the place where additional cores wait until */
/* initialization is complete before they enter the thread scheduling */
/* loop. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_schedule Thread scheduling loop */
/* */
/* CALLED BY */
/* */
/* Hardware */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_initialize_wait
.type _tx_thread_smp_initialize_wait, @function
_tx_thread_smp_initialize_wait:
/* Lockout interrupts. */
MSR DAIFSet, 0x3 // Lockout interrupts
/* Pickup the Core ID. */
MRS x2, MPIDR_EL1 // Pickup the core ID
UBFX x2, x2, #0, #8 // Isolate and right justify core ID
/* Make sure the system state for this core is TX_INITIALIZE_IN_PROGRESS before we check the release
flag. */
LDR w1, =0xF0F0F0F0 // Build TX_INITIALIZE_IN_PROGRESS flag
LDR x3, =_tx_thread_system_state // Pickup the base of the current system state array
wait_for_initialize:
LDR w0, [x3, x2, LSL #2] // Pickup the current system state for this core
CMP w0, w1 // Make sure the TX_INITIALIZE_IN_PROGRESS flag is set
B.NE wait_for_initialize // Not equal, just spin here
/* Save the system stack pointer for this core. */
LDR x0, =_tx_thread_system_stack_ptr // Pickup address of system stack ptr
MOV x1, sp // Pickup SP
SUB x1, x1, #15 //
AND x1, x1, #~0xF // Get 16-bit alignment
STR x1, [x0, x2, LSL #3] // Store system stack pointer
/* Pickup the release cores flag. */
LDR x4, =_tx_thread_smp_release_cores_flag // Build address of release cores flag
wait_for_release:
LDR w0, [x4, #0] // Pickup the flag
CMP w0, #0 // Is it set?
B.EQ wait_for_release // Wait for the flag to be set
/* Core 0 has released this core. */
/* Clear this core's system state variable. */
MOV x0, #0 // Build clear value
STR w0, [x3, x2, LSL #2] // Set the current system state for this core to zero
/* Now wait for core 0 to finish it's initialization. */
core_0_wait_loop:
LDR w0, [x3, #0] // Pickup the current system state for core 0
CMP w0, #0 // Is it 0?
B.NE core_0_wait_loop // No, keep waiting for core 0 to finish its initialization
/* Initialization is complete, enter the scheduling loop! */
B _tx_thread_schedule // Enter the scheduling loop for this core
RET

View File

@@ -0,0 +1,80 @@
/**************************************************************************/
/* */
/* 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 - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
/*
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
*/
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_low_level_initialize Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function performs low-level initialization of the booting */
/* core. */
/* */
/* INPUT */
/* */
/* number_of_cores Number of cores */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_high_level ThreadX high-level init */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_low_level_initialize
.type _tx_thread_smp_low_level_initialize, @function
_tx_thread_smp_low_level_initialize:
RET

View File

@@ -0,0 +1,122 @@
/**************************************************************************/
/* */
/* 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 - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
/*
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
*/
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_protect Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function gets protection for running inside the ThreadX */
/* source. This is acomplished by a combination of a test-and-set */
/* flag and periodically disabling interrupts. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* Previous Status Register */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ThreadX Source */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_protect
.type _tx_thread_smp_protect, @function
_tx_thread_smp_protect:
MRS x0, DAIF // Pickup current interrupt posture
MSR DAIFSet, 0x3 // Lockout interrupts
/* Pickup the CPU ID. */
MRS x2, MPIDR_EL1 // Pickup the core ID
UBFX x2, x2, #0, #8 // Isolate and right justify core ID
LDR x1, =_tx_thread_smp_protection // Build address to protection structure
LDR w3, [x1, #4] // Pickup the owning core
CMP w3, w2 // Is it this core?
B.EQ _owned // Yes, the protection is already owned
LDAXR w4, [x1, #0] // Pickup the protection flag
CBZ w4, _get_protection // Yes, get the protection
MSR DAIF, x0 // Restore interrupts
ISB //
#ifdef TX_ENABLE_WFE
WFE // Go into standby
#endif
B _tx_thread_smp_protect // On waking, restart the protection attempt
_get_protection:
MOV x4, #1 // Build lock value
STXR w5, w4, [x1] // Attempt to get the protection
CBZ w5, _got_protection // Did it succeed? w5 = 0 means success!
MSR DAIF, x0 // Restore interrupts
B _tx_thread_smp_protect // Restart the protection attempt
_got_protection:
DMB ISH //
STR w2, [x1, #4] // Save owning core
_owned:
LDR w5, [x1, #8] // Pickup ownership count
ADD w5, w5, #1 // Increment ownership count
STR w5, [x1, #8] // Store ownership count
DMB ISH //
RET

View File

@@ -0,0 +1,83 @@
/**************************************************************************/
/* */
/* 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 - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
/*
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
*/
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_time_get Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function gets the global time value that is used for debug */
/* information and event tracing. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* 32-bit time stamp */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ThreadX Source */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_time_get
.type _tx_thread_smp_time_get, @function
_tx_thread_smp_time_get:
MOV x0, #0 // Add time source - application specific
RET

View File

@@ -0,0 +1,115 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread - Low Level SMP Support */
/** */
/**************************************************************************/
/**************************************************************************/
/*
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
*/
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_unprotect Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function releases previously obtained protection. The supplied */
/* previous SR is restored. If the value of _tx_thread_system_state */
/* and _tx_thread_preempt_disable are both zero, then multithreading */
/* is enabled as well. */
/* */
/* INPUT */
/* */
/* Previous Status Register */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* ThreadX Source */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
.global _tx_thread_smp_unprotect
.type _tx_thread_smp_unprotect, @function
_tx_thread_smp_unprotect:
MSR DAIFSet, 0x3 // Lockout interrupts
LDR x1,=_tx_thread_smp_protection // Build address of protection structure
MRS x8, MPIDR_EL1 // Pickup the core ID
UBFX x8, x8, #0, #8 // Isolate and right justify core ID
LDR w2, [x1, #4] // Pickup the owning core
CMP w2, w8 // Is it this core?
B.NE _still_protected // If this is not the owning core, protection is in force elsewhere
LDR w2, [x1, #8] // Pickup the protection count
CMP w2, #0 // Check to see if the protection is still active
B.EQ _still_protected // If the protection count is zero, protection has already been cleared
SUB w2, w2, #1 // Decrement the protection count
STR w2, [x1, #8] // Store the new count back
CMP w2, #0 // Check to see if the protection is still active
B.NE _still_protected // If the protection count is non-zero, protection is still in force
LDR x2,=_tx_thread_preempt_disable // Build address of preempt disable flag
LDR w3, [x2] // Pickup preempt disable flag
CMP w3, #0 // Is the preempt disable flag set?
B.NE _still_protected // Yes, skip the protection release
MOV x2, #0xFFFFFFFF // Build invalid value
STR w2, [x1, #4] // Mark the protected core as invalid
DMB ISH // Ensure that accesses to shared resource have completed
MOV x2, #0 // Build release protection value
STR w2, [x1, #0] // Release the protection
DSB ISH // To ensure update of the protection occurs before other CPUs awake
#ifdef TX_ENABLE_WFE
SEV // Send event to other CPUs, wakes anyone waiting on the protection (using WFE)
#endif
_still_protected:
SEV // Send event to other CPUs
MSR DAIF, x0 // Restore interrupt posture
RET

View File

@@ -0,0 +1,172 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build Cortex-A5x-SMP/GHS */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function builds a stack frame on the supplied thread's stack. */
/* The stack frame results in a fake interrupt return to the supplied */
/* function pointer. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to thread control blk */
/* function_ptr Pointer to return function */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_thread_create Create thread service */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
/* VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
{ */
.global _tx_thread_stack_build
.type _tx_thread_stack_build, @function
_tx_thread_stack_build:
/* Build a fake interrupt frame. The form of the fake interrupt stack
on the Cortex-A5x should look like the following after it is built:
Stack Top: SSPR Initial SSPR
ELR Point of interrupt
x28 Initial value for x28
not used Not used
x26 Initial value for x26
x27 Initial value for x27
x24 Initial value for x24
x25 Initial value for x25
x22 Initial value for x22
x23 Initial value for x23
x20 Initial value for x20
x21 Initial value for x21
x18 Initial value for x18
x19 Initial value for x19
x16 Initial value for x16
x17 Initial value for x17
x14 Initial value for x14
x15 Initial value for x15
x12 Initial value for x12
x13 Initial value for x13
x10 Initial value for x10
x11 Initial value for x11
x8 Initial value for x8
x9 Initial value for x9
x6 Initial value for x6
x7 Initial value for x7
x4 Initial value for x4
x5 Initial value for x5
x2 Initial value for x2
x3 Initial value for x3
x0 Initial value for x0
x1 Initial value for x1
x29 Initial value for x29 (frame pointer)
x30 Initial value for x30 (link register)
0 For stack backtracing
Stack Bottom: (higher memory address) */
LDR x4, [x0, #24] // Pickup end of stack area
AND x4, x4, #~0xF // Ensure 16-byte alignment
/* Actually build the stack frame. */
MOV x2, #0 // Build clear value
MOV x3, #0 //
STP x2, x3, [x4, #-16]! // Set backtrace to 0
STP x2, x3, [x4, #-16]! // Set initial x29, x30
STP x2, x3, [x4, #-16]! // Set initial x0, x1
STP x2, x3, [x4, #-16]! // Set initial x2, x3
STP x2, x3, [x4, #-16]! // Set initial x4, x5
STP x2, x3, [x4, #-16]! // Set initial x6, x7
STP x2, x3, [x4, #-16]! // Set initial x8, x9
STP x2, x3, [x4, #-16]! // Set initial x10, x11
STP x2, x3, [x4, #-16]! // Set initial x12, x13
STP x2, x3, [x4, #-16]! // Set initial x14, x15
STP x2, x3, [x4, #-16]! // Set initial x16, x17
STP x2, x3, [x4, #-16]! // Set initial x18, x19
STP x2, x3, [x4, #-16]! // Set initial x20, x21
STP x2, x3, [x4, #-16]! // Set initial x22, x23
STP x2, x3, [x4, #-16]! // Set initial x24, x25
STP x2, x3, [x4, #-16]! // Set initial x26, x27
STP x2, x3, [x4, #-16]! // Set initial x28
#ifdef EL1
MOV x2, #0x5 // Build initial SPSR (EL1)
#else
#ifdef EL2
MOV x2, #0x9 // Build initial SPSR (EL2)
#else
MOV x2, #0xD // Build initial SPSR (EL3)
#endif
#endif
MOV x3, x1 // Build initial ELR
STP x2, x3, [x4, #-16]! // Set initial SPSR & ELR
/* Setup stack pointer. */
/* thread_ptr -> tx_thread_stack_ptr = x2; */
STR x4, [x0, #8] // Save stack pointer in thread's
MOV x3, #1 // Build ready flag
STR w3, [x0, #260] // Set ready flag
RET // Return to caller
/* } */

View File

@@ -0,0 +1,187 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Thread */
/** */
/**************************************************************************/
/**************************************************************************/
/* #define TX_SOURCE_CODE */
/* Include necessary system files. */
/*
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_timer.h"
*/
/* .set ENABLE_ARM_FP,1 */
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return Cortex-A5x-SMP/GHS */
/* 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)
{ */
.global _tx_thread_system_return
.type _tx_thread_system_return, @function
_tx_thread_system_return:
;
; /* Save minimal context on the stack. */
;
MRS x0, DAIF // Pickup DAIF
MSR DAIFSet, 0x3 // Lockout interrupts
STP x29, x30, [sp, #-16]! // Save x29 (frame pointer), x30 (link register)
STP x19, x20, [sp, #-16]! // Save x19, x20
STP x21, x22, [sp, #-16]! // Save x21, x22
STP x23, x24, [sp, #-16]! // Save x23, x24
STP x25, x26, [sp, #-16]! // Save x25, x26
STP x27, x28, [sp, #-16]! // Save x27, x28
MRS x8, MPIDR_EL1 // Pickup the core ID
UBFX x8, x8, #0, #8 // Isolate and right justify core ID
LDR x5, =_tx_thread_current_ptr // Pickup address of current ptr
LDR x6, [x5, x8, LSL #3] // Pickup current thread pointer
#ifdef ENABLE_ARM_FP
LDR w7, [x6, #268] // Pickup FP enable flag
CMP w7, #0 // Is FP enabled?
B.EQ _skip_fp_save // No, skip FP save
STP q8, q9, [sp, #-32]! // Save q8, q9
STP q10, q11, [sp, #-32]! // Save q10, q11
STP q12, q13, [sp, #-32]! // Save q12, q13
STP q14, q15, [sp, #-32]! // Save q14, q15
MRS x2, FPSR // Pickup FPSR
MRS x3, FPCR // Pickup FPCR
STP x2, x3, [sp, #-16]! // Save FPSR, FPCR
_skip_fp_save:
#endif
MOV x1, #0 // Clear x1
STP x0, x1, [sp, #-16]! // Save DAIF and clear value for ELR_EK1
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
/* Call the thread exit function to indicate the thread is no longer executing. */
MOV x19, x5 // Save x5
MOV x20, x6 // Save x6
MOV x21, x8 // Save x2
BL _tx_execution_thread_exit // Call the thread exit function
MOV x8, x21 // Restore x2
MOV x5, x19 // Restore x5
MOV x6, x20 // Restore x6
#endif
LDR x2, =_tx_timer_time_slice // Pickup address of time slice
LDR w1, [x2, x8, LSL #2] // Pickup current time slice
/* Save current stack and switch to system stack. */
/* _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp; */
/* sp = _tx_thread_system_stack_ptr[core]; */
MOV x4, sp //
STR x4, [x6, #8] // Save thread stack pointer
LDR x3, =_tx_thread_system_stack_ptr // Pickup address of system stack
LDR x4, [x3, x8, LSL #3] // Pickup system stack pointer
MOV sp, x4 // Setup system stack pointer
/* Determine if the time-slice is active. */
/* if (_tx_timer_time_slice[core])
{ */
MOV x4, #0 // Build clear value
CMP w1, #0 // Is a time-slice active?
B.EQ __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 w4, [x2, x8, LSL #2] // Clear time-slice
STR w1, [x6, #36] // Store current time-slice
/* } */
__tx_thread_dont_save_ts:
/* Clear the current thread pointer. */
/* _tx_thread_current_ptr = TX_NULL; */
STR x4, [x5, x8, LSL #3] // Clear current thread pointer
/* Set ready bit in thread control block. */
MOV x3, #1 // Build ready value
STR w3, [x6, #260] // Make the thread ready
DMB ISH //
/* Now clear protection. It is assumed that protection is in force whenever this routine is called. */
LDR x3, =_tx_thread_smp_protection // Pickup address of protection structure
LDR x1, =_tx_thread_preempt_disable // Build address to preempt disable flag
STR w4, [x1, #0] // Clear preempt disable flag
STR w4, [x3, #8] // Cear protection count
MOV x1, #0xFFFFFFFF // Build invalid value
STR w1, [x3, #4] // Set core to an invalid value
DMB ISH // Ensure that accesses to shared resource have completed
STR w4, [x3, #0] // Clear protection
DSB ISH // To ensure update of the shared resource occurs before other CPUs awake
SEV // Send event to other CPUs, wakes anyone waiting on a mutex (using WFE)
B _tx_thread_schedule // Jump to scheduler!
/* } */

View File

@@ -0,0 +1,165 @@
/**************************************************************************/
/* */
/* 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"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_thread_timeout Cortex-A5x-SMP */
/* 6.1 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function handles thread timeout processing. Timeouts occur in */
/* two flavors, namely the thread sleep timeout and all other service */
/* call timeouts. Thread sleep timeouts are processed locally, while */
/* the others are processed by the appropriate suspension clean-up */
/* service. */
/* */
/* INPUT */
/* */
/* timeout_input Contains the thread pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* Suspension Cleanup Functions */
/* _tx_thread_system_resume Resume thread */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* */
/* CALLED BY */
/* */
/* _tx_timer_expiration_process Timer expiration function */
/* _tx_timer_thread_entry Timer thread function */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
/* */
/**************************************************************************/
VOID _tx_thread_timeout(ULONG timeout_input)
{
TX_INTERRUPT_SAVE_AREA
TX_THREAD *thread_ptr;
VOID (*suspend_cleanup)(struct TX_THREAD_STRUCT *suspend_thread_ptr, ULONG suspension_sequence);
ULONG suspension_sequence;
/* Pickup the thread pointer. */
TX_THREAD_TIMEOUT_POINTER_SETUP(thread_ptr)
/* Disable interrupts. */
TX_DISABLE
/* Determine how the thread is currently suspended. */
if (thread_ptr -> tx_thread_state == TX_SLEEP)
{
#ifdef TX_NOT_INTERRUPTABLE
/* Resume the thread! */
_tx_thread_system_ni_resume(thread_ptr);
/* Restore interrupts. */
TX_RESTORE
#else
/* Increment the disable preemption flag. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Lift the suspension on the sleeping thread. */
_tx_thread_system_resume(thread_ptr);
#endif
}
else
{
/* Process all other suspension timeouts. */
#ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO
/* Increment the total number of thread timeouts. */
_tx_thread_performance_timeout_count++;
/* Increment the number of timeouts for this thread. */
thread_ptr -> tx_thread_performance_timeout_count++;
#endif
/* Pickup the cleanup routine address. */
suspend_cleanup = thread_ptr -> tx_thread_suspend_cleanup;
#ifndef TX_NOT_INTERRUPTABLE
/* Pickup the suspension sequence number that is used later to verify that the
cleanup is still necessary. */
suspension_sequence = thread_ptr -> tx_thread_suspension_sequence;
#else
/* When not interruptable is selected, the suspension sequence is not used - just set to 0. */
suspension_sequence = ((ULONG) 0);
#endif
#ifndef TX_NOT_INTERRUPTABLE
/* Restore interrupts. */
TX_RESTORE
#endif
/* Call any cleanup routines. */
if (suspend_cleanup != TX_NULL)
{
/* Yes, there is a function to call. */
(suspend_cleanup)(thread_ptr, suspension_sequence);
}
#ifdef TX_NOT_INTERRUPTABLE
/* Restore interrupts. */
TX_RESTORE
#endif
}
}

View File

@@ -0,0 +1,193 @@
/**************************************************************************/
/* */
/* 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"
*/
.text
.align 3
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt Cortex-A5x-SMP/GHS */
/* 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)
{ */
.global _tx_timer_interrupt
.type _tx_timer_interrupt, @function
_tx_timer_interrupt:
MRS x2, MPIDR_EL1 // Pickup the core ID
UBFX x2, x2, #0, #8 // Isolate and right justify core ID
CMP x2, #0 // Is this core 0?
B.EQ __tx_process_timer // If desired core, continue processing
RET // Simply return if different core
__tx_process_timer:
/* 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. */
STP x27, x28, [sp, #-16]! // Save x27, x28
STP x29, x30, [sp, #-16]! // Save x29 (frame pointer), x30 (link register)
/* Get inter-core protection. */
BL _tx_thread_smp_protect // Get inter-core protection
MOV x28, x0 // Save the return value in preserved register
/* Increment the system clock. */
/* _tx_timer_system_clock++; */
LDR x1, =_tx_timer_system_clock // Pickup address of system clock
LDR w0, [x1, #0] // Pickup system clock
ADD w0, w0, #1 // Increment system clock
STR w0, [x1, #0] // Store new system clock
/* Test for timer expiration. */
/* if (*_tx_timer_current_ptr)
{ */
LDR x1, =_tx_timer_current_ptr // Pickup current timer pointer addr
LDR x0, [x1, #0] // Pickup current timer
LDR x2, [x0, #0] // Pickup timer list entry
CMP x2, #0 // Is there anything in the list?
B.EQ __tx_timer_no_timer // No, just increment the timer
/* Set expiration flag. */
/* _tx_timer_expired = TX_TRUE; */
LDR x3, =_tx_timer_expired // Pickup expiration flag address
MOV w2, #1 // Build expired value
STR w2, [x3, #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 x0, x0, #8 // Move to next timer
/* Check for wrap-around. */
/* if (_tx_timer_current_ptr == _tx_timer_list_end) */
LDR x3, =_tx_timer_list_end // Pickup addr of timer list end
LDR x2, [x3, #0] // Pickup list end
CMP x0, x2 // Are we at list end?
B.NE __tx_timer_skip_wrap // No, skip wrap-around logic
/* Wrap to beginning of list. */
/* _tx_timer_current_ptr = _tx_timer_list_start; */
LDR x3, =_tx_timer_list_start // Pickup addr of timer list start
LDR x0, [x3, #0] // Set current pointer to list start
__tx_timer_skip_wrap:
STR x0, [x1, #0] // Store new current timer pointer
/* } */
__tx_timer_done:
/* Did a timer expire? */
/* if (_tx_timer_expired)
{ */
LDR x1, =_tx_timer_expired // Pickup addr of expired flag
LDR w0, [x1, #0] // Pickup timer expired flag
CMP w0, #0 // Check for timer expiration
B.EQ __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:
/* Call time-slice processing. */
/* _tx_thread_time_slice(); */
BL _tx_thread_time_slice // Call time-slice processing
/* Release inter-core protection. */
MOV x0, x28 // Pass the previous status register back
BL _tx_thread_smp_unprotect // Release protection
LDP x29, x30, [sp], #16 // Recover x29, x30
LDP x27, x28, [sp], #16 // Recover x27, x28
RET // Return to caller
/* } */

View File

@@ -0,0 +1,88 @@
/*
* ThreadX API Runtime Error Support
*
* Copyright 1983-2019 Green Hills Software LLC.
*
* This program is the property of Green Hills Software LLC.,
* its contents are proprietary information and no part of it
* is to be disclosed to anyone except employees of Green Hills
* Software LLC., or as agreed in writing signed by the President
* of Green Hills Software LLC.
*/
/* #include "tx_ghs.h" */
#ifndef TX_DISABLE_ERROR_CHECKING
#define TX_DISABLE_ERROR_CHECKING
#endif
#include "tx_api.h"
/* Customized ThreadX API runtime error support routine. */
void _rnerr(int num, int linenum, const char*str, void*ptr, ...);
/* __ghs_rnerr()
This is the custom runtime error checking routine.
This implementation uses the existing __rnerr() routine.
Another implementation could use the .syscall mechanism,
provided MULTI was modified to understand that.
*/
void __ghs_rnerr(char *errMsg, int stackLevels, int stackTraceDisplay, void *hexVal) {
TX_INTERRUPT_SAVE_AREA
int num;
/*
Initialize the stack levels value.
Add 3 to account for the calls to _rnerr, __rnerr, and
__ghs_rnerr.
If the implementation changes, calls to __ghs_rnerr
will not need to be changed.
Zero is not permitted, so substitute 3 in that case.
*/
num = (stackLevels+3) & 0xf;
if (!num) {
num = 3;
}
/*
Shift the stack levels value to bits 12..15 and
insert the stack trace display value in bit 11.
Bits 0..10 are unused.
*/
num = (num << 12) | (stackTraceDisplay ? 0x800 : 0);
/* This will mask all interrupts in the RTEC code, which is probably
unacceptable for many targets. */
TX_DISABLE
_rnerr(num, -1, (const char *)hexVal, (void *)errMsg);
TX_RESTORE
}
/* ThreadX thread stack checking runtime support routine. */
extern char __ghsbegin_stack[];
void __stkchk(void) {
int i;
TX_THREAD *current_thread_ptr;
/* Pickup current thread pointer. */
TX_THREAD_GET_CURRENT(current_thread_ptr)
if(current_thread_ptr)
{
if((unsigned)(&i) <=
(unsigned)(current_thread_ptr -> tx_thread_stack_start))
{
_rnerr(21, -1, 0, 0);
}
}
else
{
if((unsigned)(&i) <= (unsigned)__ghsbegin_stack)
{
_rnerr(21, -1, 0, 0);
}
}
}