6.1 minor release
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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) {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#!gbuild
|
||||
macro __BINDIR=%expand_path(bin/debug)
|
||||
[Build Configuration]
|
||||
-G
|
||||
-Odebug
|
||||
-object_dir=objs/debug
|
||||
:outputDir=objs/debug
|
||||
:binDir=${__BINDIR}
|
||||
16
ports_smp/cortex_a5x_smp/green/example_build/tgt/default.con
Normal file
16
ports_smp/cortex_a5x_smp/green/example_build/tgt/default.con
Normal 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"
|
||||
@@ -0,0 +1,9 @@
|
||||
#!gbuild
|
||||
macro __BINDIR=%expand_path(bin/release)
|
||||
[Build Configuration]
|
||||
-G
|
||||
-O
|
||||
-object_dir=objs/release
|
||||
:outputDir=objs/release
|
||||
:binDir=${__BINDIR}
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
235
ports_smp/cortex_a5x_smp/green/example_build/tx/libtx.gpj
Normal file
235
ports_smp/cortex_a5x_smp/green/example_build/tx/libtx.gpj
Normal 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
|
||||
764
ports_smp/cortex_a5x_smp/green/inc/tx_el.h
Normal file
764
ports_smp/cortex_a5x_smp/green/inc/tx_el.h
Normal 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
|
||||
|
||||
77
ports_smp/cortex_a5x_smp/green/inc/tx_ghs.h
Normal file
77
ports_smp/cortex_a5x_smp/green/inc/tx_ghs.h
Normal 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_ */
|
||||
452
ports_smp/cortex_a5x_smp/green/inc/tx_port.h
Normal file
452
ports_smp/cortex_a5x_smp/green/inc/tx_port.h
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
264
ports_smp/cortex_a5x_smp/green/readme_threadx.txt
Normal file
264
ports_smp/cortex_a5x_smp/green/readme_threadx.txt
Normal 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
|
||||
|
||||
1166
ports_smp/cortex_a5x_smp/green/src/tx_el.c
Normal file
1166
ports_smp/cortex_a5x_smp/green/src/tx_el.c
Normal file
File diff suppressed because it is too large
Load Diff
502
ports_smp/cortex_a5x_smp/green/src/tx_ghs.c
Normal file
502
ports_smp/cortex_a5x_smp/green/src/tx_ghs.c
Normal 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 */
|
||||
162
ports_smp/cortex_a5x_smp/green/src/tx_initialize_low_level.a64
Normal file
162
ports_smp/cortex_a5x_smp/green/src/tx_initialize_low_level.a64
Normal 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
|
||||
317
ports_smp/cortex_a5x_smp/green/src/tx_thread_context_restore.a64
Normal file
317
ports_smp/cortex_a5x_smp/green/src/tx_thread_context_restore.a64
Normal 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
|
||||
/* } */
|
||||
|
||||
|
||||
236
ports_smp/cortex_a5x_smp/green/src/tx_thread_context_save.a64
Normal file
236
ports_smp/cortex_a5x_smp/green/src/tx_thread_context_save.a64
Normal 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
|
||||
|
||||
/* }
|
||||
} */
|
||||
|
||||
|
||||
95
ports_smp/cortex_a5x_smp/green/src/tx_thread_fp_disable.c
Normal file
95
ports_smp/cortex_a5x_smp/green/src/tx_thread_fp_disable.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
95
ports_smp/cortex_a5x_smp/green/src/tx_thread_fp_enable.c
Normal file
95
ports_smp/cortex_a5x_smp/green/src/tx_thread_fp_enable.c
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/* } */
|
||||
|
||||
@@ -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
|
||||
/* } */
|
||||
|
||||
@@ -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
|
||||
|
||||
/* } */
|
||||
|
||||
254
ports_smp/cortex_a5x_smp/green/src/tx_thread_schedule.a64
Normal file
254
ports_smp/cortex_a5x_smp/green/src/tx_thread_schedule.a64
Normal 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
|
||||
/* } */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
122
ports_smp/cortex_a5x_smp/green/src/tx_thread_smp_protect.a64
Normal file
122
ports_smp/cortex_a5x_smp/green/src/tx_thread_smp_protect.a64
Normal 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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
115
ports_smp/cortex_a5x_smp/green/src/tx_thread_smp_unprotect.a64
Normal file
115
ports_smp/cortex_a5x_smp/green/src/tx_thread_smp_unprotect.a64
Normal 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
|
||||
|
||||
172
ports_smp/cortex_a5x_smp/green/src/tx_thread_stack_build.a64
Normal file
172
ports_smp/cortex_a5x_smp/green/src/tx_thread_stack_build.a64
Normal 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
|
||||
|
||||
/* } */
|
||||
|
||||
|
||||
187
ports_smp/cortex_a5x_smp/green/src/tx_thread_system_return.a64
Normal file
187
ports_smp/cortex_a5x_smp/green/src/tx_thread_system_return.a64
Normal 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!
|
||||
|
||||
/* } */
|
||||
|
||||
|
||||
165
ports_smp/cortex_a5x_smp/green/src/tx_thread_timeout.c
Normal file
165
ports_smp/cortex_a5x_smp/green/src/tx_thread_timeout.c
Normal 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
|
||||
}
|
||||
}
|
||||
|
||||
193
ports_smp/cortex_a5x_smp/green/src/tx_timer_interrupt.a64
Normal file
193
ports_smp/cortex_a5x_smp/green/src/tx_timer_interrupt.a64
Normal 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
|
||||
|
||||
/* } */
|
||||
|
||||
|
||||
88
ports_smp/cortex_a5x_smp/green/src/txr_ghs.c
Normal file
88
ports_smp/cortex_a5x_smp/green/src/txr_ghs.c
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user