Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/riscv32-unknown-elf.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ set(CMAKE_CXX_FLAGS "${CXXFLAGS}" CACHE INTERNAL "cxx compiler flags")
if(DEFINED SOFT_FLOAT)
set(CMAKE_ASM_FLAGS "${ASFLAGS} -D__ASSEMBLER__" CACHE INTERNAL "asm compiler flags")
else()
set(CMAKE_ASM_FLAGS "${ASFLAGS} -D__ASSEMBLER__ -D__riscv_float_abi_single" CACHE INTERNAL "asm compiler flags")
set(CMAKE_ASM_FLAGS "${ASFLAGS} -D__ASSEMBLER__" CACHE INTERNAL "asm compiler flags")
endif()

set(CMAKE_EXE_LINKER_FLAGS "${LDFLAGS}" CACHE INTERNAL "exe link flags")
Expand Down
2 changes: 1 addition & 1 deletion cmake/riscv32_gnu.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set(THREADX_ARCH "risc-v32")
set(THREADX_TOOLCHAIN "gnu")
if(DEFINED SOFT_FLOAT)
set(ARCH_FLAGS "-g -march=rv32ima_zicsr -mabi=ilp32 -mcmodel=medany")
set(CACHE{SOFT_FLOAT} FORCE 1)
set(SOFT_FLOAT 1 CACHE BOOL "build the soft-float rv32ima_zicsr/ilp32 configuration" FORCE)
else()
set(ARCH_FLAGS "-g -march=rv32gc -mabi=ilp32d -mcmodel=medany -mrelax")
endif()
Expand Down
4 changes: 4 additions & 0 deletions ports/risc-v32/gnu/example_build/qemu_virt/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Ignore generated QEMU test files.
kernel.elf
qemu-riscv32.log
test_cmds.gdb
24 changes: 19 additions & 5 deletions ports/risc-v32/gnu/example_build/qemu_virt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ add_executable(kernel.elf EXCLUDE_FROM_ALL
${QEMU_DEMO_DIR}/tx_initialize_low_level.S
)

target_link_libraries(kernel.elf PRIVATE threadx)
target_link_libraries(kernel.elf PRIVATE threadx gcc)

target_include_directories(kernel.elf PRIVATE
${CMAKE_SOURCE_DIR}/common/inc
Expand All @@ -28,18 +28,32 @@ target_link_options(kernel.elf PRIVATE
# QEMU/GDB functional test runner. Optional: skipped silently if the
# host has no Python 3 interpreter on PATH.
find_package(Python3 COMPONENTS Interpreter)
if(Python3_FOUND)
# The runner needs a GDB that understands riscv:rv32 remote targets
find_program(RISCV32_GDB NAMES riscv32-unknown-elf-gdb gdb-multiarch)
find_program(RISCV32_QEMU NAMES qemu-system-riscv32)
if(Python3_FOUND AND RISCV32_GDB AND RISCV32_QEMU)
set(RISCV32_QEMU_TEST_ARGS)
if(SOFT_FLOAT)
list(APPEND RISCV32_QEMU_TEST_ARGS --skip-fpu)
endif()
add_custom_target(check-functional-riscv32
COMMAND ${Python3_EXECUTABLE}
${QEMU_DEMO_DIR}/test/threadx_test_tx_gnu_riscv32_qemu.py
--elf $<TARGET_FILE:kernel.elf>
--qemu qemu-system-riscv32
--gdb gdb
--qemu ${RISCV32_QEMU}
--gdb ${RISCV32_GDB}
${RISCV32_QEMU_TEST_ARGS}
DEPENDS kernel.elf
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Running RISC-V32 QEMU/GDB functional test runner..."
)
else()
elseif(NOT Python3_FOUND)
message(STATUS
"Python3 not found; check-functional-riscv32 target unavailable.")
elseif(NOT RISCV32_GDB)
message(STATUS
"RISC-V GDB not found; check-functional-riscv32 target unavailable.")
else()
message(STATUS
"qemu-system-riscv32 not found; check-functional-riscv32 target unavailable.")
endif()
14 changes: 6 additions & 8 deletions ports/risc-v32/gnu/example_build/qemu_virt/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,13 @@
#include <stdint.h>
#include <stddef.h>

void *memset(const void *des, int c,size_t n)
void *memset(void *des, int c, size_t n)
{
if((des == NULL) || n <=0)
return (void*)des;
char* t = (char*)des;
int i;
for(i=0;i<n;i++)
t[i]=c;
return t;
unsigned char *target = des;

for (size_t i = 0; i < n; i++)
target[i] = (unsigned char)c;
return des;
}


Expand Down
4 changes: 4 additions & 0 deletions ports/risc-v32/gnu/example_build/qemu_virt/demo_threadx.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
#define DEMO_BYTE_POOL_SIZE 9120
#define DEMO_BLOCK_POOL_SIZE 100
#define DEMO_QUEUE_SIZE 100
#ifdef __riscv_flen
float fpu_test_val = 0.0f;
#endif

char *_to_str(ULONG val)
{
Expand Down Expand Up @@ -375,8 +377,10 @@ UINT status;
if (status != TX_SUCCESS)
break;

#ifdef __riscv_flen
/* FPU Test */
fpu_test_val += 1.1f;
#endif
/* Get the mutex again with suspension. This shows
that an owning thread may retrieve the mutex it
owns multiple times. */
Expand Down
69 changes: 59 additions & 10 deletions ports/risc-v32/gnu/example_build/qemu_virt/hwtimer.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,77 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

#include "tx_port.h"
#include "tx_api.h"
#include "csr.h"
#include "hwtimer.h"

#define CLINT (0x02000000L)
#define CLINT_TIME (CLINT+0xBFF8)
#define CLINT_TIMECMP(hart_id) (CLINT+0x4000+8*(hart_id))

/* RV32 has no 64-bit load/store, so the 64-bit CLINT registers are
accessed as two volatile 32-bit MMIO words. */
#define MTIME_LO (*(volatile uint32_t *)(CLINT_TIME))
#define MTIME_HI (*(volatile uint32_t *)(CLINT_TIME + 4))
#define MTIMECMP_LO(hart) (*(volatile uint32_t *)(CLINT_TIMECMP(hart)))
#define MTIMECMP_HI(hart) (*(volatile uint32_t *)(CLINT_TIMECMP(hart) + 4))

/* RV32 mtime re-read the high word until it is stable, so a
low-word rollover between the two loads cannot tear the value. */
static uint64_t clint_time_read(void)
{
uint32_t hi;
uint32_t lo;

do
{
hi = MTIME_HI;
lo = MTIME_LO;
} while (hi != MTIME_HI);

return ((uint64_t)hi << 32) | lo;
}

/* Only this hart writes its own mtimecmp, so a plain two-word read
cannot tear. */
static uint64_t clint_timecmp_read(int hart)
{
uint32_t lo = MTIMECMP_LO(hart);
uint32_t hi = MTIMECMP_HI(hart);

return ((uint64_t)hi << 32) | lo;
}

/* RV32 mtimecmp write, safe sequence: park the low word at all-ones
first, so no intermediate 64-bit value compares below mtime and
raises a spurious timer interrupt. */
static void clint_timecmp_write(int hart, uint64_t value)
{
MTIMECMP_LO(hart) = 0xFFFFFFFF;
MTIMECMP_HI(hart) = (uint32_t)(value >> 32);
MTIMECMP_LO(hart) = (uint32_t)value;
}

int hwtimer_init(void)
{
int hart = riscv_get_core();
uint64_t time = *((uint64_t*)CLINT_TIME);
*((uint64_t*)CLINT_TIMECMP(hart)) = time + TICKNUM_PER_TIMER;
return 0;
int hart = riscv_get_core();

clint_timecmp_write(hart, clint_time_read() + TICKNUM_PER_TIMER);
return 0;
}

int hwtimer_handler(void)
{
int hart = riscv_get_core();
uint64_t time = *((uint64_t*)CLINT_TIME);
*((uint64_t*)CLINT_TIMECMP(hart)) = time + TICKNUM_PER_TIMER;
return 0;
}
int hart = riscv_get_core();

/* Advance from the previous compare value, so trap
latency does not accumulate as tick drift */
uint64_t next = clint_timecmp_read(hart) + TICKNUM_PER_TIMER;
uint64_t now = clint_time_read();

if (next <= now)
next = now + TICKNUM_PER_TIMER;

clint_timecmp_write(hart, next);
return 0;
}
4 changes: 2 additions & 2 deletions ports/risc-v32/gnu/example_build/qemu_virt/hwtimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

#include <stdint.h>

#define TICKNUM_PER_SECOND 10000000
#define TICKNUM_PER_TIMER (TICKNUM_PER_SECOND / 10)
#define TICKNUM_PER_SECOND 10000000UL
#define TICKNUM_PER_TIMER (TICKNUM_PER_SECOND / TX_TIMER_TICKS_PER_SECOND)

int hwtimer_init(void);
int hwtimer_handler(void);
Expand Down
21 changes: 14 additions & 7 deletions ports/risc-v32/gnu/example_build/qemu_virt/link.lds
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
OUTPUT_ARCH( "riscv" )
ENTRY( _start )

PHDRS
{
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(6);
}

SECTIONS
{
/*
Expand All @@ -14,15 +20,16 @@ SECTIONS
*(.text .text.*)
. = ALIGN(0x1000);
PROVIDE(etext = .);
}
} :text

.rodata : {
. = ALIGN(16);
*(.srodata .srodata.*) /* do not need to distinguish this from .rodata */
. = ALIGN(16);
*(.rodata .rodata.*)
}
} :text

. = ALIGN(0x1000);
.data : {
. = ALIGN(16);
/* Centre __global_pointer$ in the small-data window so the +/-2 KiB
Expand All @@ -31,23 +38,23 @@ SECTIONS
*(.sdata .sdata.*) /* do not need to distinguish this from .data */
. = ALIGN(16);
*(.data .data.*)
}
} :data

.bss : {
.bss (NOLOAD) : {
. = ALIGN(16);
_bss_start = .;
*(.sbss .sbss.*) /* do not need to distinguish this from .bss */
. = ALIGN(16);
*(.bss .bss.*)
_bss_end = .;
}
} :data

.stack : {
.stack (NOLOAD) : {
. = ALIGN(4096);
_sysstack_start = .;
. += 0x1000;
_sysstack_end = .;
}
} :data

PROVIDE(_end = .);
}
Loading