summaryrefslogtreecommitdiff
path: root/ports/win64
diff options
context:
space:
mode:
Diffstat (limited to 'ports/win64')
-rw-r--r--ports/win64/vs_2022/CMakeLists.txt19
-rw-r--r--ports/win64/vs_2022/inc/tx_port.h630
-rw-r--r--ports/win64/vs_2022/src/tx_initialize_low_level.c417
-rw-r--r--ports/win64/vs_2022/src/tx_thread_context_restore.c180
-rw-r--r--ports/win64/vs_2022/src/tx_thread_context_save.c111
-rw-r--r--ports/win64/vs_2022/src/tx_thread_interrupt_control.c211
-rw-r--r--ports/win64/vs_2022/src/tx_thread_schedule.c331
-rw-r--r--ports/win64/vs_2022/src/tx_thread_stack_build.c211
-rw-r--r--ports/win64/vs_2022/src/tx_thread_system_return.c216
-rw-r--r--ports/win64/vs_2022/src/tx_timer_interrupt.c151
10 files changed, 2477 insertions, 0 deletions
diff --git a/ports/win64/vs_2022/CMakeLists.txt b/ports/win64/vs_2022/CMakeLists.txt
new file mode 100644
index 00000000..328b89d1
--- /dev/null
+++ b/ports/win64/vs_2022/CMakeLists.txt
@@ -0,0 +1,19 @@
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_restore.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_save.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.c
+
+ # {{END_TARGET_SOURCES}}
+)
+
+target_include_directories(${PROJECT_NAME}
+ PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}/inc
+)
diff --git a/ports/win64/vs_2022/inc/tx_port.h b/ports/win64/vs_2022/inc/tx_port.h
new file mode 100644
index 00000000..4cc4e8e0
--- /dev/null
+++ b/ports/win64/vs_2022/inc/tx_port.h
@@ -0,0 +1,630 @@
+/***************************************************************************
+ * Copyright (C) 2026 Eclipse ThreadX contributors
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the MIT License which is available at
+ * https://opensource.org/licenses/MIT.
+ *
+ * AI Disclosure: This file was largely AI-generated by Codex (gpt 5.4).
+ * The AI-generated portions may be considered public domain (CC0-1.0)
+ * and not subject to the project's licence. The human contributor has
+ * reviewed and verified that the code is correct.
+ *
+ * SPDX-License-Identifier: MIT and CC0-1.0
+ **************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_port.h Win64/Visual */
+/* 6.5.1.202602 */
+/* */
+/* AUTHOR */
+/* */
+/* Eclipse ThreadX contributors */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make the ThreadX */
+/* real-time kernel function identically on a variety of different */
+/* processor architectures. For example, the size or number of bits */
+/* in an "int" data type vary between microprocessor architectures and */
+/* even C compilers for the same microprocessor. ThreadX does not */
+/* directly use native C data types. Instead, ThreadX creates its */
+/* own special types that can be mapped to actual data types by this */
+/* file to guarantee consistency in the interface and functionality. */
+/* */
+/**************************************************************************/
+
+#ifndef TX_PORT_H
+#define TX_PORT_H
+
+
+/* Determine if the optional ThreadX user define file should be used. */
+
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in tx_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "tx_user.h"
+#endif
+
+
+/* Define compiler library include files. */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Define automated coverage test extensions required by the regression tests. */
+
+typedef unsigned int TEST_FLAG;
+extern TEST_FLAG threadx_byte_allocate_loop_test;
+extern TEST_FLAG threadx_byte_release_loop_test;
+extern TEST_FLAG threadx_mutex_suspension_put_test;
+extern TEST_FLAG threadx_mutex_suspension_priority_test;
+#ifndef TX_TIMER_PROCESS_IN_ISR
+extern TEST_FLAG threadx_delete_timer_thread;
+#endif
+extern void abort_and_resume_byte_allocating_thread(void);
+extern void abort_all_threads_suspended_on_mutex(void);
+extern void suspend_lowest_priority(void);
+#ifndef TX_TIMER_PROCESS_IN_ISR
+extern void delete_timer_thread(void);
+#endif
+extern TEST_FLAG test_stack_analyze_flag;
+extern TEST_FLAG test_initialize_flag;
+extern TEST_FLAG test_forced_mutex_timeout;
+
+#ifdef TX_REGRESSION_TEST
+
+#define TX_BYTE_ALLOCATE_EXTENSION if (threadx_byte_allocate_loop_test == ((TEST_FLAG) 1)) \
+ { \
+ pool_ptr -> tx_byte_pool_owner = TX_NULL; \
+ threadx_byte_allocate_loop_test = ((TEST_FLAG) 0); \
+ }
+
+#define TX_BYTE_RELEASE_EXTENSION if (threadx_byte_release_loop_test == ((TEST_FLAG) 1)) \
+ { \
+ threadx_byte_release_loop_test = ((TEST_FLAG) 0); \
+ abort_and_resume_byte_allocating_thread(); \
+ }
+
+#define TX_MUTEX_PUT_EXTENSION_1 if (threadx_mutex_suspension_put_test == ((TEST_FLAG) 1)) \
+ { \
+ threadx_mutex_suspension_put_test = ((TEST_FLAG) 0); \
+ abort_all_threads_suspended_on_mutex(); \
+ }
+
+#define TX_MUTEX_PUT_EXTENSION_2 if (test_forced_mutex_timeout == ((TEST_FLAG) 1)) \
+ { \
+ test_forced_mutex_timeout = ((TEST_FLAG) 0); \
+ _tx_thread_wait_abort(mutex_ptr -> tx_mutex_suspension_list); \
+ }
+
+#define TX_MUTEX_PRIORITY_CHANGE_EXTENSION if (threadx_mutex_suspension_priority_test == ((TEST_FLAG) 1)) \
+ { \
+ threadx_mutex_suspension_priority_test = ((TEST_FLAG) 0); \
+ suspend_lowest_priority(); \
+ }
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+#define TX_TIMER_INITIALIZE_EXTENSION(a) if (threadx_delete_timer_thread == ((TEST_FLAG) 1)) \
+ { \
+ threadx_delete_timer_thread = ((TEST_FLAG) 0); \
+ delete_timer_thread(); \
+ (a) = ((UINT) 1); \
+ }
+#endif
+
+#define TX_THREAD_STACK_ANALYZE_EXTENSION if (test_stack_analyze_flag == ((TEST_FLAG) 1)) \
+ { \
+ thread_ptr -> tx_thread_id = ((TEST_FLAG) 0); \
+ test_stack_analyze_flag = ((TEST_FLAG) 0); \
+ } \
+ else if (test_stack_analyze_flag == ((TEST_FLAG) 2)) \
+ { \
+ stack_ptr = thread_ptr -> tx_thread_stack_start; \
+ test_stack_analyze_flag = ((TEST_FLAG) 0); \
+ } \
+ else if (test_stack_analyze_flag == ((TEST_FLAG) 3)) \
+ { \
+ *stack_ptr = TX_STACK_FILL; \
+ test_stack_analyze_flag = ((TEST_FLAG) 0); \
+ } \
+ else \
+ { \
+ test_stack_analyze_flag = ((TEST_FLAG) 0); \
+ }
+
+#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION if (test_initialize_flag == ((TEST_FLAG) 1)) \
+ { \
+ test_initialize_flag = ((TEST_FLAG) 0); \
+ return; \
+ }
+
+#endif
+
+
+/* Define performance metric symbols. */
+
+#ifndef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
+#define TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
+#endif
+
+#ifndef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
+#define TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
+#endif
+
+#ifndef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
+#define TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
+#endif
+
+#ifndef TX_MUTEX_ENABLE_PERFORMANCE_INFO
+#define TX_MUTEX_ENABLE_PERFORMANCE_INFO
+#endif
+
+#ifndef TX_QUEUE_ENABLE_PERFORMANCE_INFO
+#define TX_QUEUE_ENABLE_PERFORMANCE_INFO
+#endif
+
+#ifndef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
+#define TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
+#endif
+
+#ifndef TX_THREAD_ENABLE_PERFORMANCE_INFO
+#define TX_THREAD_ENABLE_PERFORMANCE_INFO
+#endif
+
+#ifndef TX_TIMER_ENABLE_PERFORMANCE_INFO
+#define TX_TIMER_ENABLE_PERFORMANCE_INFO
+#endif
+
+
+
+/* Define ThreadX basic types for this port. */
+
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+typedef uint64_t ULONG64;
+#define ULONG64_DEFINED
+
+
+/* Override the alignment type to preserve pointer-sized alignment on LLP64. */
+
+#define ALIGN_TYPE_DEFINED
+typedef unsigned long long ALIGN_TYPE;
+
+
+/* Override the free block marker for byte pools to be a 64-bit constant. */
+
+#define TX_BYTE_BLOCK_FREE ((ALIGN_TYPE) 0xFFFFEEEEFFFFEEEEULL)
+
+
+/* Add Win32 debug insert prototype. */
+
+void _tx_win32_debug_entry_insert(char *action, char *file, unsigned long line);
+
+#ifndef TX_WIN32_DEBUG_ENABLE
+
+/* If Win32 debug is not enabled, turn logging into white-space. */
+
+#define _tx_win32_debug_entry_insert(a, b, c)
+
+#endif
+
+
+/* Define the TX_MEMSET macro to remove library reference. */
+
+#define TX_MEMSET(a,b,c) { \
+ UCHAR *ptr; \
+ UCHAR value; \
+ UINT i, size; \
+ ptr = (UCHAR *) ((VOID *) a); \
+ value = (UCHAR) b; \
+ size = (UINT) c; \
+ for (i = 0; i < size; i++) \
+ { \
+ *ptr++ = value; \
+ } \
+ }
+
+
+/* Include windows include file. */
+
+#include <windows.h>
+
+#ifndef TX_WIN32_USE_HIGH_RESOLUTION_TIMER
+#define TX_WIN32_USE_HIGH_RESOLUTION_TIMER 1
+#endif
+
+#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
+#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002UL
+#endif
+
+
+/* Define the priority levels for ThreadX. Legal values range
+ from 32 to 1024 and MUST be evenly divisible by 32. */
+
+#ifndef TX_MAX_PRIORITIES
+#define TX_MAX_PRIORITIES 32
+#endif
+
+
+/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
+ thread creation is less than this value, the thread create call will return an error. */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */
+#endif
+
+
+/* Define the system timer thread's default stack size and priority. These are only applicable
+ if TX_TIMER_PROCESS_IN_ISR is not defined. */
+
+#ifndef TX_TIMER_THREAD_STACK_SIZE
+#define TX_TIMER_THREAD_STACK_SIZE 400 /* Default timer thread stack size - Not used in Win64 port! */
+#endif
+
+#ifndef TX_TIMER_THREAD_PRIORITY
+#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
+#endif
+
+
+/* Define various constants for the ThreadX port. */
+
+#define TX_INT_DISABLE 1 /* Disable interrupts */
+#define TX_INT_ENABLE 0 /* Enable interrupts */
+
+
+/* Define the clock source for trace event entry time stamp. The following two item are port specific.
+ For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
+ source constants would be:
+
+#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
+#define TX_TRACE_TIME_MASK 0x0000FFFFUL
+
+ */
+
+#ifndef TX_TRACE_TIME_SOURCE
+#define TX_TRACE_TIME_SOURCE ((ULONG) (_tx_win32_time_stamp.LowPart))
+#endif
+#ifndef TX_TRACE_TIME_MASK
+#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
+#endif
+
+
+/* Define the port-specific trace extension to pickup the Windows timer. */
+
+#define TX_TRACE_PORT_EXTENSION QueryPerformanceCounter((LARGE_INTEGER *)&_tx_win32_time_stamp);
+
+
+/* Define the port specific options for the _tx_build_options variable. This variable indicates
+ how the ThreadX library was built. */
+
+#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0
+
+
+/* Define the in-line initialization constant so that modules with in-line
+ initialization capabilities can prevent their initialization from being
+ a function call. */
+
+#define TX_INLINE_INITIALIZATION
+
+
+/* Define the Win32-specific initialization code that is expanded in the generic source. */
+
+void _tx_initialize_start_interrupts(void);
+
+#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION _tx_initialize_start_interrupts();
+
+/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
+ disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
+ checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
+ define is negated, thereby forcing the stack fill which is necessary for the stack checking
+ logic. */
+
+#ifdef TX_ENABLE_STACK_CHECKING
+#undef TX_DISABLE_STACK_FILLING
+#endif
+
+
+/* Define the TX_THREAD control block extensions for this port. The main reason
+ for the multiple macros is so that backward compatibility can be maintained with
+ existing ThreadX kernel awareness modules. */
+
+#define TX_THREAD_EXTENSION_0 HANDLE tx_thread_win32_thread_handle; \
+ DWORD tx_thread_win32_thread_id; \
+ HANDLE tx_thread_win32_thread_run_semaphore; \
+ HANDLE tx_thread_win32_thread_start_semaphore; \
+ UINT tx_thread_win32_suspension_type; \
+ UINT tx_thread_win32_int_disabled_flag;
+#define TX_THREAD_EXTENSION_1
+#define TX_THREAD_EXTENSION_2
+#define TX_THREAD_EXTENSION_3
+
+
+/* Define the port extensions of the remaining ThreadX objects. */
+
+#define TX_BLOCK_POOL_EXTENSION
+#define TX_BYTE_POOL_EXTENSION
+#define TX_EVENT_FLAGS_GROUP_EXTENSION
+#define TX_MUTEX_EXTENSION
+#define TX_QUEUE_EXTENSION
+#define TX_SEMAPHORE_EXTENSION
+#define TX_TIMER_EXTENSION
+
+
+/* Define the user extension field of the thread control block. Nothing
+ additional is needed for this port so it is defined as white space. */
+
+#ifndef TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
+#endif
+
+
+/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
+ tx_thread_shell_entry, and tx_thread_terminate. */
+
+#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
+
+
+/* Define the ThreadX object creation extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
+#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
+
+
+/* Define the ThreadX object deletion extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
+#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
+
+
+/* Preserve the thread timeout pointer on LLP64 targets. */
+
+#define TX_TIMER_INTERNAL_EXTENSION VOID *tx_timer_internal_extension_ptr;
+
+#define TX_THREAD_CREATE_TIMEOUT_SETUP(t) (t) -> tx_thread_timer.tx_timer_internal_timeout_function = &(_tx_thread_timeout); \
+ (t) -> tx_thread_timer.tx_timer_internal_timeout_param = 0; \
+ (t) -> tx_thread_timer.tx_timer_internal_extension_ptr = (VOID *) (t);
+
+#define TX_THREAD_TIMEOUT_POINTER_SETUP(t) (t) = (TX_THREAD *) _tx_timer_expired_timer_ptr -> tx_timer_internal_extension_ptr;
+
+
+struct TX_THREAD_STRUCT;
+
+
+/* Define the Win32 critical section data structure. */
+
+typedef struct TX_WIN32_CRITICAL_SECTION_STRUCT
+{
+ HANDLE tx_win32_critical_section_mutex_handle;
+ DWORD tx_win32_critical_section_owner;
+ ULONG tx_win32_critical_section_nested_count;
+} TX_WIN32_CRITICAL_SECTION;
+
+
+/* Define Win32-specific critical section APIs. */
+
+void _tx_win32_critical_section_obtain(TX_WIN32_CRITICAL_SECTION *critical_section);
+void _tx_win32_critical_section_release(TX_WIN32_CRITICAL_SECTION *critical_section);
+void _tx_win32_critical_section_release_all(TX_WIN32_CRITICAL_SECTION *critical_section);
+
+
+/* Define post completion processing for tx_thread_delete, so that the Win32 thread resources are properly removed. */
+
+#define TX_THREAD_DELETE_PORT_COMPLETION(thread_ptr) \
+{ \
+BOOL win32_status; \
+DWORD exitcode; \
+HANDLE threadrunsemaphore; \
+HANDLE threadhandle; \
+ULONG wait_count; \
+ threadhandle = thread_ptr -> tx_thread_win32_thread_handle; \
+ threadrunsemaphore = thread_ptr -> tx_thread_win32_thread_run_semaphore; \
+ if ((threadhandle != ((HANDLE) 0)) || (threadrunsemaphore != ((HANDLE) 0)))\
+ { \
+ _tx_thread_interrupt_restore(tx_saved_posture); \
+ if (threadhandle != ((HANDLE) 0)) \
+ { \
+ wait_count = ((ULONG) 0); \
+ do \
+ { \
+ win32_status = GetExitCodeThread(threadhandle, &exitcode); \
+ if ((win32_status) && (exitcode != STILL_ACTIVE)) \
+ { \
+ break; \
+ } \
+ ResumeThread(threadhandle); \
+ if (threadrunsemaphore != ((HANDLE) 0)) \
+ { \
+ ReleaseSemaphore(threadrunsemaphore, 1, NULL); \
+ } \
+ Sleep(1); \
+ wait_count++; \
+ } while (wait_count < ((ULONG) 100)); \
+ win32_status = GetExitCodeThread(threadhandle, &exitcode); \
+ if ((win32_status) && (exitcode == STILL_ACTIVE)) \
+ { \
+ (void) TerminateThread(threadhandle, 0U); \
+ (void) WaitForSingleObject(threadhandle, INFINITE); \
+ } \
+ CloseHandle(threadhandle); \
+ } \
+ if (threadrunsemaphore != ((HANDLE) 0)) \
+ { \
+ CloseHandle(threadrunsemaphore); \
+ } \
+ tx_saved_posture = _tx_thread_interrupt_disable(); \
+ } \
+}
+
+
+/* Define post completion processing for tx_thread_reset, so that the Win32 thread resources are properly removed. */
+
+#define TX_THREAD_RESET_PORT_COMPLETION(thread_ptr) \
+{ \
+BOOL win32_status; \
+DWORD exitcode; \
+HANDLE threadrunsemaphore; \
+HANDLE threadhandle; \
+ULONG wait_count; \
+ threadhandle = thread_ptr -> tx_thread_win32_thread_handle; \
+ threadrunsemaphore = thread_ptr -> tx_thread_win32_thread_run_semaphore; \
+ if ((threadhandle != ((HANDLE) 0)) || (threadrunsemaphore != ((HANDLE) 0)))\
+ { \
+ _tx_thread_interrupt_restore(tx_saved_posture); \
+ if (threadhandle != ((HANDLE) 0)) \
+ { \
+ wait_count = ((ULONG) 0); \
+ do \
+ { \
+ win32_status = GetExitCodeThread(threadhandle, &exitcode); \
+ if ((win32_status) && (exitcode != STILL_ACTIVE)) \
+ { \
+ break; \
+ } \
+ ResumeThread(threadhandle); \
+ if (threadrunsemaphore != ((HANDLE) 0)) \
+ { \
+ ReleaseSemaphore(threadrunsemaphore, 1, NULL); \
+ } \
+ Sleep(1); \
+ wait_count++; \
+ } while (wait_count < ((ULONG) 100)); \
+ win32_status = GetExitCodeThread(threadhandle, &exitcode); \
+ if ((win32_status) && (exitcode == STILL_ACTIVE)) \
+ { \
+ (void) TerminateThread(threadhandle, 0U); \
+ (void) WaitForSingleObject(threadhandle, INFINITE); \
+ } \
+ CloseHandle(threadhandle); \
+ } \
+ if (threadrunsemaphore != ((HANDLE) 0)) \
+ { \
+ CloseHandle(threadrunsemaphore); \
+ } \
+ tx_saved_posture = _tx_thread_interrupt_disable(); \
+ } \
+}
+
+
+/* Define ThreadX interrupt lockout and restore macros for protection on
+ access of critical kernel information. The restore interrupt macro must
+ restore the interrupt posture of the running thread prior to the value
+ present prior to the disable macro. In most cases, the save area macro
+ is used to define a local function save area for the disable and restore
+ macros. */
+
+UINT _tx_thread_interrupt_disable(void);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
+
+#define TX_INTERRUPT_SAVE_AREA UINT tx_saved_posture;
+
+#define TX_DISABLE tx_saved_posture = _tx_thread_interrupt_disable();
+
+#define TX_RESTORE _tx_thread_interrupt_restore(tx_saved_posture);
+
+
+/* Define the interrupt lockout macros for each ThreadX object. */
+
+#define TX_BLOCK_POOL_DISABLE TX_DISABLE
+#define TX_BYTE_POOL_DISABLE TX_DISABLE
+#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
+#define TX_MUTEX_DISABLE TX_DISABLE
+#define TX_QUEUE_DISABLE TX_DISABLE
+#define TX_SEMAPHORE_DISABLE TX_DISABLE
+
+
+/* Define the version ID of ThreadX. This may be utilized by the application. */
+
+#ifdef TX_THREAD_INIT
+CHAR _tx_version_id[] =
+ "(c) 2026 Eclipse ThreadX contributors. * ThreadX Win64/MSVC Version 6.5.1.202602 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+
+/* Define externals for the Win32 port of ThreadX. */
+
+extern TX_WIN32_CRITICAL_SECTION _tx_win32_critical_section;
+extern HANDLE _tx_win32_scheduler_semaphore;
+extern HANDLE _tx_win32_scheduler_wake_event;
+extern DWORD _tx_win32_scheduler_id;
+extern ULONG _tx_win32_global_int_disabled_flag;
+extern LARGE_INTEGER _tx_win32_time_stamp;
+extern ULONG _tx_win32_system_error;
+extern HANDLE _tx_win32_timer_handle;
+extern HANDLE _tx_win32_timer_thread_handle;
+extern HANDLE _tx_win32_isr_semaphore;
+extern UINT _tx_win32_timer_waiting;
+extern UINT _tx_win32_timer_id;
+extern LARGE_INTEGER _tx_win32_time_stamp;
+
+
+#ifndef TX_WIN32_MEMORY_SIZE
+#define TX_WIN32_MEMORY_SIZE 64000
+#endif
+
+VOID _tx_win32_scheduler_wake(VOID);
+
+#ifndef TX_TIMER_PERIODIC
+#ifdef TX_WIN32_SLOW_TIMER
+#define TX_TIMER_PERIODIC TX_WIN32_SLOW_TIMER
+#else
+#define TX_TIMER_PERIODIC 10
+#endif
+#endif
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ports/win64/vs_2022/src/tx_initialize_low_level.c b/ports/win64/vs_2022/src/tx_initialize_low_level.c
new file mode 100644
index 00000000..b7e96575
--- /dev/null
+++ b/ports/win64/vs_2022/src/tx_initialize_low_level.c
@@ -0,0 +1,417 @@
+/***************************************************************************
+ * Copyright (C) 2026 Eclipse ThreadX contributors
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the MIT License which is available at
+ * https://opensource.org/licenses/MIT.
+ *
+ * AI Disclosure: This file was largely AI-generated by Codex (gpt 5.4).
+ * The AI-generated portions may be considered public domain (CC0-1.0)
+ * and not subject to the project's licence. The human contributor has
+ * reviewed and verified that the code is correct.
+ *
+ * SPDX-License-Identifier: MIT and CC0-1.0
+ **************************************************************************/
+
+// Some portions generated by Codex (gpt 5.4).
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Initialize */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#define TX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "tx_api.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+#pragma comment (lib, "Winmm.lib")
+
+/* Define various Win32 objects used by the ThreadX port. */
+
+TX_WIN32_CRITICAL_SECTION _tx_win32_critical_section;
+HANDLE _tx_win32_scheduler_semaphore;
+HANDLE _tx_win32_scheduler_wake_event;
+DWORD _tx_win32_scheduler_id;
+ULONG _tx_win32_global_int_disabled_flag;
+LARGE_INTEGER _tx_win32_time_stamp;
+ULONG _tx_win32_system_error;
+HANDLE _tx_win32_timer_handle;
+HANDLE _tx_win32_timer_thread_handle;
+HANDLE _tx_win32_isr_semaphore;
+UINT _tx_win32_timer_waiting;
+extern TX_THREAD *_tx_thread_current_ptr;
+
+
+/* Define simulated timer interrupt. This is done inside a thread, which is
+ how other interrupts may be defined as well. See code below for an
+ example. */
+
+UINT _tx_win32_timer_id;
+VOID CALLBACK _tx_win32_timer_interrupt(UINT wTimerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
+static VOID _tx_win32_timer_start(VOID);
+static DWORD WINAPI _tx_win32_timer_thread_entry(LPVOID thread_input);
+
+
+#ifdef TX_WIN32_DEBUG_ENABLE
+
+extern ULONG _tx_thread_system_state;
+extern UINT _tx_thread_preempt_disable;
+extern TX_THREAD *_tx_thread_current_ptr;
+extern TX_THREAD *_tx_thread_execute_ptr;
+
+
+/* Define the maximum size of the Win32 debug array. */
+
+#ifndef TX_WIN32_DEBUG_EVENT_SIZE
+#define TX_WIN32_DEBUG_EVENT_SIZE 400
+#endif
+
+
+/* Define debug log in order to debug Win32 issues with this port. */
+
+typedef struct TX_WIN32_DEBUG_ENTRY_STRUCT
+{
+ char *tx_win32_debug_entry_action;
+ LARGE_INTEGER tx_win32_debug_entry_timestamp;
+ char *tx_win32_debug_entry_file;
+ unsigned long tx_win32_debug_entry_line;
+ TX_WIN32_CRITICAL_SECTION tx_win32_debug_entry_critical_section;
+ unsigned long tx_win32_debug_entry_int_disabled_flag;
+ ULONG tx_win32_debug_entry_system_state;
+ UINT tx_win32_debug_entry_preempt_disable;
+ TX_THREAD *tx_win32_debug_entry_current_thread;
+ DWORD tx_win32_debug_entry_current_thread_id;
+ TX_THREAD *tx_win32_debug_entry_execute_thread;
+ DWORD tx_win32_debug_entry_execute_thread_id;
+ DWORD tx_win32_debug_entry_running_id;
+} TX_WIN32_DEBUG_ENTRY;
+
+
+/* Define the circular array of Win32 debug entries. */
+
+TX_WIN32_DEBUG_ENTRY _tx_win32_debug_entry_array[TX_WIN32_DEBUG_EVENT_SIZE];
+
+
+/* Define the Win32 debug index. */
+
+unsigned long _tx_win32_debug_entry_index = 0;
+
+
+/* Now define the debug entry function. */
+void _tx_win32_debug_entry_insert(char *action, char *file, unsigned long line)
+{
+
+
+ /* Get the time stamp. */
+ QueryPerformanceCounter((LARGE_INTEGER *)&_tx_win32_time_stamp);
+
+ /* Setup the debug entry. */
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_action = action;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_timestamp = _tx_win32_time_stamp;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_file = file;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_line = line;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_critical_section = _tx_win32_critical_section;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_int_disabled_flag = _tx_win32_global_int_disabled_flag;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_system_state = _tx_thread_system_state;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_preempt_disable = _tx_thread_preempt_disable;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_current_thread = _tx_thread_current_ptr;
+ if (_tx_thread_current_ptr)
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_current_thread_id = _tx_thread_current_ptr -> tx_thread_win32_thread_id;
+ else
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_current_thread_id = 0;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_execute_thread = _tx_thread_execute_ptr;
+ if (_tx_thread_execute_ptr)
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_execute_thread_id = _tx_thread_execute_ptr -> tx_thread_win32_thread_id;
+ else
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_execute_thread_id = 0;
+ _tx_win32_debug_entry_array[_tx_win32_debug_entry_index].tx_win32_debug_entry_running_id = GetCurrentThreadId();
+
+ /* Now move to the next entry. */
+ _tx_win32_debug_entry_index++;
+
+ /* Determine if we need to wrap the list. */
+ if (_tx_win32_debug_entry_index >= TX_WIN32_DEBUG_EVENT_SIZE)
+ {
+
+ /* Yes, wrap the list! */
+ _tx_win32_debug_entry_index = 0;
+ }
+}
+
+#endif
+
+
+/* Define the ThreadX timer interrupt handler. */
+
+void _tx_timer_interrupt(void);
+
+
+/* Define other external function references. */
+
+VOID _tx_initialize_low_level(VOID);
+VOID _tx_thread_context_save(VOID);
+VOID _tx_thread_context_restore(VOID);
+VOID _tx_win32_scheduler_wake(VOID);
+
+
+/* Define other external variable references. */
+
+extern VOID *_tx_initialize_unused_memory;
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_initialize_low_level Win64/MSVC */
+/* 6.1 */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is responsible for any low-level processor */
+/* initialization, including setting up interrupt vectors, setting */
+/* up a periodic timer interrupt source, saving the system stack */
+/* pointer for use in ISR processing later, and finding the first */
+/* available RAM memory address for tx_application_define. */
+/* */
+/* INPUT */
+/* */
+/* None */
+/* */
+/* OUTPUT */
+/* */
+/* None */
+/* */
+/* CALLS */
+/* */
+/* CreateMutex Win32 create mutex */
+/* CreateThread Win32 create thread */
+/* CreateSemaphore Win32 create semaphore */
+/* GetCurrentThreadId Win32 get current thread ID */
+/* SetProcessAffinityMask Win32 process affinity set */
+/* SetThreadPriority Win32 set thread priority */
+/* */
+/* CALLED BY */
+/* */
+/* _tx_initialize_kernel_enter ThreadX entry function */
+/* */
+/**************************************************************************/
+VOID _tx_initialize_low_level(VOID)
+{
+
+/* Deprecate TX_WIN32_MULTI_CORE build option and default to restricting
+ execution to one core. */
+
+#ifndef TX_WIN32_BYPASS_AFFINITY_SETUP
+
+ /* Limit this ThreadX simulation on Win64 to a single core. */
+ if (SetProcessAffinityMask(GetCurrentProcess(), ((DWORD_PTR) 1)) == 0)
+ {
+
+ /* Error restricting the process to one core. */
+ printf("ThreadX Win64 error restricting the process to one core!\n");
+ while(1)
+ {
+ }
+ }
+#endif
+
+ /* Pickup the first available memory address. */
+
+ /* Save the first available memory address. */
+ _tx_initialize_unused_memory = malloc(TX_WIN32_MEMORY_SIZE);
+
+ /* Pickup the unique Id of the current thread, which will also be the Id of the scheduler. */
+ _tx_win32_scheduler_id = GetCurrentThreadId();
+
+ /* Create the system critical section mutex. This is used by the system to block all other access,
+ analogous to an interrupt lockout on an embedded target. */
+ _tx_win32_critical_section.tx_win32_critical_section_mutex_handle = CreateMutex(NULL, FALSE, NULL);
+ _tx_win32_critical_section.tx_win32_critical_section_nested_count = 0;
+ _tx_win32_critical_section.tx_win32_critical_section_owner = 0;
+ if (_tx_win32_critical_section.tx_win32_critical_section_mutex_handle == NULL)
+ {
+ printf("ThreadX Win64 error creating critical section mutex!\n");
+ while(1)
+ {
+ }
+ }
+
+ /* Create the semaphore that regulates when the scheduler executes. */
+ _tx_win32_scheduler_semaphore = CreateSemaphore(NULL, 0, 1, NULL);
+ _tx_win32_isr_semaphore = CreateSemaphore(NULL, 0, 1, NULL);
+ if ((_tx_win32_scheduler_semaphore == NULL) || (_tx_win32_isr_semaphore == NULL))
+ {
+ printf("ThreadX Win64 error creating semaphores!\n");
+ while(1)
+ {
+ }
+ }
+
+ /* Create the event that wakes the scheduler whenever the ready state changes. */
+ _tx_win32_scheduler_wake_event = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (_tx_win32_scheduler_wake_event == NULL)
+ {
+ printf("ThreadX Win64 error creating scheduler wake event!\n");
+ while(1)
+ {
+ }
+ }
+
+ /* Initialize the global interrupt disabled flag. */
+ _tx_win32_global_int_disabled_flag = TX_FALSE;
+ _tx_win32_timer_waiting = TX_FALSE;
+
+ /* Done, return to caller. */
+}
+
+
+/* This routine is called after initialization is complete in order to start
+ all interrupt threads. Interrupt threads in addition to the timer may
+ be added to this routine as well. */
+
+void _tx_initialize_start_interrupts(void)
+{
+ TIMECAPS tc;
+ UINT wTimerRes;
+
+ /* Queries the timer device to determine its resolution. */
+ if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR)
+ {
+ /* Error; application can't continue. */
+ printf("Query timer device error.");
+ while (1)
+ {
+ }
+ }
+
+ wTimerRes = min(max(tc.wPeriodMin, TX_TIMER_PERIODIC), tc.wPeriodMax);
+
+ /* Request the best available timer resolution for the simulation. */
+ if (timeBeginPeriod(wTimerRes) != TIMERR_NOERROR)
+ {
+ printf("ThreadX Win64 error configuring timer resolution!\n");
+ while (1)
+ {
+ }
+ }
+
+ /* Create the periodic waitable timer used to drive simulated interrupts. */
+#if (TX_WIN32_USE_HIGH_RESOLUTION_TIMER != 0)
+ _tx_win32_timer_handle = CreateWaitableTimerEx(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
+ if (_tx_win32_timer_handle == NULL)
+#endif
+ {
+ _tx_win32_timer_handle = CreateWaitableTimer(NULL, FALSE, NULL);
+ }
+
+ if (_tx_win32_timer_handle == NULL)
+ {
+ printf("ThreadX Win64 error creating timer handle!\n");
+ while (1)
+ {
+ }
+ }
+
+ /* Create the timer thread so interrupts are serialized through one execution context. */
+ _tx_win32_timer_thread_handle = CreateThread(NULL, 0, _tx_win32_timer_thread_entry, NULL, 0, NULL);
+ if (_tx_win32_timer_thread_handle == NULL)
+ {
+ printf("ThreadX Win64 error creating timer thread!\n");
+ while (1)
+ {
+ }
+ }
+
+ SetThreadPriority(_tx_win32_timer_thread_handle, THREAD_PRIORITY_HIGHEST);
+
+ _tx_win32_timer_id = 1;
+
+ /* Start the first simulated tick. */
+ _tx_win32_timer_start();
+}
+
+/* Define the ThreadX system timer interrupt. Other interrupts may be simulated
+ in a similar way. */
+
+VOID CALLBACK _tx_win32_timer_interrupt(UINT wTimerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
+{
+ TX_PARAMETER_NOT_USED(wTimerID);
+ TX_PARAMETER_NOT_USED(msg);
+ TX_PARAMETER_NOT_USED(dwUser);
+ TX_PARAMETER_NOT_USED(dw1);
+ TX_PARAMETER_NOT_USED(dw2);
+
+ /* Call ThreadX context save for interrupt preparation. */
+ _tx_thread_context_save();
+
+ /* Call the ThreadX system timer interrupt processing. */
+ _tx_timer_interrupt();
+
+ /* Call ThreadX context restore for interrupt completion. */
+ _tx_thread_context_restore();
+
+ /* Wake the scheduler so it can promptly observe timer-driven work. */
+ _tx_win32_scheduler_wake();
+}
+
+
+static DWORD WINAPI _tx_win32_timer_thread_entry(LPVOID thread_input)
+{
+ TX_PARAMETER_NOT_USED(thread_input);
+
+ /* Drive periodic simulated interrupts from a single thread. */
+ while (1)
+ {
+ WaitForSingleObject(_tx_win32_timer_handle, INFINITE);
+ _tx_win32_timer_interrupt(0, 0, 0, 0, 0);
+ _tx_win32_timer_start();
+ }
+}
+
+
+VOID _tx_win32_scheduler_wake(VOID)
+{
+
+ /* Wake the scheduler if it is waiting for a state change. */
+ if (_tx_win32_scheduler_wake_event != NULL)
+ {
+ SetEvent(_tx_win32_scheduler_wake_event);
+ }
+}
+
+
+static VOID _tx_win32_timer_start(VOID)
+{
+
+LARGE_INTEGER due_time;
+
+
+ /* Rearm the host timer relative to "now" to avoid burst catch-up ticks. */
+ due_time.QuadPart = -(((LONGLONG) TX_TIMER_PERIODIC) * 10000LL);
+#if (TX_WIN32_USE_HIGH_RESOLUTION_TIMER != 0)
+ if (SetWaitableTimerEx(_tx_win32_timer_handle, &due_time, 0, NULL, NULL, NULL, 0) == 0)
+#else
+ if (SetWaitableTimer(_tx_win32_timer_handle, &due_time, 0, NULL, NULL, FALSE) == 0)
+#endif
+ {
+ printf("ThreadX Win64 error starting timer!\n");
+ while (1)
+ {
+ }
+ }
+}
+
diff --git a/ports/win64/vs_2022/src/tx_thread_context_restore.c b/ports/win64/vs_2022/src/tx_thread_context_restore.c
new file mode 100644
index 00000000..9786e7cb
--- /dev/null
+++ b/ports/win64/vs_2022/src/tx_thread_context_restore.c
@@ -0,0 +1,180 @@
+/***************************************************************************
+ * Copyright (C) 2026 Eclipse ThreadX contributors
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the MIT License which is available at
+ * https://opensource.org/licenses/MIT.
+ *
+ * AI Disclosure: This file was largely AI-generated by Codex (gpt 5.4).
+ * The AI-generated portions may be considered public domain (CC0-1.0)
+ * and not subject to the project's licence. The human contributor has
+ * reviewed and verified that the code is correct.
+ *
+ * SPDX-License-Identifier: MIT and CC0-1.0
+ **************************************************************************/
+
+// Some portions generated by Codex (gpt 5.4).
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#define TX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_thread_context_restore Win64/MSVC */
+/* 6.1 */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function restores the interrupt context if it is processing a */
+/* nested interrupt. If not, it returns to the interrupt thread if no */
+/* preemption is necessary. Otherwise, if preemption is necessary or */
+/* if no thread was running, the function returns to the scheduler. */
+/* */
+/* INPUT */
+/* */
+/* None */
+/* */
+/* OUTPUT */
+/* */
+/* None */
+/* */
+/* CALLS */
+/* */
+/* ReleaseSemaphore Win32 release semaphore */
+/* ResumeThread Win32 resume thread */
+/* _tx_win32_critical_section_obtain Obtain critical section */
+/* _tx_win32_critical_section_release Release critical section */
+/* */
+/* CALLED BY */
+/* */
+/* ISRs Interrupt Service Routines */
+/* */
+/**************************************************************************/
+VOID _tx_thread_context_restore(VOID)
+{
+TX_THREAD *execute_thread;
+
+ /* Enter critical section to ensure other threads are not playing with
+ the core ThreadX data structures. */
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("CONTEXT_RESTORE", __FILE__, __LINE__);
+
+ /* Decrement the nested interrupt count. */
+ _tx_thread_system_state--;
+
+ /* Pickup the execute thread pointer. */
+ execute_thread = _tx_thread_execute_ptr;
+
+ /* Determine if this is the first nested interrupt and if a ThreadX
+ application thread was running at the time. */
+ if ((!_tx_thread_system_state) && (_tx_thread_current_ptr))
+ {
+
+ /* Yes, this is the first and last interrupt processed. */
+
+ /* Check to see if preemption is required. */
+ if ((_tx_thread_preempt_disable == 0) && (_tx_thread_current_ptr != _tx_thread_execute_ptr))
+ {
+
+ /* Preempt the running application thread. We don't need to suspend the
+ application thread since that is done in the context save processing. */
+
+ /* Indicate that this thread was suspended asynchronously. */
+ _tx_thread_current_ptr -> tx_thread_win32_suspension_type = 1;
+
+ /* Save the remaining time-slice and disable it. */
+ if (_tx_timer_time_slice)
+ {
+
+ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+ _tx_timer_time_slice = 0;
+ }
+
+ /* Clear the current thread pointer. */
+ _tx_thread_current_ptr = TX_NULL;
+
+ /* Block the timer ISR until the resumed thread has observed the wakeup. */
+ _tx_win32_timer_waiting = TX_TRUE;
+
+ /* Wakeup the system thread by setting the system semaphore. */
+ ReleaseSemaphore(_tx_win32_scheduler_semaphore, 1, NULL);
+ _tx_win32_scheduler_wake();
+
+ /* If the timer made a solicited wakeup ready, let that thread run before
+ the host timer ISR continues. */
+ if ((execute_thread != TX_NULL) &&
+ (execute_thread -> tx_thread_win32_suspension_type == 0))
+ {
+
+ /* Release the critical section while the scheduler runs. */
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+ WaitForSingleObject(_tx_win32_isr_semaphore, INFINITE);
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+ while (WaitForSingleObject(_tx_win32_isr_semaphore, 0) == WAIT_OBJECT_0)
+ {
+ }
+ }
+
+ /* The timer ISR no longer needs to hold off future ticks. */
+ _tx_win32_timer_waiting = TX_FALSE;
+ }
+ else
+ {
+
+ /* Since preemption is not required, resume the interrupted thread. */
+ ResumeThread(_tx_thread_current_ptr -> tx_thread_win32_thread_handle);
+ }
+ }
+ else if ((!_tx_thread_system_state) && (execute_thread != TX_NULL))
+ {
+
+ /* The timer made a thread ready while the scheduler was idle. Keep the
+ timer ISR blocked until the solicited wakeup has started running. */
+ _tx_win32_timer_waiting = TX_TRUE;
+ _tx_win32_scheduler_wake();
+
+ if (execute_thread -> tx_thread_win32_suspension_type == 0)
+ {
+
+ /* Release the critical section while the scheduler runs. */
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+ WaitForSingleObject(_tx_win32_isr_semaphore, INFINITE);
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+ while (WaitForSingleObject(_tx_win32_isr_semaphore, 0) == WAIT_OBJECT_0)
+ {
+ }
+ }
+
+ _tx_win32_timer_waiting = TX_FALSE;
+ }
+
+ /* Leave Win32 critical section. */
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+}
+
+
diff --git a/ports/win64/vs_2022/src/tx_thread_context_save.c b/ports/win64/vs_2022/src/tx_thread_context_save.c
new file mode 100644
index 00000000..84f2d290
--- /dev/null
+++ b/ports/win64/vs_2022/src/tx_thread_context_save.c
@@ -0,0 +1,111 @@
+/***************************************************************************
+ * Copyright (C) 2026 Eclipse ThreadX contributors
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the MIT License which is available at
+ * https://opensource.org/licenses/MIT.
+ *
+ * AI Disclosure: This file was largely AI-generated by Codex (gpt 5.4).
+ * The AI-generated portions may be considered public domain (CC0-1.0)
+ * and not subject to the project's licence. The human contributor has
+ * reviewed and verified that the code is correct.
+ *
+ * SPDX-License-Identifier: MIT and CC0-1.0
+ **************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#define TX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_thread_context_save Win64/MSVC */
+/* 6.1 */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function saves the context of an executing thread in the */
+/* beginning of interrupt processing. The function also ensures that */
+/* the system stack is used upon return to the calling ISR. */
+/* */
+/* INPUT */
+/* */
+/* None */
+/* */
+/* OUTPUT */
+/* */
+/* None */
+/* */
+/* CALLS */
+/* */
+/* SuspendThread Win32 thread suspend */
+/* _tx_win32_critical_section_obtain Obtain critical section */
+/* _tx_win32_critical_section_release Release critical section */
+/* */
+/* CALLED BY */
+/* */
+/* ISRs */
+/* */
+/**************************************************************************/
+VOID _tx_thread_context_save(VOID)
+{
+
+TX_THREAD *thread_ptr;
+
+
+ /* Enter critical section to ensure other threads are not playing with
+ the core ThreadX data structures. */
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("CONTEXT_SAVE", __FILE__, __LINE__);
+
+ /* Pickup the current thread pointer. */
+ thread_ptr = _tx_thread_current_ptr;
+
+ /* If an application thread is running, suspend it to simulate preemption. */
+ if ((thread_ptr) && (_tx_thread_system_state == 0))
+ {
+
+ /* Yes, this is the first interrupt and an application thread is running...
+ suspend it! */
+
+ /* Suspend the thread to simulate preemption. Note that the thread is suspended BEFORE the protection get
+ flag is checked to ensure there is not a race condition between this thread and the update of that flag. */
+ SuspendThread(thread_ptr -> tx_thread_win32_thread_handle);
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("CONTEXT_SAVE-suspend_thread", __FILE__, __LINE__);
+
+ }
+
+ /* Increment the nested interrupt condition. */
+ _tx_thread_system_state++;
+
+ /* Exit Win32 critical section. */
+ _tx_win32_critical_section_release(&_tx_win32_critical_section);
+}
+
+
diff --git a/ports/win64/vs_2022/src/tx_thread_interrupt_control.c b/ports/win64/vs_2022/src/tx_thread_interrupt_control.c
new file mode 100644
index 00000000..ab50a3c9
--- /dev/null
+++ b/ports/win64/vs_2022/src/tx_thread_interrupt_control.c
@@ -0,0 +1,211 @@
+/***************************************************************************
+ * Copyright (C) 2026 Eclipse ThreadX contributors
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the MIT License which is available at
+ * https://opensource.org/licenses/MIT.
+ *
+ * AI Disclosure: This file was largely AI-generated by Codex (gpt 5.4).
+ * The AI-generated portions may be considered public domain (CC0-1.0)
+ * and not subject to the project's licence. The human contributor has
+ * reviewed and verified that the code is correct.
+ *
+ * SPDX-License-Identifier: MIT and CC0-1.0
+ **************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define TX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "tx_api.h"
+#include "tx_thread.h"
+
+#include <winbase.h>
+
+/* Define small routines used for the TX_DISABLE/TX_RESTORE macros. */
+
+UINT _tx_thread_interrupt_disable(void)
+{
+
+UINT previous_value;
+
+
+ previous_value = _tx_thread_interrupt_control(TX_INT_DISABLE);
+ return(previous_value);
+}
+
+
+VOID _tx_thread_interrupt_restore(UINT previous_posture)
+{
+
+ previous_posture = _tx_thread_interrupt_control(previous_posture);
+}
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_thread_interrupt_control Win64/MSVC */
+/* 6.1 */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is responsible for changing the interrupt lockout */
+/* posture of the system. */
+/* */
+/* INPUT */
+/* */
+/* new_posture New interrupt lockout posture */
+/* */
+/* OUTPUT */
+/* */
+/* old_posture Old interrupt lockout posture */
+/* */
+/* CALLS */
+/* */
+/* ExitThread Win32 thread exit */
+/* GetCurrentThread Win32 get current thread */
+/* GetCurrentThreadId Win32 get current thread ID */
+/* GetThreadPriority Win32 get thread priority */
+/* _tx_win32_critical_section_obtain Obtain critical section */
+/* _tx_win32_critical_section_release Release critical section */
+/* _tx_win32_critical_section_release_all */
+/* Release critical section */
+/* */
+/* CALLED BY */
+/* */
+/* Application Code */
+/* */
+/**************************************************************************/
+UINT _tx_thread_interrupt_control(UINT new_posture)
+{
+
+UINT old_posture;
+HANDLE threadhandle;
+int threadpriority;
+DWORD threadid;
+TX_THREAD *thread_ptr;
+
+
+ /* Enter Win32 critical section. */
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+
+#ifdef TX_WIN32_DEBUG_ENABLE
+
+ /* Determine if this is a disable or enable request. */
+ if (new_posture == TX_INT_ENABLE)
+ {
+ /* Enable. */
+ _tx_win32_debug_entry_insert("RESTORE", __FILE__, __LINE__);
+ }
+ else
+ {
+ /* Disable. */
+ _tx_win32_debug_entry_insert("DISABLE", __FILE__, __LINE__);
+ }
+#endif
+
+ /* Determine if the thread was terminated. */
+
+ /* Pickup the handle of the current thread. */
+ threadhandle = GetCurrentThread();
+
+ /* Pickup the current thread pointer. */
+ thread_ptr = _tx_thread_current_ptr;
+
+ /* Pickup the priority of the current thread. */
+ threadpriority = GetThreadPriority(threadhandle);
+
+ /* Pickup the ID of the current thread. */
+ threadid = GetCurrentThreadId();
+
+ /* Determine if this is a thread (THREAD_PRIORITY_LOWEST) and it does not
+ match the current thread pointer. */
+ if ((threadpriority == THREAD_PRIORITY_LOWEST) &&
+ ((!thread_ptr) || (thread_ptr -> tx_thread_win32_thread_id != threadid)))
+ {
+
+ /* This indicates the Win32 thread was actually terminated by ThreadX is only
+ being allowed to run in order to cleanup its resources. */
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+
+ /* Exit this thread. */
+ ExitThread(0);
+ }
+
+ /* Determine the current interrupt lockout condition. */
+ if (_tx_win32_critical_section.tx_win32_critical_section_nested_count == 1)
+ {
+
+ /* First pass through, interrupts are enabled. */
+ old_posture = TX_INT_ENABLE;
+ }
+ else
+ {
+
+ /* Interrupts are disabled. */
+ old_posture = TX_INT_DISABLE;
+ }
+
+ /* First, determine if this call is from a non-thread. */
+ if (_tx_thread_system_state)
+ {
+
+ /* Determine how to apply the new posture. */
+ if (new_posture == TX_INT_ENABLE)
+ {
+
+ /* Clear the disabled flag. */
+ _tx_win32_global_int_disabled_flag = TX_FALSE;
+
+ /* Determine if the critical section is locked. */
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+ }
+ else if (new_posture == TX_INT_DISABLE)
+ {
+
+ /* Set the disabled flag. */
+ _tx_win32_global_int_disabled_flag = TX_TRUE;
+ }
+ }
+ else if (thread_ptr)
+ {
+
+ /* Determine how to apply the new posture. */
+ if (new_posture == TX_INT_ENABLE)
+ {
+
+ /* Clear the disabled flag. */
+ _tx_thread_current_ptr -> tx_thread_win32_int_disabled_flag = TX_FALSE;
+
+ /* Determine if the critical section is locked. */
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+ }
+ else if (new_posture == TX_INT_DISABLE)
+ {
+
+ /* Set the disabled flag. */
+ _tx_thread_current_ptr -> tx_thread_win32_int_disabled_flag = TX_TRUE;
+ }
+ }
+
+ /* Return the previous interrupt disable posture. */
+ return(old_posture);
+}
+
+
diff --git a/ports/win64/vs_2022/src/tx_thread_schedule.c b/ports/win64/vs_2022/src/tx_thread_schedule.c
new file mode 100644
index 00000000..d08305ee
--- /dev/null
+++ b/ports/win64/vs_2022/src/tx_thread_schedule.c
@@ -0,0 +1,331 @@
+/***************************************************************************
+ * Copyright (C) 2026 Eclipse ThreadX contributors
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the MIT License which is available at
+ * https://opensource.org/licenses/MIT.
+ *
+ * AI Disclosure: This file was largely AI-generated by Codex (gpt 5.4).
+ * The AI-generated portions may be considered public domain (CC0-1.0)
+ * and not subject to the project's licence. The human contributor has
+ * reviewed and verified that the code is correct.
+ *
+ * SPDX-License-Identifier: MIT and CC0-1.0
+ **************************************************************************/
+
+// Some portions generated by Codex (gpt 5.4).
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#define TX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+
+
+static VOID _tx_win32_semaphore_reset(HANDLE semaphore_handle);
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_thread_schedule Win64/MSVC */
+/* 6.1 */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function waits for a thread control block pointer to appear in */
+/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+/* in the variable, the corresponding thread is resumed. */
+/* */
+/* INPUT */
+/* */
+/* None */
+/* */
+/* OUTPUT */
+/* */
+/* None */
+/* */
+/* CALLS */
+/* */
+/* ReleaseSemaphore Win32 release semaphore */
+/* ResumeThread Win32 resume thread */
+/* _tx_win32_scheduler_wake Wake scheduler waiters */
+/* WaitForSingleObject Win32 wait on a semaphore */
+/* _tx_win32_critical_section_obtain Obtain critical section */
+/* _tx_win32_critical_section_release Release critical section */
+/* */
+/* CALLED BY */
+/* */
+/* _tx_initialize_kernel_enter ThreadX entry function */
+/* */
+/**************************************************************************/
+VOID _tx_thread_schedule(VOID)
+{
+DWORD wait_status;
+
+
+ /* Loop forever. */
+ while(1)
+ {
+
+ /* Wait for a thread to execute and all ISRs to complete. */
+ while(1)
+ {
+
+
+ /* Enter Win32 critical section. */
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("SCHEDULE-wake_up", __FILE__, __LINE__);
+
+ /* Determine if there is a thread ready to execute AND all ISRs
+ are complete. */
+ if ((_tx_thread_execute_ptr != TX_NULL) && (_tx_thread_system_state == 0))
+ {
+
+ /* Get out of this loop and schedule the thread! */
+ break;
+ }
+ else
+ {
+
+ /* Leave the critical section. */
+ _tx_win32_critical_section_release(&_tx_win32_critical_section);
+
+ /* Wait for the next scheduling state change. */
+ WaitForSingleObject(_tx_win32_scheduler_wake_event, INFINITE);
+ }
+ }
+
+ /* Yes! We have a thread to execute. Note that the critical section is already
+ active from the scheduling loop above. */
+
+ /* Setup the current thread pointer. */
+ _tx_thread_current_ptr = _tx_thread_execute_ptr;
+
+ /* Increment the run count for this thread. */
+ _tx_thread_current_ptr -> tx_thread_run_count++;
+
+ /* Setup time-slice, if present. */
+ _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+
+ /* Determine how the thread was suspended. */
+ if (_tx_thread_current_ptr -> tx_thread_win32_suspension_type)
+ {
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("SCHEDULE-resume_thread", __FILE__, __LINE__);
+
+ /* Pseudo interrupt suspension. The thread is not waiting on
+ its run semaphore. */
+ ResumeThread(_tx_thread_current_ptr -> tx_thread_win32_thread_handle);
+ }
+ else
+ {
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("SCHEDULE-release_sem", __FILE__, __LINE__);
+
+ /* Clear any stale wakeup acknowledgements before this solicited resume. */
+ _tx_win32_semaphore_reset(_tx_thread_current_ptr -> tx_thread_win32_thread_start_semaphore);
+ _tx_win32_semaphore_reset(_tx_thread_current_ptr -> tx_thread_win32_thread_run_semaphore);
+
+ /* Let the thread run again by releasing its run semaphore. */
+ if (ReleaseSemaphore(_tx_thread_current_ptr -> tx_thread_win32_thread_run_semaphore, 1, NULL) == 0)
+ {
+
+ /* Increment the system error counter. */
+ _tx_win32_system_error++;
+ }
+
+ /* Let the solicited wakeup reach ThreadX before the timer ISR advances again. */
+ if (_tx_win32_timer_waiting)
+ {
+
+ /* Wait for the thread to acknowledge the wakeup and then release the ISR. */
+ wait_status = WaitForSingleObject(_tx_thread_current_ptr -> tx_thread_win32_thread_start_semaphore, INFINITE);
+ if (ReleaseSemaphore(_tx_win32_isr_semaphore, 1, NULL) == 0)
+ {
+
+ /* Increment the system error counter. */
+ _tx_win32_system_error++;
+ }
+
+ if (wait_status != WAIT_OBJECT_0)
+ {
+
+ /* Increment the system error counter. */
+ _tx_win32_system_error++;
+ }
+ }
+ }
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("SCHEDULE-self_suspend_sem", __FILE__, __LINE__);
+
+ /* Exit Win32 critical section. */
+ _tx_win32_critical_section_release(&_tx_win32_critical_section);
+
+ /* Now suspend the main thread so the application thread can run. */
+ WaitForSingleObject(_tx_win32_scheduler_semaphore, INFINITE);
+ }
+}
+
+
+static VOID _tx_win32_semaphore_reset(HANDLE semaphore_handle)
+{
+
+ /* Drain any stale semaphore count from a previous host-side wakeup. */
+ while (WaitForSingleObject(semaphore_handle, 0) == WAIT_OBJECT_0)
+ {
+ }
+}
+
+
+/* Define the ThreadX Win32 critical section get, release, and release all functions. */
+
+void _tx_win32_critical_section_obtain(TX_WIN32_CRITICAL_SECTION *critical_section)
+{
+ /* Is the protection owned? */
+ if (critical_section -> tx_win32_critical_section_owner == GetCurrentThreadId())
+ {
+
+ /* Simply increment the nested counter. */
+ critical_section -> tx_win32_critical_section_nested_count++;
+ }
+ else
+ {
+
+ /* Get the Win32 critical section. */
+ if (WaitForSingleObject(critical_section -> tx_win32_critical_section_mutex_handle, INFINITE) != WAIT_OBJECT_0)
+ {
+
+ /* Increment the system error counter and stop when the mutex cannot be acquired. */
+ _tx_win32_system_error++;
+ while(1)
+ {
+ }
+ }
+
+ /* At this point we have the mutex. */
+
+ /* Increment the nesting counter. */
+ critical_section -> tx_win32_critical_section_nested_count = 1;
+
+ /* Remember the owner. */
+ critical_section -> tx_win32_critical_section_owner = GetCurrentThreadId();
+ }
+}
+
+
+void _tx_win32_critical_section_release(TX_WIN32_CRITICAL_SECTION *critical_section)
+{
+
+
+ /* Ensure the caller is the mutex owner. */
+ if (critical_section -> tx_win32_critical_section_owner == GetCurrentThreadId())
+ {
+
+ /* Determine if there is protection. */
+ if (critical_section -> tx_win32_critical_section_nested_count)
+ {
+
+ /* Decrement the nesting counter. */
+ critical_section -> tx_win32_critical_section_nested_count--;
+
+ /* Determine if the critical section is now being released. */
+ if (critical_section -> tx_win32_critical_section_nested_count == 0)
+ {
+
+ /* Yes, it is being released clear the owner. */
+ critical_section -> tx_win32_critical_section_owner = 0;
+
+ /* Finally, release the mutex. */
+ if (ReleaseMutex(critical_section -> tx_win32_critical_section_mutex_handle) != TX_TRUE)
+ {
+
+ /* Increment the system error counter. */
+ _tx_win32_system_error++;
+ }
+
+ /* Just in case, make sure there the mutex is not owned. */
+ while (ReleaseMutex(critical_section -> tx_win32_critical_section_mutex_handle) == TX_TRUE)
+ {
+
+ /* Increment the system error counter. */
+ _tx_win32_system_error++;
+ }
+ }
+ }
+ }
+ else
+ {
+
+ /* Increment the system error counter. */
+ _tx_win32_system_error++;
+ }
+}
+
+
+void _tx_win32_critical_section_release_all(TX_WIN32_CRITICAL_SECTION *critical_section)
+{
+
+ /* Ensure the caller is the mutex owner. */
+ if (critical_section -> tx_win32_critical_section_owner == GetCurrentThreadId())
+ {
+
+ /* Determine if there is protection. */
+ if (critical_section -> tx_win32_critical_section_nested_count)
+ {
+
+ /* Clear the nesting counter. */
+ critical_section -> tx_win32_critical_section_nested_count = 0;
+
+ /* Yes, it is being release clear the owner. */
+ critical_section -> tx_win32_critical_section_owner = 0;
+
+ /* Finally, release the mutex. */
+ if (ReleaseMutex(critical_section -> tx_win32_critical_section_mutex_handle) != TX_TRUE)
+ {
+
+ /* Increment the system error counter. */
+ _tx_win32_system_error++;
+ }
+
+ /* Just in case, make sure there the mutex is not owned. */
+ while (ReleaseMutex(critical_section -> tx_win32_critical_section_mutex_handle) == TX_TRUE)
+ {
+
+ /* Increment the system error counter. */
+ _tx_win32_system_error++;
+ }
+ }
+ }
+ else
+ {
+
+ /* Increment the system error counter. */
+ _tx_win32_system_error++;
+ }
+}
+
+
diff --git a/ports/win64/vs_2022/src/tx_thread_stack_build.c b/ports/win64/vs_2022/src/tx_thread_stack_build.c
new file mode 100644
index 00000000..c50f7754
--- /dev/null
+++ b/ports/win64/vs_2022/src/tx_thread_stack_build.c
@@ -0,0 +1,211 @@
+/***************************************************************************
+ * Copyright (C) 2026 Eclipse ThreadX contributors
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the MIT License which is available at
+ * https://opensource.org/licenses/MIT.
+ *
+ * AI Disclosure: This file was largely AI-generated by Codex (gpt 5.4).
+ * The AI-generated portions may be considered public domain (CC0-1.0)
+ * and not subject to the project's licence. The human contributor has
+ * reviewed and verified that the code is correct.
+ *
+ * SPDX-License-Identifier: MIT and CC0-1.0
+ **************************************************************************/
+
+// Some portions generated by Codex (gpt 5.4).
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#define TX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "tx_api.h"
+#include "tx_thread.h"
+#include <stdio.h>
+
+
+/* Prototype for new thread entry function. */
+
+DWORD WINAPI _tx_win32_thread_entry(LPVOID p);
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_thread_stack_build Win64/MSVC */
+/* 6.1 */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function builds a stack frame on the supplied thread's stack. */
+/* The stack frame results in a fake interrupt return to the supplied */
+/* function pointer. */
+/* */
+/* INPUT */
+/* */
+/* thread_ptr Pointer to thread control blk */
+/* function_ptr Pointer to return function */
+/* */
+/* OUTPUT */
+/* */
+/* None */
+/* */
+/* CALLS */
+/* */
+/* CreateThread Win32 create thread */
+/* ResumeThread Win32 resume thread */
+/* SetThreadPriority Win32 set thread priority */
+/* */
+/* CALLED BY */
+/* */
+/* _tx_thread_create Create thread service */
+/* _tx_thread_reset Reset thread service */
+/* */
+/**************************************************************************/
+VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
+{
+
+ /* Create a Win32 thread for the application thread. */
+ thread_ptr -> tx_thread_win32_thread_handle =
+ CreateThread(NULL, 0, _tx_win32_thread_entry, (LPVOID) thread_ptr, CREATE_SUSPENDED,
+ &(thread_ptr -> tx_thread_win32_thread_id));
+
+ /* Check for a good thread create. */
+ if (!thread_ptr -> tx_thread_win32_thread_handle)
+ {
+
+ /* Display an error message. */
+ printf("ThreadX Win32 error creating thread!\n");
+ while(1)
+ {
+ }
+ }
+
+ /* Otherwise, we have a good thread create. Now set the priority to
+ a lower level. */
+ SetThreadPriority(thread_ptr -> tx_thread_win32_thread_handle, THREAD_PRIORITY_LOWEST);
+
+ /* Create the run semaphore for the thread. This will allow the scheduler
+ control over when the thread actually runs. */
+ thread_ptr -> tx_thread_win32_thread_run_semaphore = CreateSemaphore(NULL, 0, 1, NULL);
+
+ /* Determine if the run semaphore was created successfully. */
+ if (!thread_ptr -> tx_thread_win32_thread_run_semaphore)
+ {
+
+ /* Display an error message. */
+ printf("ThreadX Win32 error creating thread running semaphore!\n");
+ while(1)
+ {
+ }
+ }
+
+ /* Create the scheduler acknowledgement semaphore for this thread. */
+ thread_ptr -> tx_thread_win32_thread_start_semaphore = CreateSemaphore(NULL, 0, 1, NULL);
+
+ /* Determine if the start semaphore was created successfully. */
+ if (!thread_ptr -> tx_thread_win32_thread_start_semaphore)
+ {
+
+ /* Display an error message. */
+ printf("ThreadX Win32 error creating thread start semaphore!\n");
+ while(1)
+ {
+ }
+ }
+
+ /* Setup the thread suspension type to solicited thread suspension.
+ Pseudo interrupt handlers will suspend with this field set to 1. */
+ thread_ptr -> tx_thread_win32_suspension_type = 0;
+
+ /* Clear the disabled count that will keep track of the
+ tx_interrupt_control nesting. */
+ thread_ptr -> tx_thread_win32_int_disabled_flag = 0;
+
+ /* Setup a fake thread stack pointer. */
+ thread_ptr -> tx_thread_stack_ptr = (VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8);
+
+ /* Clear the first word of the stack. */
+ *(((ULONG *) thread_ptr -> tx_thread_stack_ptr) - 1) = 0;
+
+ /* Make the thread initially ready so it will run to the initial wait on
+ its run semaphore. */
+ ResumeThread(thread_ptr -> tx_thread_win32_thread_handle);
+
+ /* Wait until the host thread is parked at the controlled handoff point
+ before ThreadX can schedule it. */
+ if (WaitForSingleObject(thread_ptr -> tx_thread_win32_thread_start_semaphore, INFINITE) != WAIT_OBJECT_0)
+ {
+
+ /* Display an error message. */
+ printf("ThreadX Win32 error synchronizing thread startup!\n");
+ while(1)
+ {
+ }
+ }
+}
+
+
+DWORD WINAPI _tx_win32_thread_entry(LPVOID ptr)
+{
+
+TX_THREAD *thread_ptr;
+TX_THREAD *current_thread_ptr;
+HANDLE threadhandle;
+int threadpriority;
+DWORD threadid;
+
+ /* Pickup the current thread pointer. */
+ thread_ptr = (TX_THREAD *) ptr;
+
+ /* Tell the creator that this host thread has reached the controlled
+ handoff point and is ready to be scheduled. */
+ ReleaseSemaphore(thread_ptr -> tx_thread_win32_thread_start_semaphore, 1, NULL);
+
+ /* Now suspend the thread initially. If the thread has already
+ been scheduled, this will return immediately. */
+ WaitForSingleObject(thread_ptr -> tx_thread_win32_thread_run_semaphore, INFINITE);
+
+ /* Acknowledge that the host thread is now able to execute ThreadX code. */
+ ReleaseSemaphore(thread_ptr -> tx_thread_win32_thread_start_semaphore, 1, NULL);
+
+ /* A deleted host thread can be released only to let it exit. In notify-enabled
+ builds, the first TX_DISABLE in _tx_thread_shell_entry catches this path.
+ When callbacks are disabled, perform the same check before the shell calls
+ the stale ThreadX entry function. */
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+ threadhandle = GetCurrentThread();
+ threadpriority = GetThreadPriority(threadhandle);
+ threadid = GetCurrentThreadId();
+ current_thread_ptr = _tx_thread_current_ptr;
+ if ((threadpriority == THREAD_PRIORITY_LOWEST) &&
+ ((current_thread_ptr == TX_NULL) || (current_thread_ptr -> tx_thread_win32_thread_id != threadid)))
+ {
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+ ExitThread(0);
+ }
+ _tx_win32_critical_section_release(&_tx_win32_critical_section);
+
+ /* Call ThreadX thread entry point. */
+ _tx_thread_shell_entry();
+
+ return EXIT_SUCCESS;
+}
+
+
diff --git a/ports/win64/vs_2022/src/tx_thread_system_return.c b/ports/win64/vs_2022/src/tx_thread_system_return.c
new file mode 100644
index 00000000..7a8fc89c
--- /dev/null
+++ b/ports/win64/vs_2022/src/tx_thread_system_return.c
@@ -0,0 +1,216 @@
+/***************************************************************************
+ * Copyright (C) 2026 Eclipse ThreadX contributors
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the MIT License which is available at
+ * https://opensource.org/licenses/MIT.
+ *
+ * AI Disclosure: This file was largely AI-generated by Codex (gpt 5.4).
+ * The AI-generated portions may be considered public domain (CC0-1.0)
+ * and not subject to the project's licence. The human contributor has
+ * reviewed and verified that the code is correct.
+ *
+ * SPDX-License-Identifier: MIT and CC0-1.0
+ **************************************************************************/
+
+// Some portions generated by Codex (gpt 5.4).
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define TX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "tx_api.h"
+#include "tx_thread.h"
+#include "tx_timer.h"
+#include <stdio.h>
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_thread_system_return Win64/MSVC */
+/* 6.1 */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is target processor specific. It is used to transfer */
+/* control from a thread back to the system. Only a minimal context */
+/* is saved since the compiler assumes temp registers are going to get */
+/* slicked by a function call anyway. */
+/* */
+/* INPUT */
+/* */
+/* None */
+/* */
+/* OUTPUT */
+/* */
+/* None */
+/* */
+/* CALLS */
+/* */
+/* _tx_win32_critical_section_obtain Obtain critical section */
+/* _tx_win32_critical_section_release Release critical section */
+/* _tx_win32_critical_section_release_all */
+/* Release critical section */
+/* ExitThread Win32 thread exit */
+/* GetCurrentThread Win32 get current thread */
+/* GetCurrentThreadId Win32 get current thread ID */
+/* GetThreadPriority Win32 get thread priority */
+/* ReleaseSemaphore Win32 release semaphore */
+/* WaitForSingleObject Win32 wait on semaphore */
+/* */
+/* CALLED BY */
+/* */
+/* ThreadX components */
+/* */
+/**************************************************************************/
+VOID _tx_thread_system_return(VOID)
+{
+
+TX_THREAD *temp_thread_ptr;
+HANDLE temp_run_semaphore;
+UINT temp_thread_state;
+HANDLE threadhandle;
+int threadpriority;
+DWORD threadid;
+
+
+ /* Enter Win32 critical section. */
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+
+ /* Pickup the handle of the current thread. */
+ threadhandle = GetCurrentThread();
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("SYSTEM_RETURN", __FILE__, __LINE__);
+
+ /* First, determine if the thread was terminated. */
+
+ /* Pickup the priority of the current thread. */
+ threadpriority = GetThreadPriority(threadhandle);
+
+ /* Pickup the ID of the current thread. */
+ threadid = GetCurrentThreadId();
+
+ /* Pickup the current thread pointer. */
+ temp_thread_ptr = _tx_thread_current_ptr;
+
+ /* Determine if this is a thread (THREAD_PRIORITY_LOWEST) and it does not
+ match the current thread pointer. */
+ if ((threadpriority == THREAD_PRIORITY_LOWEST) &&
+ ((!temp_thread_ptr) || (temp_thread_ptr -> tx_thread_win32_thread_id != threadid)))
+ {
+
+ /* This indicates the Win32 thread was actually terminated by ThreadX and is only
+ being allowed to run in order to cleanup its resources. */
+
+ /* Release critical section. */
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+
+ /* Exit thread. */
+ ExitThread(0);
+ }
+
+ /* Determine if the time-slice is active. */
+ if (_tx_timer_time_slice)
+ {
+
+ /* Preserve current remaining time-slice for the thread and clear the current time-slice. */
+ temp_thread_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+ _tx_timer_time_slice = 0;
+ }
+
+ /* Save the run semaphore into a temporary variable as well. */
+ temp_run_semaphore = temp_thread_ptr -> tx_thread_win32_thread_run_semaphore;
+
+ /* Pickup the current thread state. */
+ temp_thread_state = temp_thread_ptr -> tx_thread_state;
+
+ /* Setup the suspension type for this thread. */
+ temp_thread_ptr -> tx_thread_win32_suspension_type = 0;
+
+ /* Set the current thread pointer to NULL. */
+ _tx_thread_current_ptr = TX_NULL;
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("SYSTEM_RETURN-release_sem", __FILE__, __LINE__);
+
+ /* Release the semaphore that the main scheduling thread is waiting
+ on. Note that the main scheduling algorithm will take care of
+ setting the current thread pointer to NULL. */
+ ReleaseSemaphore(_tx_win32_scheduler_semaphore, 1, NULL);
+ _tx_win32_scheduler_wake();
+
+ /* Leave Win32 critical section. */
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+
+ /* Determine if the thread was self-terminating. */
+ if (temp_thread_state == TX_TERMINATED)
+ {
+
+ /* Exit the thread instead of waiting on the semaphore! */
+ ExitThread(0);
+ }
+
+ /* Wait on the run semaphore for this thread. This won't get set again
+ until the thread is scheduled. */
+ WaitForSingleObject(temp_run_semaphore, INFINITE);
+
+ /* Acknowledge that the thread is once again executing ThreadX code. */
+ ReleaseSemaphore(temp_thread_ptr -> tx_thread_win32_thread_start_semaphore, 1, NULL);
+
+ /* Enter Win32 critical section. */
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("SYSTEM_RETURN-wake_up", __FILE__, __LINE__);
+
+ /* Determine if the thread was terminated. */
+
+ /* Pickup the current thread pointer. */
+ temp_thread_ptr = _tx_thread_current_ptr;
+
+ /* Determine if this is a thread (THREAD_PRIORITY_LOWEST) and it does not
+ match the current thread pointer. */
+ if ((threadpriority == THREAD_PRIORITY_LOWEST) &&
+ ((!temp_thread_ptr) || (temp_thread_ptr -> tx_thread_win32_thread_id != threadid)))
+ {
+
+ /* Leave Win32 critical section. */
+ _tx_win32_critical_section_release_all(&_tx_win32_critical_section);
+
+ /* This indicates the Win32 thread was actually terminated by ThreadX and is only
+ being allowed to run in order to cleanup its resources. */
+ ExitThread(0);
+ }
+
+ /* Now determine if the application thread last had interrupts disabled. */
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("SYSTEM_RETURN-finish", __FILE__, __LINE__);
+
+ /* Determine if this thread had interrupts disabled. */
+ if (!_tx_thread_current_ptr -> tx_thread_win32_int_disabled_flag)
+ {
+
+ /* Leave Win32 critical section. */
+ _tx_win32_critical_section_release(&_tx_win32_critical_section);
+ }
+}
+
+
diff --git a/ports/win64/vs_2022/src/tx_timer_interrupt.c b/ports/win64/vs_2022/src/tx_timer_interrupt.c
new file mode 100644
index 00000000..6814334b
--- /dev/null
+++ b/ports/win64/vs_2022/src/tx_timer_interrupt.c
@@ -0,0 +1,151 @@
+/***************************************************************************
+ * Copyright (C) 2026 Eclipse ThreadX contributors
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the MIT License which is available at
+ * https://opensource.org/licenses/MIT.
+ *
+ * AI Disclosure: This file was largely AI-generated by Codex (gpt 5.4).
+ * The AI-generated portions may be considered public domain (CC0-1.0)
+ * and not subject to the project's licence. The human contributor has
+ * reviewed and verified that the code is correct.
+ *
+ * SPDX-License-Identifier: MIT and CC0-1.0
+ **************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Timer */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define TX_SOURCE_CODE
+
+
+/* Include necessary system files. */
+
+#include "tx_api.h"
+#include "tx_timer.h"
+#include "tx_thread.h"
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_timer_interrupt Win64/MSVC */
+/* 6.1 */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function processes the hardware timer interrupt. This */
+/* processing includes incrementing the system clock and checking for */
+/* time slice and/or timer expiration. If either is found, the */
+/* interrupt context save/restore functions are called along with the */
+/* expiration functions. */
+/* */
+/* INPUT */
+/* */
+/* None */
+/* */
+/* OUTPUT */
+/* */
+/* None */
+/* */
+/* CALLS */
+/* */
+/* _tx_thread_time_slice Time slice interrupted thread */
+/* _tx_timer_expiration_process Timer expiration processing */
+/* _tx_win32_critical_section_obtain Obtain critical section */
+/* _tx_win32_critical_section_release Release critical section */
+/* */
+/* CALLED BY */
+/* */
+/* interrupt vector */
+/* */
+/**************************************************************************/
+VOID _tx_timer_interrupt(VOID)
+{
+
+
+ /* Enter critical section to ensure other threads are not playing with
+ the core ThreadX data structures. */
+ _tx_win32_critical_section_obtain(&_tx_win32_critical_section);
+
+ /* Debug entry. */
+ _tx_win32_debug_entry_insert("TIMER INTERRUPT", __FILE__, __LINE__);
+
+ /* Increment the system clock. */
+ _tx_timer_system_clock++;
+
+ /* Test for time-slice expiration. */
+ if (_tx_timer_time_slice)
+ {
+
+ /* Decrement the time_slice. */
+ _tx_timer_time_slice--;
+
+ /* Check for expiration. */
+ if (_tx_timer_time_slice == 0)
+ {
+
+ /* Set the time-slice expired flag. */
+ _tx_timer_expired_time_slice = TX_TRUE;
+ }
+ }
+
+ /* Test for timer expiration. */
+ if (*_tx_timer_current_ptr)
+ {
+
+ /* Set expiration flag. */
+ _tx_timer_expired = TX_TRUE;
+ }
+ else
+ {
+
+ /* No timer expired, increment the timer pointer. */
+ _tx_timer_current_ptr++;
+
+ /* Check for wrap-around. */
+ if (_tx_timer_current_ptr == _tx_timer_list_end)
+ {
+
+ /* Wrap to beginning of list. */
+ _tx_timer_current_ptr = _tx_timer_list_start;
+ }
+ }
+
+ /* See if anything has expired. */
+ if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+ {
+
+ /* Did a timer expire? */
+ if (_tx_timer_expired)
+ {
+
+ /* Process timer expiration. */
+ _tx_timer_expiration_process();
+ }
+
+ /* Did time slice expire? */
+ if (_tx_timer_expired_time_slice)
+ {
+
+ /* Time slice interrupted thread. */
+ _tx_thread_time_slice();
+ }
+ }
+
+ /* Exit Win32 critical section. */
+ _tx_win32_critical_section_release(&_tx_win32_critical_section);
+}
+
+