Release 6.1.9
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.1337922098" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-A35.AArch64.ARMv8.Neon.Crypto" valueType="string"/>
|
||||
|
||||
<option id="com.arm.toolchain.v6.base.options.debug.level.1596377417" superClass="com.arm.toolchain.v6.base.options.debug.level" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
<option id="com.arm.toolchain.v6.base.options.debug.level.1596377417" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
|
||||
|
||||
<targetPlatform id="com.arm.toolchain.v6.base.var.arm_compiler_6-6.1592753597.2060144338" name=""/>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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,
|
||||
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
@@ -104,41 +104,41 @@ CHAR *pointer = TX_NULL;
|
||||
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,
|
||||
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
|
||||
/* 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,
|
||||
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,
|
||||
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.
|
||||
/* 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,
|
||||
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,
|
||||
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. */
|
||||
@@ -146,23 +146,23 @@ CHAR *pointer = TX_NULL;
|
||||
|
||||
/* 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,
|
||||
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,
|
||||
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,
|
||||
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. */
|
||||
@@ -264,11 +264,11 @@ UINT status;
|
||||
/* 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
|
||||
/* 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++;
|
||||
}
|
||||
@@ -327,7 +327,7 @@ ULONG actual_flags;
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
@@ -380,7 +380,7 @@ UINT status;
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
|
||||
@@ -328,7 +328,7 @@ el1_entry_aarch64:
|
||||
//
|
||||
// Cortex-A processors automatically invalidate their caches on reset
|
||||
// (unless suppressed with the DBGL1RSTDISABLE or L2RSTDISABLE pins).
|
||||
// It is therefore not necessary for software to invalidate the caches
|
||||
// It is therefore not necessary for software to invalidate the caches
|
||||
// on startup, however, this is done here in case of a warm reset.
|
||||
bl InvalidateUDCaches
|
||||
tlbi VMALLE1
|
||||
@@ -800,4 +800,4 @@ __user_setup_stackheap:
|
||||
ADRP X0, Image$$ARM_LIB_HEAP$$ZI$$Base
|
||||
ADRP X2, Image$$ARM_LIB_HEAP$$ZI$$Limit
|
||||
RET
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* This is a small demo of the high-performance ThreadX kernel running as a module. It includes
|
||||
examples of eight threads of different priorities, using a message queue, semaphore, mutex,
|
||||
/* This is a small demo of the high-performance ThreadX kernel running as a module. It includes
|
||||
examples of eight threads of different priorities, using a message queue, semaphore, mutex,
|
||||
event flags group, byte pool, and block pool. */
|
||||
|
||||
/* Specify that this is a module! */
|
||||
@@ -20,7 +20,7 @@
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the pool space in the bss section of the module. ULONG is used to
|
||||
/* Define the pool space in the bss section of the module. ULONG is used to
|
||||
get the word alignment. */
|
||||
|
||||
ULONG demo_module_pool_space[DEMO_BYTE_POOL_SIZE / sizeof(ULONG)];
|
||||
@@ -103,7 +103,7 @@ CHAR *pointer;
|
||||
|
||||
|
||||
/* Allocate all the objects. In MMU mode, modules cannot allocate control blocks within
|
||||
their own memory area so they cannot corrupt the resident portion of ThreadX by overwriting
|
||||
their own memory area so they cannot corrupt the resident portion of ThreadX by overwriting
|
||||
the control block(s). */
|
||||
status = txm_module_object_allocate((void*)&thread_0, sizeof(TX_THREAD));
|
||||
while (status != TX_SUCCESS);
|
||||
@@ -133,7 +133,7 @@ CHAR *pointer;
|
||||
while (status != TX_SUCCESS);
|
||||
status = txm_module_object_allocate((void*)&block_pool_0, sizeof(TX_BLOCK_POOL));
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
status = tx_byte_pool_create(byte_pool_0, "module byte pool 0", demo_module_pool_space, DEMO_BYTE_POOL_SIZE);
|
||||
@@ -193,7 +193,7 @@ CHAR *pointer;
|
||||
|
||||
/* Create the main thread. */
|
||||
status = tx_thread_create(thread_0, "module thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -201,11 +201,11 @@ CHAR *pointer;
|
||||
status = tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
/* Create threads 1 and 2. These threads pass information through a ThreadX
|
||||
/* 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. */
|
||||
status = tx_thread_create(thread_1, "module thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -214,7 +214,7 @@ CHAR *pointer;
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
status = tx_thread_create(thread_2, "module thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -222,10 +222,10 @@ CHAR *pointer;
|
||||
status = tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
|
||||
/* 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. */
|
||||
status = tx_thread_create(thread_3, "module thread 3", thread_3_and_4_entry, 3,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -234,7 +234,7 @@ CHAR *pointer;
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
status = tx_thread_create(thread_4, "module thread 4", thread_3_and_4_entry, 4,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -245,7 +245,7 @@ CHAR *pointer;
|
||||
/* Create thread 5. This thread simply pends on an event flag which will be set
|
||||
by thread_0. */
|
||||
status = tx_thread_create(thread_5, "module thread 5", thread_5_entry, 5,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -255,7 +255,7 @@ CHAR *pointer;
|
||||
|
||||
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
|
||||
status = tx_thread_create(thread_6, "module thread 6", thread_6_and_7_entry, 6,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -264,7 +264,7 @@ CHAR *pointer;
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
status = tx_thread_create(thread_7, "module thread 7", thread_6_and_7_entry, 7,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
}
|
||||
@@ -276,7 +276,7 @@ void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sits in while-forever-sleep loop. */
|
||||
while(1)
|
||||
{
|
||||
@@ -286,7 +286,7 @@ UINT status;
|
||||
|
||||
/* 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);
|
||||
|
||||
@@ -338,11 +338,11 @@ UINT status;
|
||||
/* 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
|
||||
/* 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++;
|
||||
}
|
||||
@@ -401,7 +401,7 @@ ULONG actual_flags;
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
status = tx_event_flags_get(event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
@@ -454,7 +454,7 @@ UINT status;
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(mutex_0);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.text
|
||||
.align 4
|
||||
.section Init
|
||||
|
||||
|
||||
// External references
|
||||
.global _txm_module_thread_shell_entry
|
||||
.global _txm_module_callback_request_thread_entry
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.force.preproc.70495432" superClass="com.arm.tool.assembler.v6.base.option.force.preproc" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.force.preproc.70495432" name="Preprocess input files (-x assembler-with-cpp)" superClass="com.arm.tool.assembler.v6.base.option.force.preproc" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.1024953339" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ void module_manager_entry(ULONG thread_input)
|
||||
|
||||
/* Load the module with absolute address linkage, in this example it is placed there by the multiple image download. */
|
||||
txm_module_manager_absolute_load(&my_module, "my module", (void *) MODULE_CODE);
|
||||
|
||||
|
||||
/* Start the module. */
|
||||
txm_module_manager_start(&my_module);
|
||||
|
||||
@@ -127,10 +127,10 @@ void module_manager_entry(ULONG thread_input)
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Stop the module. */
|
||||
txm_module_manager_stop(&my_module);
|
||||
|
||||
|
||||
/* Unload the module. */
|
||||
txm_module_manager_unload(&my_module);
|
||||
|
||||
@@ -139,11 +139,11 @@ void module_manager_entry(ULONG thread_input)
|
||||
|
||||
/* Start the module again. */
|
||||
txm_module_manager_start(&my_module);
|
||||
|
||||
|
||||
/* Now just spin... */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ el1_entry_aarch64:
|
||||
//
|
||||
// Cortex-A processors automatically invalidate their caches on reset
|
||||
// (unless suppressed with the DBGL1RSTDISABLE or L2RSTDISABLE pins).
|
||||
// It is therefore not necessary for software to invalidate the caches
|
||||
// It is therefore not necessary for software to invalidate the caches
|
||||
// on startup, however, this is done here in case of a warm reset.
|
||||
bl InvalidateUDCaches
|
||||
tlbi VMALLE1
|
||||
@@ -800,4 +800,4 @@ __user_setup_stackheap:
|
||||
ADRP X0, Image$$ARM_LIB_HEAP$$ZI$$Base
|
||||
ADRP X2, Image$$ARM_LIB_HEAP$$ZI$$Limit
|
||||
RET
|
||||
|
||||
|
||||
|
||||
@@ -200,78 +200,6 @@
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.lib.release.base.597173224">
|
||||
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.release.base.597173224" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
|
||||
<externalSettings/>
|
||||
|
||||
<extensions>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
|
||||
</extensions>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
|
||||
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.lib.release.base.597173224" name="Release" parent="com.arm.eclipse.build.config.v6.lib.release.base">
|
||||
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.lib.release.base.597173224." name="/" resourcePath="">
|
||||
|
||||
<toolChain id="com.arm.toolchain.v6.lib.release.base.var.arm_compiler_6-6.1176479246" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.lib.release.base.var.arm_compiler_6-6">
|
||||
|
||||
<targetPlatform id="com.arm.toolchain.v6.lib.release.base.var.arm_compiler_6-6.1176479246.1337532818" name=""/>
|
||||
|
||||
<builder autoBuildTarget="all" buildPath="${workspace_loc:/tx}/Release" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.1329350735" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="false" superClass="com.arm.toolchain.v6.builder"/>
|
||||
|
||||
<tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.599090274" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.optlevel.1379419239" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.optlevel.high" valueType="enumerated"/>
|
||||
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1827794426" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.681809063" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.optlevel.1575069010" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.optlevel.high" valueType="enumerated"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.541732194" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.1308655066" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
</tool>
|
||||
|
||||
<tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.1174783096" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
<tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.121864210" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
|
||||
|
||||
</toolChain>
|
||||
|
||||
</folderInfo>
|
||||
|
||||
<sourceEntries>
|
||||
|
||||
<entry excluding="src_generic/tx_misra.c|src_generic/tx_thread_timeout.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
|
||||
</cconfiguration>
|
||||
|
||||
</storageModule>
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
|
||||
</option>
|
||||
|
||||
<option id="com.arm.tool.assembler.v6.base.option.force.preproc.2015328324" superClass="com.arm.tool.assembler.v6.base.option.force.preproc" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.force.preproc.2015328324" name="Preprocess input files (-x assembler-with-cpp)" superClass="com.arm.tool.assembler.v6.base.option.force.preproc" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.1847017761" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h Cortex-A35-SMP/AC6 */
|
||||
/* 6.1.3 */
|
||||
/* 6.1.9 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
@@ -48,6 +48,9 @@
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 12-31-2020 Andres Mlinar Initial Version 6.1.3 */
|
||||
/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
/* symbol ULONG64_DEFINED, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -152,7 +155,7 @@ typedef unsigned int ULONG;
|
||||
typedef unsigned long long ULONG64;
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
|
||||
#define ULONG64_DEFINED
|
||||
|
||||
/* Override the alignment type to use 64-bit alignment and storage for pointers. */
|
||||
|
||||
@@ -441,7 +444,7 @@ VOID tx_thread_fp_disable(VOID);
|
||||
|
||||
#ifdef TX_THREAD_INIT
|
||||
CHAR _tx_version_id[] =
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Modules Cortex-A35-SMP/AC6 Version 6.1.3 *";
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Modules Cortex-A35-SMP/AC6 Version 6.1.9 *";
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
|
||||
@@ -274,6 +274,6 @@ ALIGN_TYPE _txm_module_manager_port_dispatch(TXM_MODULE_INSTANCE *module_instanc
|
||||
|
||||
#define TXM_MODULE_MANAGER_VERSION_ID \
|
||||
CHAR _txm_module_manager_version_id[] = \
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A35/AC6 Version 6.1.3 *";
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A35/AC6 Version 6.1.9 *";
|
||||
|
||||
#endif
|
||||
|
||||
@@ -121,7 +121,7 @@ VOID (*entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT type);
|
||||
An error here typically indicates the resident portion of _tx_thread_schedule
|
||||
is not supporting the trap to obtain the function pointer. */
|
||||
}
|
||||
|
||||
|
||||
/* Resume the module's callback thread, already created in the manager. */
|
||||
_txe_thread_resume(thread_info -> txm_module_thread_entry_info_callback_request_thread);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_smp_core_get Cortex-A35-SMP/AC6 */
|
||||
/* 6.1 */
|
||||
/* 6.1.9 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -58,17 +58,28 @@
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 10-15-2021 Andres Mlinar Updated comments, */
|
||||
/* added ARMv8.2-A support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
RET
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_smp_protect Cortex-A35-SMP/AC6 */
|
||||
/* 6.1 */
|
||||
/* 6.1.9 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -64,6 +64,10 @@
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 10-15-2021 Andres Mlinar Updated comments, */
|
||||
/* added ARMv8.2-A support, */
|
||||
/* improved SMP code, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.global _tx_thread_smp_protect
|
||||
@@ -78,10 +82,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
|
||||
@@ -163,7 +174,7 @@ _list_not_empty:
|
||||
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
|
||||
// {
|
||||
|
||||
LDR w3, [x2, #0] // Pickup the protection flag
|
||||
LDAXR w3, [x2, #0] // Pickup the protection flag
|
||||
CMP w3, #0
|
||||
BNE _start_waiting // No, protection not available
|
||||
|
||||
@@ -171,7 +182,9 @@ _list_not_empty:
|
||||
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
|
||||
|
||||
MOV w3, #1 // Build lock value
|
||||
STR w3, [x2, #0] // Store lock value
|
||||
STXR w4, w3, [x2, #0] // Attempt to get the protection
|
||||
CMP w4, #0
|
||||
BNE _start_waiting // Did it fail?
|
||||
DMB ISH //
|
||||
|
||||
/* Got the lock. */
|
||||
@@ -217,7 +230,7 @@ _already_in_list0:
|
||||
/* Restore interrupts. */
|
||||
|
||||
MSR DAIF, x0 // Restore interrupts
|
||||
ISB //
|
||||
ISB //
|
||||
#ifdef TX_ENABLE_WFE
|
||||
WFE // Go into standby
|
||||
#endif
|
||||
@@ -236,10 +249,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
|
||||
@@ -257,7 +277,7 @@ _try_to_get_lock:
|
||||
|
||||
/* Are we at the front of the list? */
|
||||
// if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
|
||||
// {/
|
||||
// {
|
||||
|
||||
LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
|
||||
LDR w3, [x3] // Get the value of the head
|
||||
@@ -271,7 +291,7 @@ _try_to_get_lock:
|
||||
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
|
||||
// {
|
||||
|
||||
LDR w3, [x2, #0] // Pickup the protection flag
|
||||
LDAXR w3, [x2, #0] // Pickup the protection flag
|
||||
CMP w3, #0
|
||||
BNE _did_not_get_lock // No, protection not available
|
||||
|
||||
@@ -279,7 +299,9 @@ _try_to_get_lock:
|
||||
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
|
||||
|
||||
MOV w3, #1 // Build lock value
|
||||
STR w3, [x2, #0] // Store lock value
|
||||
STXR w4, w3, [x2, #0] // Attempt to get the protection
|
||||
CMP w4, #0
|
||||
BNE _did_not_get_lock // Did it fail?
|
||||
DMB ISH //
|
||||
|
||||
/* Got the lock. */
|
||||
@@ -328,7 +350,7 @@ _already_in_list1:
|
||||
/* Restore interrupts and try again. */
|
||||
|
||||
MSR DAIF, x0 // Restore interrupts
|
||||
ISB //
|
||||
ISB //
|
||||
#ifdef TX_ENABLE_WFE
|
||||
WFE // Go into standby
|
||||
#endif
|
||||
@@ -349,4 +371,3 @@ _got_lock_after_waiting:
|
||||
_return:
|
||||
|
||||
RET
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
.macro _tx_thread_smp_protect_lock_got
|
||||
|
||||
/* Set the currently owned core. */
|
||||
/* _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core; */
|
||||
// _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
|
||||
|
||||
STR w1, [x2, #4] // Store this core
|
||||
|
||||
/* Increment the protection count. */
|
||||
/* _tx_thread_smp_protection.tx_thread_smp_protect_count++; */
|
||||
// _tx_thread_smp_protection.tx_thread_smp_protect_count++;
|
||||
|
||||
LDR w3, [x2, #8] // Pickup ownership count
|
||||
ADD w3, w3, #1 // Increment ownership count
|
||||
@@ -40,7 +40,7 @@
|
||||
.macro _tx_thread_smp_protect_remove_from_front_of_list
|
||||
|
||||
/* Remove ourselves from the list. */
|
||||
/* _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF; */
|
||||
// _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF;
|
||||
|
||||
MOV w3, #0xFFFFFFFF // Build the invalid core value
|
||||
LDR x4, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
|
||||
@@ -50,53 +50,55 @@
|
||||
ADD w5, w5, #1 // Increment the head
|
||||
|
||||
/* Did we wrap? */
|
||||
/* if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
|
||||
{ */
|
||||
// if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
|
||||
// {
|
||||
|
||||
LDR x3, =_tx_thread_smp_protect_wait_list_size // Load address of core list size
|
||||
LDR w3, [x3] // Load the max cores value
|
||||
CMP w5, w3 // Compare the head to it
|
||||
BNE _store_new_head\@ // Are we at the max?
|
||||
|
||||
/* _tx_thread_smp_protect_wait_list_head = 0; */
|
||||
// _tx_thread_smp_protect_wait_list_head = 0;
|
||||
|
||||
EOR w5, w5, w5 // We're at the max. Set it to zero
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_store_new_head\@:
|
||||
|
||||
STR w5, [x4] // Store the new head
|
||||
|
||||
/* We have the lock! */
|
||||
/* return; */
|
||||
DMB ISH // Ensure write to protection finishes
|
||||
|
||||
// return;
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.macro _tx_thread_smp_protect_wait_list_lock_get
|
||||
/* VOID _tx_thread_smp_protect_wait_list_lock_get()
|
||||
{ */
|
||||
// VOID _tx_thread_smp_protect_wait_list_lock_get()
|
||||
// {
|
||||
/* We do this until we have the lock. */
|
||||
/* while (1)
|
||||
{ */
|
||||
// while (1)
|
||||
// {
|
||||
|
||||
_tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
|
||||
|
||||
/* Is the list lock available? */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force); */
|
||||
// Is the list lock available? */
|
||||
// _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force);
|
||||
|
||||
LDR x1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
LDAXR w2, [x1] // Pickup the protection flag
|
||||
|
||||
/* if (protect_in_force == 0)
|
||||
{ */
|
||||
// if (protect_in_force == 0)
|
||||
// {
|
||||
|
||||
CMP w2, #0
|
||||
BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ // No, protection not available
|
||||
|
||||
/* Try to get the list. */
|
||||
/* int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1); */
|
||||
// int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1);
|
||||
|
||||
MOV w2, #1 // Build lock value
|
||||
STXR w3, w2, [x1] // Attempt to get the protection
|
||||
@@ -107,17 +109,17 @@ _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
|
||||
BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ // Did it fail? If so, try again.
|
||||
|
||||
/* We have the lock! */
|
||||
/* return; */
|
||||
// return;
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.macro _tx_thread_smp_protect_wait_list_add
|
||||
/* VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
|
||||
{ */
|
||||
// VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
|
||||
// {
|
||||
|
||||
/* We're about to modify the list, so get the list lock. */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_get(); */
|
||||
// _tx_thread_smp_protect_wait_list_lock_get();
|
||||
|
||||
STP x1, x2, [sp, #-16]! // Save registers we'll be using
|
||||
|
||||
@@ -126,7 +128,7 @@ _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
|
||||
LDP x1, x2, [sp], #16
|
||||
|
||||
/* Add this core. */
|
||||
/* _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core; */
|
||||
// _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core;
|
||||
|
||||
LDR x3, =_tx_thread_smp_protect_wait_list_tail // Get the address of the tail
|
||||
LDR w4, [x3] // Get the value of tail
|
||||
@@ -135,64 +137,66 @@ _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
|
||||
ADD w4, w4, #1 // Increment the tail
|
||||
|
||||
/* Did we wrap? */
|
||||
/* if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
|
||||
{ */
|
||||
// if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
|
||||
// {
|
||||
|
||||
LDR x5, =_tx_thread_smp_protect_wait_list_size // Load max cores address
|
||||
LDR w5, [x5] // Load max cores value
|
||||
CMP w4, w5 // Compare max cores to tail
|
||||
BNE _tx_thread_smp_protect_wait_list_add__no_wrap\@ // Did we wrap?
|
||||
|
||||
/* _tx_thread_smp_protect_wait_list_tail = 0; */
|
||||
// _tx_thread_smp_protect_wait_list_tail = 0;
|
||||
|
||||
MOV w4, #0
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_add__no_wrap\@:
|
||||
|
||||
STR w4, [x3] // Store the new tail value.
|
||||
DMB ISH // Ensure that accesses to shared resource have completed
|
||||
|
||||
/* Release the list lock. */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0; */
|
||||
// _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
|
||||
|
||||
MOV w3, #0 // Build lock value
|
||||
LDR x4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
STR w3, [x4] // Store the new value
|
||||
DMB ISH // Ensure write to protection finishes
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.macro _tx_thread_smp_protect_wait_list_remove
|
||||
/* VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
|
||||
{ */
|
||||
// VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
|
||||
// {
|
||||
|
||||
/* Get the core index. */
|
||||
/* UINT core_index;
|
||||
for (core_index = 0;; core_index++) */
|
||||
// UINT core_index;
|
||||
// for (core_index = 0;; core_index++)
|
||||
|
||||
EOR w4, w4, w4 // Clear for 'core_index'
|
||||
LDR x2, =_tx_thread_smp_protect_wait_list // Get the address of the list
|
||||
|
||||
/* { */
|
||||
// {
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__check_cur_core\@:
|
||||
|
||||
/* Is this the core? */
|
||||
/* if (_tx_thread_smp_protect_wait_list[core_index] == core)
|
||||
{
|
||||
break; */
|
||||
// if (_tx_thread_smp_protect_wait_list[core_index] == core)
|
||||
// {
|
||||
// break;
|
||||
|
||||
LDR w3, [x2, x4, LSL #2] // Get the value at the current index
|
||||
CMP w3, w8 // Did we find the core?
|
||||
BEQ _tx_thread_smp_protect_wait_list_remove__found_core\@
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
ADD w4, w4, #1 // Increment cur index
|
||||
B _tx_thread_smp_protect_wait_list_remove__check_cur_core\@ // Restart the loop
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__found_core\@:
|
||||
|
||||
@@ -200,15 +204,15 @@ _tx_thread_smp_protect_wait_list_remove__found_core\@:
|
||||
core could be simultaneously adding (a core is simultaneously trying to get
|
||||
the inter-core lock) or removing (a core is simultaneously being preempted,
|
||||
like what is currently happening). */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_get(); */
|
||||
// _tx_thread_smp_protect_wait_list_lock_get();
|
||||
|
||||
MOV x6, x1
|
||||
_tx_thread_smp_protect_wait_list_lock_get
|
||||
MOV x1, x6
|
||||
|
||||
/* We remove by shifting. */
|
||||
/* while (core_index != _tx_thread_smp_protect_wait_list_tail)
|
||||
{ */
|
||||
// while (core_index != _tx_thread_smp_protect_wait_list_tail)
|
||||
// {
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@:
|
||||
|
||||
@@ -217,76 +221,78 @@ _tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@:
|
||||
CMP w4, w2 // Compare cur index and tail
|
||||
BEQ _tx_thread_smp_protect_wait_list_remove__removed\@
|
||||
|
||||
/* UINT next_index = core_index + 1; */
|
||||
// UINT next_index = core_index + 1;
|
||||
|
||||
MOV w2, w4 // Move current index to next index register
|
||||
ADD w2, w2, #1 // Add 1
|
||||
|
||||
/* if (next_index == _tx_thread_smp_protect_wait_list_size)
|
||||
{ */
|
||||
// if (next_index == _tx_thread_smp_protect_wait_list_size)
|
||||
// {
|
||||
|
||||
LDR x3, =_tx_thread_smp_protect_wait_list_size
|
||||
LDR w3, [x3]
|
||||
CMP w2, w3
|
||||
BNE _tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@
|
||||
|
||||
/* next_index = 0; */
|
||||
// next_index = 0;
|
||||
|
||||
MOV w2, #0
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@:
|
||||
|
||||
/* list_cores[core_index] = list_cores[next_index]; */
|
||||
// list_cores[core_index] = list_cores[next_index];
|
||||
|
||||
LDR x5, =_tx_thread_smp_protect_wait_list // Get the address of the list
|
||||
LDR w3, [x5, x2, LSL #2] // Get the value at the next index
|
||||
STR w3, [x5, x4, LSL #2] // Store the value at the current index
|
||||
|
||||
/* core_index = next_index; */
|
||||
// core_index = next_index;
|
||||
|
||||
MOV w4, w2
|
||||
|
||||
B _tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__removed\@:
|
||||
|
||||
/* Now update the tail. */
|
||||
/* if (_tx_thread_smp_protect_wait_list_tail == 0)
|
||||
{ */
|
||||
// if (_tx_thread_smp_protect_wait_list_tail == 0)
|
||||
// {
|
||||
|
||||
LDR x5, =_tx_thread_smp_protect_wait_list_tail // Load tail address
|
||||
LDR w4, [x5] // Load tail value
|
||||
CMP w4, #0
|
||||
BNE _tx_thread_smp_protect_wait_list_remove__tail_not_zero\@
|
||||
|
||||
/* _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size; */
|
||||
// _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size;
|
||||
|
||||
LDR x2, =_tx_thread_smp_protect_wait_list_size
|
||||
LDR w4, [x2]
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__tail_not_zero\@:
|
||||
|
||||
/* _tx_thread_smp_protect_wait_list_tail--; */
|
||||
// _tx_thread_smp_protect_wait_list_tail--;
|
||||
|
||||
SUB w4, w4, #1
|
||||
STR w4, [x5] // Store new tail value
|
||||
DMB ISH // Ensure that accesses to shared resource have completed
|
||||
|
||||
/* Release the list lock. */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0; */
|
||||
// _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
|
||||
|
||||
MOV w2, #0 // Build lock value
|
||||
LDR x4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force // Load lock address
|
||||
STR w2, [x4] // Store the new value
|
||||
DMB ISH // Ensure write to protection finishes
|
||||
|
||||
/* We're no longer waiting. Note that this should be zero since, again,
|
||||
this function is only called when a thread preemption is occurring. */
|
||||
/* _tx_thread_smp_protect_wait_counts[core]--; */
|
||||
// _tx_thread_smp_protect_wait_counts[core]--;
|
||||
LDR x4, =_tx_thread_smp_protect_wait_counts // Load wait list counts
|
||||
LDR w2, [x4, x8, LSL #2] // Load waiting value
|
||||
SUB w2, w2, #1 // Subtract 1
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_smp_unprotect Cortex-A35-SMP/AC6 */
|
||||
/* 6.1 */
|
||||
/* 6.1.9 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -61,6 +61,9 @@
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 10-15-2021 Andres Mlinar Updated comments, */
|
||||
/* added ARMv8.2-A support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.global _tx_thread_smp_unprotect
|
||||
@@ -69,10 +72,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
|
||||
@@ -114,4 +124,3 @@ _still_protected:
|
||||
#endif
|
||||
MSR DAIF, x0 // Restore interrupt posture
|
||||
RET
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
@@ -79,7 +79,7 @@ VOID _tx_thread_timeout(ULONG timeout_input)
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
TX_THREAD *thread_ptr;
|
||||
VOID (*suspend_cleanup)(struct TX_THREAD_STRUCT *suspend_thread_ptr, ULONG suspension_sequence);
|
||||
ULONG suspension_sequence;
|
||||
|
||||
@@ -126,7 +126,7 @@ ULONG suspension_sequence;
|
||||
/* 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;
|
||||
|
||||
@@ -162,4 +162,3 @@ ULONG suspension_sequence;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,6 @@ ALIGN_TYPE return_value = TX_NOT_AVAILABLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return(return_value);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2014-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
* Use, modification and redistribution of this file is subject to your possession of a
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
*/
|
||||
#ifndef GICV3_h
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2016-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2014-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
* Use, modification and redistribution of this file is subject to your possession of a
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
*/
|
||||
#ifndef GICV3_gicc_h
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2014-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
* Use, modification and redistribution of this file is subject to your possession of a
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2014-2018 Arm Limited (or its affiliates). All rights reserved.
|
||||
* Use, modification and redistribution of this file is subject to your possession of a
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
*/
|
||||
#include "GICv3.h"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* 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,
|
||||
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
@@ -104,41 +104,41 @@ CHAR *pointer = TX_NULL;
|
||||
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,
|
||||
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
|
||||
/* 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,
|
||||
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,
|
||||
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.
|
||||
/* 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,
|
||||
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,
|
||||
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. */
|
||||
@@ -146,23 +146,23 @@ CHAR *pointer = TX_NULL;
|
||||
|
||||
/* 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,
|
||||
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,
|
||||
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,
|
||||
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. */
|
||||
@@ -264,11 +264,11 @@ UINT status;
|
||||
/* 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
|
||||
/* 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++;
|
||||
}
|
||||
@@ -327,7 +327,7 @@ ULONG actual_flags;
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
@@ -380,7 +380,7 @@ UINT status;
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2009-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//
|
||||
// Copyright (c) 2009-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
// Copyright (c) 2014-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
@@ -326,7 +326,7 @@ el1_entry_aarch64:
|
||||
//
|
||||
// Cortex-A processors automatically invalidate their caches on reset
|
||||
// (unless suppressed with the DBGL1RSTDISABLE or L2RSTDISABLE pins).
|
||||
// It is therefore not necessary for software to invalidate the caches
|
||||
// It is therefore not necessary for software to invalidate the caches
|
||||
// on startup, however, this is done here in case of a warm reset.
|
||||
bl InvalidateUDCaches
|
||||
tlbi VMALLE1
|
||||
@@ -685,7 +685,7 @@ nol2setup:
|
||||
bic x1, x1, #SCTLR_ELx_A // Disable alignment fault checking. To enable, change bic to orr
|
||||
msr SCTLR_EL1, x1
|
||||
isb
|
||||
|
||||
|
||||
//
|
||||
// The Arm Architecture Reference Manual for Armv8-A states:
|
||||
//
|
||||
@@ -740,7 +740,7 @@ arg0:
|
||||
bl main
|
||||
|
||||
b exit // Will not return
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// EL1 - secondary CPU init code
|
||||
//
|
||||
@@ -795,4 +795,4 @@ loop_wfi:
|
||||
// Branch to thread start
|
||||
//
|
||||
//B MainApp
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2018 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2016 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2016 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2013-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2014-2016 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ _gcc_setup:
|
||||
ldr x9, =__RAM_segment_start__
|
||||
|
||||
/* Copy GOT table. */
|
||||
|
||||
|
||||
ldr x0, =__got_load_start__
|
||||
sub x0 ,x0, x3
|
||||
add x0, x0, x5
|
||||
@@ -51,7 +51,7 @@ got_setup_done:
|
||||
|
||||
|
||||
/* Copy initialised sections into RAM if required. */
|
||||
|
||||
|
||||
ldr x0, =__data_load_start__
|
||||
sub x0, x0, x3
|
||||
add x0, x0, x5
|
||||
@@ -62,9 +62,9 @@ got_setup_done:
|
||||
sub x2, x2, x4
|
||||
add x2, x2, x9
|
||||
bl crt0_memory_copy
|
||||
|
||||
|
||||
/* Zero bss. */
|
||||
|
||||
|
||||
ldr x0, =__bss_start__
|
||||
sub x0, x0, x4
|
||||
add x0, x0, x9
|
||||
@@ -88,12 +88,12 @@ got_setup_done:
|
||||
str x2, [x0]
|
||||
add x0, x0, #4
|
||||
str x1, [x0]
|
||||
|
||||
|
||||
ldr x30, [sp] // Restore other preserved registers
|
||||
add sp, sp, 16
|
||||
|
||||
ret // Return to caller
|
||||
|
||||
|
||||
|
||||
/* Startup helper functions. */
|
||||
|
||||
@@ -126,4 +126,4 @@ memory_set_done:
|
||||
|
||||
/* Setup attibutes of heap section so it doesn't take up room in the elf file */
|
||||
.section .heap, "wa", %nobits
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* This is a small demo of the high-performance ThreadX kernel running as a module. It includes
|
||||
examples of eight threads of different priorities, using a message queue, semaphore, mutex,
|
||||
/* This is a small demo of the high-performance ThreadX kernel running as a module. It includes
|
||||
examples of eight threads of different priorities, using a message queue, semaphore, mutex,
|
||||
event flags group, byte pool, and block pool. */
|
||||
|
||||
/* Specify that this is a module! */
|
||||
@@ -20,7 +20,7 @@
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the pool space in the bss section of the module. ULONG is used to
|
||||
/* Define the pool space in the bss section of the module. ULONG is used to
|
||||
get the word alignment. */
|
||||
|
||||
ULONG demo_module_pool_space[DEMO_BYTE_POOL_SIZE / sizeof(ULONG)];
|
||||
@@ -103,7 +103,7 @@ CHAR *pointer;
|
||||
|
||||
|
||||
/* Allocate all the objects. In MMU mode, modules cannot allocate control blocks within
|
||||
their own memory area so they cannot corrupt the resident portion of ThreadX by overwriting
|
||||
their own memory area so they cannot corrupt the resident portion of ThreadX by overwriting
|
||||
the control block(s). */
|
||||
status = txm_module_object_allocate((void*)&thread_0, sizeof(TX_THREAD));
|
||||
while (status != TX_SUCCESS);
|
||||
@@ -133,7 +133,7 @@ CHAR *pointer;
|
||||
while (status != TX_SUCCESS);
|
||||
status = txm_module_object_allocate((void*)&block_pool_0, sizeof(TX_BLOCK_POOL));
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
status = tx_byte_pool_create(byte_pool_0, "module byte pool 0", demo_module_pool_space, DEMO_BYTE_POOL_SIZE);
|
||||
@@ -193,7 +193,7 @@ CHAR *pointer;
|
||||
|
||||
/* Create the main thread. */
|
||||
status = tx_thread_create(thread_0, "module thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -201,11 +201,11 @@ CHAR *pointer;
|
||||
status = tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
/* Create threads 1 and 2. These threads pass information through a ThreadX
|
||||
/* 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. */
|
||||
status = tx_thread_create(thread_1, "module thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -214,7 +214,7 @@ CHAR *pointer;
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
status = tx_thread_create(thread_2, "module thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -222,10 +222,10 @@ CHAR *pointer;
|
||||
status = tx_byte_allocate(byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
|
||||
/* 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. */
|
||||
status = tx_thread_create(thread_3, "module thread 3", thread_3_and_4_entry, 3,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -234,7 +234,7 @@ CHAR *pointer;
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
status = tx_thread_create(thread_4, "module thread 4", thread_3_and_4_entry, 4,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -245,7 +245,7 @@ CHAR *pointer;
|
||||
/* Create thread 5. This thread simply pends on an event flag which will be set
|
||||
by thread_0. */
|
||||
status = tx_thread_create(thread_5, "module thread 5", thread_5_entry, 5,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -255,7 +255,7 @@ CHAR *pointer;
|
||||
|
||||
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
|
||||
status = tx_thread_create(thread_6, "module thread 6", thread_6_and_7_entry, 6,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
@@ -264,7 +264,7 @@ CHAR *pointer;
|
||||
while (status != TX_SUCCESS);
|
||||
|
||||
status = tx_thread_create(thread_7, "module thread 7", thread_6_and_7_entry, 7,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
while (status != TX_SUCCESS);
|
||||
}
|
||||
@@ -276,7 +276,7 @@ void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sits in while-forever-sleep loop. */
|
||||
while(1)
|
||||
{
|
||||
@@ -286,7 +286,7 @@ UINT status;
|
||||
|
||||
/* 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);
|
||||
|
||||
@@ -338,11 +338,11 @@ UINT status;
|
||||
/* 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
|
||||
/* 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++;
|
||||
}
|
||||
@@ -401,7 +401,7 @@ ULONG actual_flags;
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
status = tx_event_flags_get(event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
@@ -454,7 +454,7 @@ UINT status;
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(mutex_0);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.section .txm_module_preamble
|
||||
.align 4
|
||||
|
||||
|
||||
// External references
|
||||
.global _txm_module_thread_shell_entry
|
||||
.global _txm_module_callback_request_thread_entry
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2014-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
* Use, modification and redistribution of this file is subject to your possession of a
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
*/
|
||||
#ifndef GICV3_h
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2016-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2014-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
* Use, modification and redistribution of this file is subject to your possession of a
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
*/
|
||||
#ifndef GICV3_gicc_h
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2014-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
* Use, modification and redistribution of this file is subject to your possession of a
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (c) 2014-2018 Arm Limited (or its affiliates). All rights reserved.
|
||||
* Use, modification and redistribution of this file is subject to your possession of a
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
* and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
*/
|
||||
#include "GICv3.h"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ void module_manager_entry(ULONG thread_input)
|
||||
|
||||
/* Load the module with absolute address linkage, in this example it is placed there by the multiple image download. */
|
||||
txm_module_manager_absolute_load(&my_module, "my module", (void *) MODULE_CODE);
|
||||
|
||||
|
||||
/* Start the module. */
|
||||
txm_module_manager_start(&my_module);
|
||||
|
||||
@@ -127,10 +127,10 @@ void module_manager_entry(ULONG thread_input)
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Stop the module. */
|
||||
txm_module_manager_stop(&my_module);
|
||||
|
||||
|
||||
/* Unload the module. */
|
||||
txm_module_manager_unload(&my_module);
|
||||
|
||||
@@ -139,11 +139,11 @@ void module_manager_entry(ULONG thread_input)
|
||||
|
||||
/* Start the module again. */
|
||||
txm_module_manager_start(&my_module);
|
||||
|
||||
|
||||
/* Now just spin... */
|
||||
while(1)
|
||||
{
|
||||
|
||||
|
||||
tx_thread_sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2009-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
//
|
||||
// Copyright (c) 2009-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//
|
||||
// Copyright (c) 2014-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
@@ -326,7 +326,7 @@ el1_entry_aarch64:
|
||||
//
|
||||
// Cortex-A processors automatically invalidate their caches on reset
|
||||
// (unless suppressed with the DBGL1RSTDISABLE or L2RSTDISABLE pins).
|
||||
// It is therefore not necessary for software to invalidate the caches
|
||||
// It is therefore not necessary for software to invalidate the caches
|
||||
// on startup, however, this is done here in case of a warm reset.
|
||||
bl InvalidateUDCaches
|
||||
tlbi VMALLE1
|
||||
@@ -685,7 +685,7 @@ nol2setup:
|
||||
bic x1, x1, #SCTLR_ELx_A // Disable alignment fault checking. To enable, change bic to orr
|
||||
msr SCTLR_EL1, x1
|
||||
isb
|
||||
|
||||
|
||||
//
|
||||
// The Arm Architecture Reference Manual for Armv8-A states:
|
||||
//
|
||||
@@ -740,7 +740,7 @@ arg0:
|
||||
bl main
|
||||
|
||||
b exit // Will not return
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// EL1 - secondary CPU init code
|
||||
//
|
||||
@@ -795,4 +795,4 @@ loop_wfi:
|
||||
// Branch to thread start
|
||||
//
|
||||
//B MainApp
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2018 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2016 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2012-2016 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2013-2017 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
//
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Copyright (c) 2014-2016 Arm Limited (or its affiliates). All rights reserved.
|
||||
// Use, modification and redistribution of this file is subject to your possession of a
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// valid End User License Agreement for the Arm Product of which these examples are part of
|
||||
// and your compliance with all applicable terms and conditions of such licence agreement.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h Cortex-A35-SMP/GNU */
|
||||
/* 6.1.3 */
|
||||
/* 6.1.9 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
@@ -48,6 +48,9 @@
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 12-31-2020 Andres Mlinar Initial Version 6.1.3 */
|
||||
/* 10-15-2021 William E. Lamie Modified comment(s), added */
|
||||
/* symbol ULONG64_DEFINED, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -152,7 +155,7 @@ typedef unsigned int ULONG;
|
||||
typedef unsigned long long ULONG64;
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
|
||||
#define ULONG64_DEFINED
|
||||
|
||||
/* Override the alignment type to use 64-bit alignment and storage for pointers. */
|
||||
|
||||
@@ -441,7 +444,7 @@ VOID tx_thread_fp_disable(VOID);
|
||||
|
||||
#ifdef TX_THREAD_INIT
|
||||
CHAR _tx_version_id[] =
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Modules Cortex-A35-SMP/GNU Version 6.1.3 *";
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Modules Cortex-A35-SMP/GNU Version 6.1.9 *";
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
|
||||
@@ -274,6 +274,6 @@ ALIGN_TYPE _txm_module_manager_port_dispatch(TXM_MODULE_INSTANCE *module_instanc
|
||||
|
||||
#define TXM_MODULE_MANAGER_VERSION_ID \
|
||||
CHAR _txm_module_manager_version_id[] = \
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A35/GNU Version 6.1.3 *";
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-A35/GNU Version 6.1.9 *";
|
||||
|
||||
#endif
|
||||
|
||||
@@ -121,7 +121,7 @@ VOID (*entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT type);
|
||||
An error here typically indicates the resident portion of _tx_thread_schedule
|
||||
is not supporting the trap to obtain the function pointer. */
|
||||
}
|
||||
|
||||
|
||||
/* Resume the module's callback thread, already created in the manager. */
|
||||
_txe_thread_resume(thread_info -> txm_module_thread_entry_info_callback_request_thread);
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_smp_core_get Cortex-A35-SMP/GNU */
|
||||
/* 6.1 */
|
||||
/* _tx_thread_smp_core_get Cortex-A35-SMP/GCC */
|
||||
/* 6.1.9 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -58,17 +58,28 @@
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 10-15-2021 Andres Mlinar Updated comments, */
|
||||
/* added ARMv8.2-A support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.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
|
||||
RET
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_smp_protect Cortex-A35-SMP/GNU */
|
||||
/* 6.1 */
|
||||
/* _tx_thread_smp_protect Cortex-A35-SMP/GCC */
|
||||
/* 6.1.9 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -64,6 +64,10 @@
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 10-15-2021 Andres Mlinar Updated comments, */
|
||||
/* added ARMv8.2-A support, */
|
||||
/* improved SMP code, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.global _tx_thread_smp_protect
|
||||
@@ -78,10 +82,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
|
||||
@@ -163,7 +174,7 @@ _list_not_empty:
|
||||
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
|
||||
// {
|
||||
|
||||
LDR w3, [x2, #0] // Pickup the protection flag
|
||||
LDAXR w3, [x2, #0] // Pickup the protection flag
|
||||
CMP w3, #0
|
||||
BNE _start_waiting // No, protection not available
|
||||
|
||||
@@ -171,7 +182,9 @@ _list_not_empty:
|
||||
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
|
||||
|
||||
MOV w3, #1 // Build lock value
|
||||
STR w3, [x2, #0] // Store lock value
|
||||
STXR w4, w3, [x2, #0] // Attempt to get the protection
|
||||
CMP w4, #0
|
||||
BNE _start_waiting // Did it fail?
|
||||
DMB ISH //
|
||||
|
||||
/* Got the lock. */
|
||||
@@ -217,7 +230,7 @@ _already_in_list0:
|
||||
/* Restore interrupts. */
|
||||
|
||||
MSR DAIF, x0 // Restore interrupts
|
||||
ISB //
|
||||
ISB //
|
||||
#ifdef TX_ENABLE_WFE
|
||||
WFE // Go into standby
|
||||
#endif
|
||||
@@ -236,10 +249,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
|
||||
@@ -257,7 +277,7 @@ _try_to_get_lock:
|
||||
|
||||
/* Are we at the front of the list? */
|
||||
// if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
|
||||
// {/
|
||||
// {
|
||||
|
||||
LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
|
||||
LDR w3, [x3] // Get the value of the head
|
||||
@@ -271,7 +291,7 @@ _try_to_get_lock:
|
||||
// if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
|
||||
// {
|
||||
|
||||
LDR w3, [x2, #0] // Pickup the protection flag
|
||||
LDAXR w3, [x2, #0] // Pickup the protection flag
|
||||
CMP w3, #0
|
||||
BNE _did_not_get_lock // No, protection not available
|
||||
|
||||
@@ -279,7 +299,9 @@ _try_to_get_lock:
|
||||
// _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
|
||||
|
||||
MOV w3, #1 // Build lock value
|
||||
STR w3, [x2, #0] // Store lock value
|
||||
STXR w4, w3, [x2, #0] // Attempt to get the protection
|
||||
CMP w4, #0
|
||||
BNE _did_not_get_lock // Did it fail?
|
||||
DMB ISH //
|
||||
|
||||
/* Got the lock. */
|
||||
@@ -328,7 +350,7 @@ _already_in_list1:
|
||||
/* Restore interrupts and try again. */
|
||||
|
||||
MSR DAIF, x0 // Restore interrupts
|
||||
ISB //
|
||||
ISB //
|
||||
#ifdef TX_ENABLE_WFE
|
||||
WFE // Go into standby
|
||||
#endif
|
||||
@@ -349,4 +371,3 @@ _got_lock_after_waiting:
|
||||
_return:
|
||||
|
||||
RET
|
||||
|
||||
|
||||
@@ -23,12 +23,12 @@
|
||||
.macro _tx_thread_smp_protect_lock_got
|
||||
|
||||
/* Set the currently owned core. */
|
||||
/* _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core; */
|
||||
// _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
|
||||
|
||||
STR w1, [x2, #4] // Store this core
|
||||
|
||||
/* Increment the protection count. */
|
||||
/* _tx_thread_smp_protection.tx_thread_smp_protect_count++; */
|
||||
// _tx_thread_smp_protection.tx_thread_smp_protect_count++;
|
||||
|
||||
LDR w3, [x2, #8] // Pickup ownership count
|
||||
ADD w3, w3, #1 // Increment ownership count
|
||||
@@ -40,7 +40,7 @@
|
||||
.macro _tx_thread_smp_protect_remove_from_front_of_list
|
||||
|
||||
/* Remove ourselves from the list. */
|
||||
/* _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF; */
|
||||
// _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF;
|
||||
|
||||
MOV w3, #0xFFFFFFFF // Build the invalid core value
|
||||
LDR x4, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
|
||||
@@ -50,53 +50,55 @@
|
||||
ADD w5, w5, #1 // Increment the head
|
||||
|
||||
/* Did we wrap? */
|
||||
/* if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
|
||||
{ */
|
||||
// if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
|
||||
// {
|
||||
|
||||
LDR x3, =_tx_thread_smp_protect_wait_list_size // Load address of core list size
|
||||
LDR w3, [x3] // Load the max cores value
|
||||
CMP w5, w3 // Compare the head to it
|
||||
BNE _store_new_head\@ // Are we at the max?
|
||||
|
||||
/* _tx_thread_smp_protect_wait_list_head = 0; */
|
||||
// _tx_thread_smp_protect_wait_list_head = 0;
|
||||
|
||||
EOR w5, w5, w5 // We're at the max. Set it to zero
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_store_new_head\@:
|
||||
|
||||
STR w5, [x4] // Store the new head
|
||||
|
||||
/* We have the lock! */
|
||||
/* return; */
|
||||
DMB ISH // Ensure write to protection finishes
|
||||
|
||||
// return;
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.macro _tx_thread_smp_protect_wait_list_lock_get
|
||||
/* VOID _tx_thread_smp_protect_wait_list_lock_get()
|
||||
{ */
|
||||
// VOID _tx_thread_smp_protect_wait_list_lock_get()
|
||||
// {
|
||||
/* We do this until we have the lock. */
|
||||
/* while (1)
|
||||
{ */
|
||||
// while (1)
|
||||
// {
|
||||
|
||||
_tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
|
||||
|
||||
/* Is the list lock available? */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force); */
|
||||
// Is the list lock available? */
|
||||
// _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force);
|
||||
|
||||
LDR x1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
LDAXR w2, [x1] // Pickup the protection flag
|
||||
|
||||
/* if (protect_in_force == 0)
|
||||
{ */
|
||||
// if (protect_in_force == 0)
|
||||
// {
|
||||
|
||||
CMP w2, #0
|
||||
BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ // No, protection not available
|
||||
|
||||
/* Try to get the list. */
|
||||
/* int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1); */
|
||||
// int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1);
|
||||
|
||||
MOV w2, #1 // Build lock value
|
||||
STXR w3, w2, [x1] // Attempt to get the protection
|
||||
@@ -107,17 +109,17 @@ _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
|
||||
BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ // Did it fail? If so, try again.
|
||||
|
||||
/* We have the lock! */
|
||||
/* return; */
|
||||
// return;
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.macro _tx_thread_smp_protect_wait_list_add
|
||||
/* VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
|
||||
{ */
|
||||
// VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
|
||||
// {
|
||||
|
||||
/* We're about to modify the list, so get the list lock. */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_get(); */
|
||||
// _tx_thread_smp_protect_wait_list_lock_get();
|
||||
|
||||
STP x1, x2, [sp, #-16]! // Save registers we'll be using
|
||||
|
||||
@@ -126,7 +128,7 @@ _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
|
||||
LDP x1, x2, [sp], #16
|
||||
|
||||
/* Add this core. */
|
||||
/* _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core; */
|
||||
// _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core;
|
||||
|
||||
LDR x3, =_tx_thread_smp_protect_wait_list_tail // Get the address of the tail
|
||||
LDR w4, [x3] // Get the value of tail
|
||||
@@ -135,64 +137,66 @@ _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
|
||||
ADD w4, w4, #1 // Increment the tail
|
||||
|
||||
/* Did we wrap? */
|
||||
/* if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
|
||||
{ */
|
||||
// if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
|
||||
// {
|
||||
|
||||
LDR x5, =_tx_thread_smp_protect_wait_list_size // Load max cores address
|
||||
LDR w5, [x5] // Load max cores value
|
||||
CMP w4, w5 // Compare max cores to tail
|
||||
BNE _tx_thread_smp_protect_wait_list_add__no_wrap\@ // Did we wrap?
|
||||
|
||||
/* _tx_thread_smp_protect_wait_list_tail = 0; */
|
||||
// _tx_thread_smp_protect_wait_list_tail = 0;
|
||||
|
||||
MOV w4, #0
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_add__no_wrap\@:
|
||||
|
||||
STR w4, [x3] // Store the new tail value.
|
||||
DMB ISH // Ensure that accesses to shared resource have completed
|
||||
|
||||
/* Release the list lock. */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0; */
|
||||
// _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
|
||||
|
||||
MOV w3, #0 // Build lock value
|
||||
LDR x4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
|
||||
STR w3, [x4] // Store the new value
|
||||
DMB ISH // Ensure write to protection finishes
|
||||
|
||||
.endm
|
||||
|
||||
|
||||
.macro _tx_thread_smp_protect_wait_list_remove
|
||||
/* VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
|
||||
{ */
|
||||
// VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
|
||||
// {
|
||||
|
||||
/* Get the core index. */
|
||||
/* UINT core_index;
|
||||
for (core_index = 0;; core_index++) */
|
||||
// UINT core_index;
|
||||
// for (core_index = 0;; core_index++)
|
||||
|
||||
EOR w4, w4, w4 // Clear for 'core_index'
|
||||
LDR x2, =_tx_thread_smp_protect_wait_list // Get the address of the list
|
||||
|
||||
/* { */
|
||||
// {
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__check_cur_core\@:
|
||||
|
||||
/* Is this the core? */
|
||||
/* if (_tx_thread_smp_protect_wait_list[core_index] == core)
|
||||
{
|
||||
break; */
|
||||
// if (_tx_thread_smp_protect_wait_list[core_index] == core)
|
||||
// {
|
||||
// break;
|
||||
|
||||
LDR w3, [x2, x4, LSL #2] // Get the value at the current index
|
||||
CMP w3, w8 // Did we find the core?
|
||||
BEQ _tx_thread_smp_protect_wait_list_remove__found_core\@
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
ADD w4, w4, #1 // Increment cur index
|
||||
B _tx_thread_smp_protect_wait_list_remove__check_cur_core\@ // Restart the loop
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__found_core\@:
|
||||
|
||||
@@ -200,15 +204,15 @@ _tx_thread_smp_protect_wait_list_remove__found_core\@:
|
||||
core could be simultaneously adding (a core is simultaneously trying to get
|
||||
the inter-core lock) or removing (a core is simultaneously being preempted,
|
||||
like what is currently happening). */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_get(); */
|
||||
// _tx_thread_smp_protect_wait_list_lock_get();
|
||||
|
||||
MOV x6, x1
|
||||
_tx_thread_smp_protect_wait_list_lock_get
|
||||
MOV x1, x6
|
||||
|
||||
/* We remove by shifting. */
|
||||
/* while (core_index != _tx_thread_smp_protect_wait_list_tail)
|
||||
{ */
|
||||
// while (core_index != _tx_thread_smp_protect_wait_list_tail)
|
||||
// {
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@:
|
||||
|
||||
@@ -217,76 +221,78 @@ _tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@:
|
||||
CMP w4, w2 // Compare cur index and tail
|
||||
BEQ _tx_thread_smp_protect_wait_list_remove__removed\@
|
||||
|
||||
/* UINT next_index = core_index + 1; */
|
||||
// UINT next_index = core_index + 1;
|
||||
|
||||
MOV w2, w4 // Move current index to next index register
|
||||
ADD w2, w2, #1 // Add 1
|
||||
|
||||
/* if (next_index == _tx_thread_smp_protect_wait_list_size)
|
||||
{ */
|
||||
// if (next_index == _tx_thread_smp_protect_wait_list_size)
|
||||
// {
|
||||
|
||||
LDR x3, =_tx_thread_smp_protect_wait_list_size
|
||||
LDR w3, [x3]
|
||||
CMP w2, w3
|
||||
BNE _tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@
|
||||
|
||||
/* next_index = 0; */
|
||||
// next_index = 0;
|
||||
|
||||
MOV w2, #0
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@:
|
||||
|
||||
/* list_cores[core_index] = list_cores[next_index]; */
|
||||
// list_cores[core_index] = list_cores[next_index];
|
||||
|
||||
LDR x5, =_tx_thread_smp_protect_wait_list // Get the address of the list
|
||||
LDR w3, [x5, x2, LSL #2] // Get the value at the next index
|
||||
STR w3, [x5, x4, LSL #2] // Store the value at the current index
|
||||
|
||||
/* core_index = next_index; */
|
||||
// core_index = next_index;
|
||||
|
||||
MOV w4, w2
|
||||
|
||||
B _tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__removed\@:
|
||||
|
||||
/* Now update the tail. */
|
||||
/* if (_tx_thread_smp_protect_wait_list_tail == 0)
|
||||
{ */
|
||||
// if (_tx_thread_smp_protect_wait_list_tail == 0)
|
||||
// {
|
||||
|
||||
LDR x5, =_tx_thread_smp_protect_wait_list_tail // Load tail address
|
||||
LDR w4, [x5] // Load tail value
|
||||
CMP w4, #0
|
||||
BNE _tx_thread_smp_protect_wait_list_remove__tail_not_zero\@
|
||||
|
||||
/* _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size; */
|
||||
// _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size;
|
||||
|
||||
LDR x2, =_tx_thread_smp_protect_wait_list_size
|
||||
LDR w4, [x2]
|
||||
|
||||
/* } */
|
||||
// }
|
||||
|
||||
_tx_thread_smp_protect_wait_list_remove__tail_not_zero\@:
|
||||
|
||||
/* _tx_thread_smp_protect_wait_list_tail--; */
|
||||
// _tx_thread_smp_protect_wait_list_tail--;
|
||||
|
||||
SUB w4, w4, #1
|
||||
STR w4, [x5] // Store new tail value
|
||||
DMB ISH // Ensure that accesses to shared resource have completed
|
||||
|
||||
/* Release the list lock. */
|
||||
/* _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0; */
|
||||
// _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
|
||||
|
||||
MOV w2, #0 // Build lock value
|
||||
LDR x4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force // Load lock address
|
||||
STR w2, [x4] // Store the new value
|
||||
DMB ISH // Ensure write to protection finishes
|
||||
|
||||
/* We're no longer waiting. Note that this should be zero since, again,
|
||||
this function is only called when a thread preemption is occurring. */
|
||||
/* _tx_thread_smp_protect_wait_counts[core]--; */
|
||||
// _tx_thread_smp_protect_wait_counts[core]--;
|
||||
LDR x4, =_tx_thread_smp_protect_wait_counts // Load wait list counts
|
||||
LDR w2, [x4, x8, LSL #2] // Load waiting value
|
||||
SUB w2, w2, #1 // Subtract 1
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_smp_unprotect Cortex-A35-SMP/GNU */
|
||||
/* 6.1 */
|
||||
/* _tx_thread_smp_unprotect Cortex-A35-SMP/GCC */
|
||||
/* 6.1.9 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
@@ -61,6 +61,9 @@
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
|
||||
/* 10-15-2021 Andres Mlinar Updated comments, */
|
||||
/* added ARMv8.2-A support, */
|
||||
/* resulting in version 6.1.9 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
.global _tx_thread_smp_unprotect
|
||||
@@ -69,10 +72,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
|
||||
@@ -114,4 +124,3 @@ _still_protected:
|
||||
#endif
|
||||
MSR DAIF, x0 // Restore interrupt posture
|
||||
RET
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
@@ -79,7 +79,7 @@ VOID _tx_thread_timeout(ULONG timeout_input)
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
TX_THREAD *thread_ptr;
|
||||
VOID (*suspend_cleanup)(struct TX_THREAD_STRUCT *suspend_thread_ptr, ULONG suspension_sequence);
|
||||
ULONG suspension_sequence;
|
||||
|
||||
@@ -126,7 +126,7 @@ ULONG suspension_sequence;
|
||||
/* 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;
|
||||
|
||||
@@ -162,4 +162,3 @@ ULONG suspension_sequence;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user