Skip to content

Commit 359595d

Browse files
committed
Add RISC-V32 arch. port layer
This update adapts the ThreadX low-level kernel routines for RV32, including: - startup and initialization logic - context save/restore implementations - interrupt control and scheduler entry - thread stack build and system return paths - timer interrupt handling These changes provide full low-level support needed to run ThreadX on RISC-V32 targets. Signed-off-by: Akif Ejaz <akif.ejaz@10xengineers.ai>
1 parent c4ad279 commit 359595d

12 files changed

+2055
-0
lines changed

cmake/riscv32-unknown-elf.cmake

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Toolchain settings
2+
set(CMAKE_C_COMPILER riscv32-unknown-elf-gcc)
3+
set(CMAKE_CXX_COMPILER riscv32-unknown-elf-g++)
4+
set(AS riscv32-unknown-elf-as)
5+
set(AR riscv32-unknown-elf-ar)
6+
set(OBJCOPY riscv32-unknown-elf-objcopy)
7+
set(OBJDUMP riscv32-unknown-elf-objdump)
8+
set(SIZE riscv32-unknown-elf-size)
9+
10+
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
11+
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
12+
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
13+
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
14+
15+
# this makes the test compiles use static library option so that we don't need to pre-set linker flags and scripts
16+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
17+
18+
set(CMAKE_C_FLAGS "${CFLAGS}" CACHE INTERNAL "c compiler flags")
19+
set(CMAKE_CXX_FLAGS "${CXXFLAGS}" CACHE INTERNAL "cxx compiler flags")
20+
set(CMAKE_ASM_FLAGS "${ASFLAGS} -D__ASSEMBLER__ -D__riscv_float_abi_single" CACHE INTERNAL "asm compiler flags")
21+
set(CMAKE_EXE_LINKER_FLAGS "${LDFLAGS}" CACHE INTERNAL "exe link flags")
22+
23+
SET(CMAKE_C_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "c debug compiler flags")
24+
SET(CMAKE_CXX_FLAGS_DEBUG "-Og -g -ggdb3" CACHE INTERNAL "cxx debug compiler flags")
25+
SET(CMAKE_ASM_FLAGS_DEBUG "-g -ggdb3" CACHE INTERNAL "asm debug compiler flags")
26+
27+
SET(CMAKE_C_FLAGS_RELEASE "-O3" CACHE INTERNAL "c release compiler flags")
28+
SET(CMAKE_CXX_FLAGS_RELEASE "-O3" CACHE INTERNAL "cxx release compiler flags")
29+
SET(CMAKE_ASM_FLAGS_RELEASE "" CACHE INTERNAL "asm release compiler flags")

cmake/riscv32_gnu.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Name of the target
2+
set(CMAKE_SYSTEM_NAME Generic)
3+
set(CMAKE_SYSTEM_PROCESSOR risc-v32)
4+
5+
set(THREADX_ARCH "risc-v32")
6+
set(THREADX_TOOLCHAIN "gnu")
7+
set(ARCH_FLAGS "-g -march=rv32gc -mabi=ilp32d -mcmodel=medany")
8+
set(CFLAGS "${ARCH_FLAGS}")
9+
set(ASFLAGS "${ARCH_FLAGS}")
10+
set(LDFLAGS "${ARCH_FLAGS}")
11+
12+
include(${CMAKE_CURRENT_LIST_DIR}/riscv32-unknown-elf.cmake)

ports/risc-v32/gnu/CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
target_sources(${PROJECT_NAME}
3+
PRIVATE
4+
# {{BEGIN_TARGET_SOURCES}}
5+
${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.S
6+
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_restore.S
7+
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_save.S
8+
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.S
9+
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.S
10+
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.S
11+
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S
12+
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.c
13+
# {{END_TARGET_SOURCES}}
14+
)
15+
16+
target_include_directories(${PROJECT_NAME}
17+
PUBLIC
18+
${CMAKE_CURRENT_LIST_DIR}/inc
19+
)

ports/risc-v32/gnu/inc/tx_port.h

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
/***************************************************************************
2+
* Copyright (c) 2025 10xEngineers
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the MIT License which is available at
6+
* https://opensource.org/licenses/MIT.
7+
*
8+
* SPDX-License-Identifier: MIT
9+
**************************************************************************/
10+
11+
12+
/**************************************************************************/
13+
/**************************************************************************/
14+
/** */
15+
/** ThreadX Component */
16+
/** */
17+
/** Port Specific */
18+
/** */
19+
/**************************************************************************/
20+
/**************************************************************************/
21+
22+
23+
/**************************************************************************/
24+
/* */
25+
/* PORT SPECIFIC C INFORMATION RELEASE */
26+
/* */
27+
/* tx_port.h RISC-V32/GNU */
28+
/* 6.4.x */
29+
/* */
30+
/* AUTHOR */
31+
/* */
32+
/* Akif Ejaz, 10xEngineers */
33+
/* */
34+
/* DESCRIPTION */
35+
/* */
36+
/* This file contains data type definitions that make the ThreadX */
37+
/* real-time kernel function identically on a variety of different */
38+
/* processor architectures. For example, the size or number of bits */
39+
/* in an "int" data type vary between microprocessor architectures and */
40+
/* even C compilers for the same microprocessor. ThreadX does not */
41+
/* directly use native C data types. Instead, ThreadX creates its */
42+
/* own special types that can be mapped to actual data types by this */
43+
/* file to guarantee consistency in the interface and functionality. */
44+
/* */
45+
/* RELEASE HISTORY */
46+
/* */
47+
/* DATE NAME DESCRIPTION */
48+
/* */
49+
/* 23-12-2025 Akif Ejaz Initial Version 6.4.x */
50+
/* */
51+
/**************************************************************************/
52+
53+
#ifndef TX_PORT_H
54+
#define TX_PORT_H
55+
56+
#ifdef __ASSEMBLER__
57+
58+
59+
#if __riscv_xlen == 64
60+
# define SLL32 sllw
61+
# define STORE sd
62+
# define LOAD ld
63+
# define LWU lwu
64+
# define LOG_REGBYTES 3
65+
#else
66+
# define SLL32 sll
67+
# define STORE sw
68+
# define LOAD lw
69+
# define LWU lw
70+
# define LOG_REGBYTES 2
71+
#endif
72+
#define REGBYTES (1 << LOG_REGBYTES)
73+
74+
#else /*not __ASSEMBLER__ */
75+
76+
/* Include for memset. */
77+
#include <string.h>
78+
79+
80+
/* Determine if the optional ThreadX user define file should be used. */
81+
82+
#ifdef TX_INCLUDE_USER_DEFINE_FILE
83+
84+
85+
/* Yes, include the user defines in tx_user.h. The defines in this file may
86+
alternately be defined on the command line. */
87+
88+
#include "tx_user.h"
89+
#endif
90+
91+
92+
/* Define compiler library include files. */
93+
94+
95+
/* Define ThreadX basic types for this port. */
96+
97+
#define VOID void
98+
typedef char CHAR;
99+
typedef unsigned char UCHAR;
100+
typedef int INT;
101+
typedef unsigned int UINT;
102+
typedef long LONG;
103+
typedef unsigned long ULONG;
104+
typedef unsigned long long ULONG64;
105+
typedef short SHORT;
106+
typedef unsigned short USHORT;
107+
#define ULONG64_DEFINED
108+
#define ALIGN_TYPE_DEFINED
109+
#define ALIGN_TYPE ULONG64
110+
111+
112+
113+
114+
/* Define the priority levels for ThreadX. Legal values range
115+
from 32 to 1024 and MUST be evenly divisible by 32. */
116+
117+
#ifndef TX_MAX_PRIORITIES
118+
#define TX_MAX_PRIORITIES 32
119+
#endif
120+
121+
122+
/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
123+
thread creation is less than this value, the thread create call will return an error. */
124+
125+
#ifndef TX_MINIMUM_STACK
126+
#define TX_MINIMUM_STACK 1024 /* Minimum stack size for this port */
127+
#endif
128+
129+
130+
/* Define the system timer thread's default stack size and priority. These are only applicable
131+
if TX_TIMER_PROCESS_IN_ISR is not defined. */
132+
133+
#ifndef TX_TIMER_THREAD_STACK_SIZE
134+
#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
135+
#endif
136+
137+
#ifndef TX_TIMER_THREAD_PRIORITY
138+
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
139+
#endif
140+
141+
142+
/* Define various constants for the ThreadX RISC-V port. */
143+
144+
#define TX_INT_DISABLE 0x00000000 /* Disable interrupts value */
145+
#define TX_INT_ENABLE 0x00000008 /* Enable interrupt value */
146+
147+
148+
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
149+
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
150+
source constants would be:
151+
152+
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
153+
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
154+
155+
*/
156+
157+
#ifndef TX_TRACE_TIME_SOURCE
158+
#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
159+
#endif
160+
#ifndef TX_TRACE_TIME_MASK
161+
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
162+
#endif
163+
164+
165+
/* Define the port specific options for the _tx_build_options variable. This variable indicates
166+
how the ThreadX library was built. */
167+
168+
#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0
169+
170+
171+
/* Define the in-line initialization constant so that modules with in-line
172+
initialization capabilities can prevent their initialization from being
173+
a function call. */
174+
175+
#define TX_INLINE_INITIALIZATION
176+
177+
178+
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
179+
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
180+
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
181+
define is negated, thereby forcing the stack fill which is necessary for the stack checking
182+
logic. */
183+
184+
#ifdef TX_ENABLE_STACK_CHECKING
185+
#undef TX_DISABLE_STACK_FILLING
186+
#endif
187+
188+
189+
/* Define the TX_THREAD control block extensions for this port. The main reason
190+
for the multiple macros is so that backward compatibility can be maintained with
191+
existing ThreadX kernel awareness modules. */
192+
193+
#define TX_THREAD_EXTENSION_0
194+
#define TX_THREAD_EXTENSION_1
195+
#define TX_THREAD_EXTENSION_2
196+
#define TX_THREAD_EXTENSION_3
197+
198+
199+
/* Define the port extensions of the remaining ThreadX objects. */
200+
201+
#define TX_BLOCK_POOL_EXTENSION
202+
#define TX_BYTE_POOL_EXTENSION
203+
#define TX_EVENT_FLAGS_GROUP_EXTENSION
204+
#define TX_MUTEX_EXTENSION
205+
#define TX_QUEUE_EXTENSION
206+
#define TX_SEMAPHORE_EXTENSION
207+
#define TX_TIMER_EXTENSION
208+
209+
210+
/* Define the user extension field of the thread control block. Nothing
211+
additional is needed for this port so it is defined as white space. */
212+
213+
#ifndef TX_THREAD_USER_EXTENSION
214+
#define TX_THREAD_USER_EXTENSION
215+
#endif
216+
217+
218+
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
219+
tx_thread_shell_entry, and tx_thread_terminate. */
220+
221+
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
222+
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
223+
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
224+
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
225+
226+
227+
/* Define the ThreadX object creation extensions for the remaining objects. */
228+
229+
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
230+
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
231+
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
232+
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
233+
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
234+
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
235+
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
236+
237+
238+
/* Define the ThreadX object deletion extensions for the remaining objects. */
239+
240+
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
241+
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
242+
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
243+
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
244+
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
245+
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
246+
#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
247+
248+
249+
/* Define ThreadX interrupt lockout and restore macros for protection on
250+
access of critical kernel information. The restore interrupt macro must
251+
restore the interrupt posture of the running thread prior to the value
252+
present prior to the disable macro. In most cases, the save area macro
253+
is used to define a local function save area for the disable and restore
254+
macros. */
255+
256+
#ifdef TX_DISABLE_INLINE
257+
258+
ULONG64 _tx_thread_interrupt_control(unsigned int new_posture);
259+
260+
#define TX_INTERRUPT_SAVE_AREA register ULONG64 interrupt_save;
261+
262+
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
263+
#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
264+
265+
#else
266+
267+
#define TX_INTERRUPT_SAVE_AREA ULONG64 interrupt_save;
268+
/* Atomically read mstatus into interrupt_save and clear bit 3 of mstatus. */
269+
#define TX_DISABLE {__asm__ ("csrrci %0, mstatus, 0x08" : "=r" (interrupt_save) : );};
270+
/* We only care about mstatus.mie (bit 3), so mask interrupt_save and write to mstatus. */
271+
#define TX_RESTORE {register ULONG64 __tempmask = interrupt_save & 0x08; \
272+
__asm__ ("csrrs x0, mstatus, %0 \n\t" : : "r" (__tempmask) : );};
273+
274+
#endif
275+
276+
277+
/* Define the interrupt lockout macros for each ThreadX object. */
278+
279+
#define TX_BLOCK_POOL_DISABLE TX_DISABLE
280+
#define TX_BYTE_POOL_DISABLE TX_DISABLE
281+
#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
282+
#define TX_MUTEX_DISABLE TX_DISABLE
283+
#define TX_QUEUE_DISABLE TX_DISABLE
284+
#define TX_SEMAPHORE_DISABLE TX_DISABLE
285+
286+
287+
/* Define the version ID of ThreadX. This may be utilized by the application. */
288+
289+
#ifdef TX_THREAD_INIT
290+
CHAR _tx_version_id[] =
291+
"Copyright (c) 2024 Microsoft Corporation. * ThreadX RISC-V32/GNU Version 6.4.2 *";
292+
#else
293+
extern CHAR _tx_version_id[];
294+
#endif
295+
296+
#endif /*not __ASSEMBLER__ */
297+
#endif

0 commit comments

Comments
 (0)