From 614fe9c674b66e1cfe02b61871938df52bac82d4 Mon Sep 17 00:00:00 2001 From: Patrick Siegl <3261314+psiegl@users.noreply.github.com> Date: Wed, 20 May 2026 18:28:51 +0200 Subject: [PATCH 1/4] a653lib offering WAMR & Wasmtime CLIs with APEX support --- .github/workflows/nix.yaml | 78 ++++ CMakeLists.txt | 325 ++++++++++++++++- a653_config.h | 5 + a653_inc/a653Error.h | 5 + a653_inc/a653Init.h | 4 + a653_inc/a653Lib.h | 4 + a653_inc/a653Partition.h | 2 + a653_inc/a653Process.h | 20 ++ a653_inc/a653Queuing.h | 11 + a653_inc/a653Sampling.h | 17 +- a653_inc/a653Semaphore.h | 5 + a653_inc/a653Time.h | 6 + a653_inc/a653Type.h | 7 + a653_lib/a653_i_process.c | 2 +- a653_lib/a653_i_sync.c | 44 ++- a653_lib_wasm32/a653_wamr.c | 160 +++++++++ a653_lib_wasm32/a653_wamr.h | 18 + a653_lib_wasm32/a653_wasmtime.c | 265 ++++++++++++++ a653_lib_wasm32/a653_wasmtime.h | 20 ++ a653_lib_wasm32/apex_host_fncs_wasm32.c | 110 ++++++ a653_lib_wasm32/apex_host_fncs_wasm32.h | 33 ++ .../arinc653_part1_apex_blackboard_wasm32.c | 137 ++++++++ .../arinc653_part1_apex_blackboard_wasm32.h | 26 ++ .../arinc653_part1_apex_buffer_wasm32.c | 131 +++++++ .../arinc653_part1_apex_buffer_wasm32.h | 24 ++ .../arinc653_part1_apex_error_wasm32.c | 142 ++++++++ .../arinc653_part1_apex_error_wasm32.h | 24 ++ .../arinc653_part1_apex_event_wasm32.c | 121 +++++++ .../arinc653_part1_apex_event_wasm32.h | 26 ++ .../arinc653_part1_apex_mutex_wasm32.c | 152 ++++++++ .../arinc653_part1_apex_mutex_wasm32.h | 28 ++ .../arinc653_part1_apex_partition_wasm32.c | 49 +++ .../arinc653_part1_apex_partition_wasm32.h | 18 + .../arinc653_part1_apex_process_wasm32.c | 332 ++++++++++++++++++ .../arinc653_part1_apex_process_wasm32.h | 48 +++ .../arinc653_part1_apex_queuing_port_wasm32.c | 141 ++++++++ .../arinc653_part1_apex_queuing_port_wasm32.h | 26 ++ ...arinc653_part1_apex_sampling_port_wasm32.c | 119 +++++++ ...arinc653_part1_apex_sampling_port_wasm32.h | 24 ++ .../arinc653_part1_apex_semaphore_wasm32.c | 106 ++++++ .../arinc653_part1_apex_semaphore_wasm32.h | 24 ++ .../arinc653_part1_apex_time_wasm32.c | 67 ++++ .../arinc653_part1_apex_time_wasm32.h | 22 ++ ...art2_apex_sampling_port_extension_wasm32.c | 87 +++++ ...art2_apex_sampling_port_extension_wasm32.h | 20 ++ a653_lib_wasm32/arinc653_wasm32_helper.h | 78 ++++ a653_lib_wasm32/generic_helper.c | 75 ++++ a653_lib_wasm32/generic_helper.h | 30 ++ a653_lib_wasm32/wasm32_main.c | 54 +++ flake.lock | 102 +++++- flake.nix | 24 +- partition_a.c | 19 +- partition_b.c | 16 +- pkgs/a653lib.nix | 39 +- scripts/process-arinc-header.awk | 6 +- scripts/split-arinc-header.awk | 2 +- 56 files changed, 3436 insertions(+), 44 deletions(-) create mode 100644 a653_lib_wasm32/a653_wamr.c create mode 100644 a653_lib_wasm32/a653_wamr.h create mode 100644 a653_lib_wasm32/a653_wasmtime.c create mode 100644 a653_lib_wasm32/a653_wasmtime.h create mode 100644 a653_lib_wasm32/apex_host_fncs_wasm32.c create mode 100644 a653_lib_wasm32/apex_host_fncs_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_blackboard_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_blackboard_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_buffer_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_buffer_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_error_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_error_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_event_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_event_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_mutex_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_mutex_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_partition_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_partition_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_process_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_process_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_queuing_port_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_queuing_port_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_sampling_port_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_sampling_port_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_semaphore_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_semaphore_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part1_apex_time_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part1_apex_time_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_part2_apex_sampling_port_extension_wasm32.c create mode 100644 a653_lib_wasm32/arinc653_part2_apex_sampling_port_extension_wasm32.h create mode 100644 a653_lib_wasm32/arinc653_wasm32_helper.h create mode 100644 a653_lib_wasm32/generic_helper.c create mode 100644 a653_lib_wasm32/generic_helper.h create mode 100644 a653_lib_wasm32/wasm32_main.c diff --git a/.github/workflows/nix.yaml b/.github/workflows/nix.yaml index b2fe9ad..a144cfc 100644 --- a/.github/workflows/nix.yaml +++ b/.github/workflows/nix.yaml @@ -18,6 +18,84 @@ jobs: - uses: DeterminateSystems/magic-nix-cache-action@main - name: Build run: nix build .#packages.x86_64-linux.a653lib --print-build-logs + x86_64-ubuntu-linux---a653lib-wasm: + name: x86_64-ubuntu-linux.a653lib-wasm + runs-on: + - ubuntu-latest + needs: [] + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y curl cmake cargo clang llvm libclang-dev gawk + + - name: Install WebAssembly Micro Runtime (WAMR) + run: | + git clone https://github.com/bytecodealliance/wasm-micro-runtime.git ~/wasm-micro-runtime + cd ~/wasm-micro-runtime + git checkout WAMR-2.4.4 + + mkdir build && cd build + cmake .. \ + -DWAMR_BUILD_LIBC_BUILTIN=1 \ + -DWAMR_BUILD_LIBC_WASI=1 \ + -DWAMR_BUILD_SHARED_MEMORY=1 \ + -DCMAKE_BUILD_TYPE=Release + make + sudo make install + + - name: Install Wasmtime C API + run: | + # Motivated by https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=libwasmtime + + curl -L https://github.com/bytecodealliance/wasmtime/releases/download/v45.0.0/wasmtime-v45.0.0-x86_64-linux-c-api.tar.xz -o wasmtime-v45.0.0-x86_64-linux-c-api.tar.xz + tar -xf wasmtime-v45.0.0-x86_64-linux-c-api.tar.xz + + cd wasmtime-v45.0.0-x86_64-linux-c-api + sudo cp -a include/. /usr/local/include/ + sudo cp -a lib/. /usr/local/lib + sudo ldconfig + + - name: Install wasi-sdk + run: | + curl -L https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-33/wasi-sdk-33.0-x86_64-linux.deb -o wasi-sdk.deb + sudo dpkg -i wasi-sdk.deb + rm wasi-sdk.deb + + ls -l /opt/wasi-sdk* + + - name: Configure + run: | + cmake -S . -B build-wasm \ + -G "Unix Makefiles" \ + -DA653LIB_BUILD_WASM=ON \ + -DWASI_SYSROOT=/opt/wasi-sdk/share/wasi-sysroot \ + -DWASM_CLANG=/opt/wasi-sdk/bin/clang + + - name: Build + run: | + cmake --build build-wasm --target wasm + + - name: Exec. a653lib employing WebAssembly Micro Runtime (WAMR) lib. to execute Wasm partition A & B + continue-on-error: true + run: | + cd build-wasm + + # the a653lib main is executing a 'wasm32_rt', which can be any APEX-enabled Wasm interpreter. + ln -sf p_wamr wasm32_rt + timeout 1m ./a653_main_wasm + + - name: Exec. a653lib employing Wasmtime lib. to execute Wasm partition A & B + continue-on-error: true + run: | + cd build-wasm + + # the a653lib main is executing a 'wasm32_rt', which can be any APEX-enabled Wasm interpreter. + ln -sf p_wasmtime wasm32_rt + timeout 1m ./a653_main_wasm + x86_64-linux---a653lib-aarch64: name: x86_64-linux.a653lib-aarch64 runs-on: diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b09397..00c3c31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,9 +26,54 @@ else() endif() # -# Generated ARINC headers +### Options # +option(A653LIB_BUILD_WASM "Build wasm guest partitions and runtime launchers" OFF) +option(A653LIB_FETCH_C_ABI_LENS "Clone and build c-abi-lens automatically" ON) + +set( + WASI_SYSROOT + "/usr/share/wasi-sysroot" + CACHE PATH + "WASI sysroot used for wasm32-wasip1 guest compilation" +) + +set( + WASM_CLANG + "clang" + CACHE FILEPATH + "Clang executable used for wasm32-wasip1 guest compilation" +) + +set( + IWASM_LIBRARY + "" + CACHE FILEPATH + "Optional full path to libiwasm.a or shared lib for the WAMR launcher" +) + +set( + WASMTIME_LIBRARY + "" + CACHE FILEPATH + "Optional full path to libwasmtime for the Wasmtime launcher" +) + +set( + C_ABI_LENS_REPO_DIR + "${CMAKE_CURRENT_BINARY_DIR}/c-abi-lens-src" + CACHE PATH + "Location of the arinc653-wasm/c-abi-lens checkout" +) + +set( + C_ABI_LENS_EXECUTABLE + "" + CACHE FILEPATH + "Optional path to a prebuilt c-abi-lens executable" +) + set( ARINC653_ZIP "" @@ -36,6 +81,10 @@ set( "Path to a pre-fetched arinc653.h.zip archive. If set, CMake copies it into the build tree instead of downloading it." ) +# +### Generated ARINC headers +# + set(ARINC_URL "https://brx-content.fullsight.org/site/binaries/content/assets/itc/content/support-files/arinc653.h.zip" ) @@ -97,13 +146,22 @@ if(NOT EXISTS "${ARINC_RAW_HEADER}") endif() find_program(AWK_EXECUTABLE awk REQUIRED) +find_program(SED_EXECUTABLE sed REQUIRED) + +set(PROCESS_ARINC_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/process_arinc_header.sh") +file(WRITE "${PROCESS_ARINC_SCRIPT}" [=[ +#!/bin/sh +set -eu +exec awk -f "$1" "$2" > "$3" +]=]) +execute_process(COMMAND chmod +x "${PROCESS_ARINC_SCRIPT}") add_custom_command( OUTPUT "${ARINC_PATCHED_HEADER}" - COMMAND "${AWK_EXECUTABLE}" - -f "${CMAKE_CURRENT_SOURCE_DIR}/scripts/process-arinc-header.awk" + COMMAND "${PROCESS_ARINC_SCRIPT}" + "${CMAKE_CURRENT_SOURCE_DIR}/scripts/process-arinc-header.awk" "${ARINC_RAW_HEADER}" - > "${ARINC_PATCHED_HEADER}" + "${ARINC_PATCHED_HEADER}" DEPENDS "${ARINC_RAW_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/process-arinc-header.awk" @@ -132,7 +190,7 @@ add_dependencies(arinc_generated_headers arinc_headers) target_include_directories(arinc_generated_headers INTERFACE "${ARINC_GEN_DIR}") # -# Existing helper macro +### Existing helper macro # # Function to add a new ARINC 653 Partition executable @@ -202,6 +260,14 @@ target_sources( a653_inc/a653Type.h ) +target_include_directories( + a653lib + PUBLIC + a653_inc + PRIVATE + ${PRIVATE_INCLUDE_DIRS} +) + target_link_libraries(a653lib PUBLIC arinc_generated_headers) # Implementation dependent initialization code, to be linked into partitions. This lib has no @@ -230,6 +296,250 @@ list(APPEND EXECUTABLES a653lib_main) add_653_partition(partition_a) add_653_partition(partition_b partition_b.c) +# +### Wasm support +# + +if(A653LIB_BUILD_WASM) + set(A653_WASM_DIR "${CMAKE_CURRENT_SOURCE_DIR}/a653_lib_wasm32") + set(A653_WASM_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/a653_inc") + set(CAMW32_GETSET_HEADER "${CMAKE_CURRENT_BINARY_DIR}/camw32_getset.h") + + find_program(CLANG_EXECUTABLE NAMES "${WASM_CLANG}" clang REQUIRED) + find_program(GIT_EXECUTABLE git) + find_program(CARGO_EXECUTABLE cargo) + + find_library(IWASM_LIBRARY_AUTO NAMES iwasm) + find_library(WASMTIME_LIBRARY_AUTO NAMES wasmtime + HINTS /usr/local/lib + ) + + if(IWASM_LIBRARY) + set(IWASM_LINK "${IWASM_LIBRARY}") + elseif(IWASM_LIBRARY_AUTO) + set(IWASM_LINK "${IWASM_LIBRARY_AUTO}") + else() + set(IWASM_LINK iwasm) + endif() + + if(WASMTIME_LIBRARY) + set(WASMTIME_LINK "${WASMTIME_LIBRARY}") + elseif(WASMTIME_LIBRARY_AUTO) + set(WASMTIME_LINK "${WASMTIME_LIBRARY_AUTO}") + else() + set(WASMTIME_LINK wasmtime) + endif() + + add_custom_target( + wasm_headers + COMMAND "${CMAKE_COMMAND}" -E make_directory "${A653_WASM_INCLUDE_DIR}" + COMMAND "${CMAKE_COMMAND}" -E copy_directory + "${CMAKE_CURRENT_SOURCE_DIR}/a653_inc" + "${A653_WASM_INCLUDE_DIR}" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different + ${ARINC_SPLIT_HEADERS} + "${A653_WASM_INCLUDE_DIR}" + DEPENDS arinc_headers + COMMENT "Preparing merged include tree for wasm guest compilation" + ) + + if(C_ABI_LENS_EXECUTABLE) + set(C_ABI_LENS_BIN "${C_ABI_LENS_EXECUTABLE}") + add_custom_target(c_abi_lens_tool DEPENDS "${C_ABI_LENS_BIN}") + else() + set(C_ABI_LENS_SRC_DIR "${C_ABI_LENS_REPO_DIR}") + set(C_ABI_LENS_BIN "${C_ABI_LENS_SRC_DIR}/pkgs/c-abi-lens/target/debug/c-abi-lens") + + if(A653LIB_FETCH_C_ABI_LENS) + if(NOT GIT_EXECUTABLE) + message(FATAL_ERROR "git is required to fetch c-abi-lens") + endif() + if(NOT CARGO_EXECUTABLE) + message(FATAL_ERROR "cargo is required to build c-abi-lens") + endif() + + add_custom_command( + OUTPUT "${C_ABI_LENS_SRC_DIR}/pkgs/c-abi-lens/Cargo.toml" + COMMAND "${GIT_EXECUTABLE}" clone + "https://github.com/psiegl/arinc653-wasm.git" + --branch psiegl-old + "${C_ABI_LENS_SRC_DIR}" + VERBATIM + COMMENT "Cloning arinc653-wasm repository" + ) + + add_custom_command( + OUTPUT "${C_ABI_LENS_BIN}" + COMMAND "${CARGO_EXECUTABLE}" build + WORKING_DIRECTORY "${C_ABI_LENS_SRC_DIR}/pkgs/c-abi-lens" + DEPENDS "${C_ABI_LENS_SRC_DIR}/pkgs/c-abi-lens/Cargo.toml" + VERBATIM + COMMENT "Building c-abi-lens" + ) + + add_custom_target(c_abi_lens_tool DEPENDS "${C_ABI_LENS_BIN}") + else() + if(NOT EXISTS "${C_ABI_LENS_BIN}") + message( + FATAL_ERROR + "Set C_ABI_LENS_EXECUTABLE or enable A653LIB_FETCH_C_ABI_LENS" + ) + endif() + add_custom_target(c_abi_lens_tool DEPENDS "${C_ABI_LENS_BIN}") + endif() + endif() + + set(GEN_CAMW32_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/gen_camw32_getset.sh") + file(WRITE "${GEN_CAMW32_SCRIPT}" [=[ +#!/bin/sh +set -eu +tool="$1" +header="$2" +out="$3" +tmp="${out}.tmp" +"$tool" "$header" -- --target=wasm32-wasip1 > "$tmp" +sed 's|camw|camw32|g' "$tmp" > "$out" +rm -f "$tmp" +]=]) + execute_process(COMMAND chmod +x "${GEN_CAMW32_SCRIPT}") + + add_custom_command( + OUTPUT "${CAMW32_GETSET_HEADER}" + COMMAND "${GEN_CAMW32_SCRIPT}" + "${C_ABI_LENS_BIN}" + "${A653_WASM_INCLUDE_DIR}/a653Lib.h" + "${CAMW32_GETSET_HEADER}" + DEPENDS + wasm_headers + c_abi_lens_tool + "${A653_WASM_INCLUDE_DIR}/a653Lib.h" + VERBATIM + COMMENT "Generating camw32_getset.h using c-abi-lens" + ) + + add_custom_target(camw32_getset DEPENDS "${CAMW32_GETSET_HEADER}") + + set(A653_WASM_GUESTS + partition_a + partition_b + ) + + set(A653_WASM_RUNTIME_COMMON_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/init.c" + "${A653_WASM_DIR}/generic_helper.c" + ) + + set(A653_WASM_RUNTIME_SPECIFIC_SOURCES + "${A653_WASM_DIR}/apex_host_fncs_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_time_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_process_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_partition_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_sampling_port_wasm32.c" + "${A653_WASM_DIR}/arinc653_part2_apex_sampling_port_extension_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_queuing_port_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_semaphore_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_error_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_buffer_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_event_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_blackboard_wasm32.c" + "${A653_WASM_DIR}/arinc653_part1_apex_mutex_wasm32.c" + "${A653_WASM_DIR}/wasm32_main.c" + ) + + add_executable(a653lib_main_wasm main.c) + target_link_libraries(a653lib_main_wasm PUBLIC a653lib) + target_include_directories( + a653lib_main_wasm + PRIVATE + ${PRIVATE_INCLUDE_DIRS} + "${A653_WASM_DIR}" + "${A653_WASM_INCLUDE_DIR}" + ) + target_compile_definitions(a653lib_main_wasm PRIVATE __WASM_RT__) + set_target_properties(a653lib_main_wasm PROPERTIES OUTPUT_NAME "a653_main_wasm") + add_dependencies(a653lib_main_wasm wasm_headers) + + add_executable( + p_wamr + ${A653_WASM_RUNTIME_COMMON_SOURCES} + ${A653_WASM_RUNTIME_SPECIFIC_SOURCES} + "${A653_WASM_DIR}/a653_wamr.c" + ) + target_link_libraries(p_wamr PRIVATE a653lib "${IWASM_LINK}" m) + target_include_directories( + p_wamr + PRIVATE + a653_lib + "${A653_WASM_DIR}" + "${A653_WASM_INCLUDE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}" + ) + target_compile_definitions(p_wamr PRIVATE __WAMR__) + add_dependencies(p_wamr wasm_headers camw32_getset) + + add_executable( + p_wasmtime + ${A653_WASM_RUNTIME_COMMON_SOURCES} + ${A653_WASM_RUNTIME_SPECIFIC_SOURCES} + "${A653_WASM_DIR}/a653_wasmtime.c" + ) + target_link_libraries(p_wasmtime PRIVATE a653lib "${WASMTIME_LINK}" m wasmtime) + target_include_directories( + p_wasmtime + PRIVATE + a653_lib + "${A653_WASM_DIR}" + "${A653_WASM_INCLUDE_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}" + ) + target_compile_definitions(p_wasmtime PRIVATE __WASMTIME__) + add_dependencies(p_wasmtime wasm_headers camw32_getset) + + set_target_properties(p_wamr p_wasmtime PROPERTIES + C_STANDARD 11 + C_STANDARD_REQUIRED YES + ) + + foreach(partition IN LISTS A653_WASM_GUESTS) + set(src "${CMAKE_CURRENT_SOURCE_DIR}/${partition}.c") + set(out "${CMAKE_CURRENT_BINARY_DIR}/${partition}.wasm") + set(layout "${CMAKE_CURRENT_BINARY_DIR}/${partition}.wasm32_struct_layout.txt") + + add_custom_command( + OUTPUT "${out}" "${layout}" + COMMAND + "${CLANG_EXECUTABLE}" + -I${A653_WASM_INCLUDE_DIR} + --target=wasm32-wasip1 + -Wl,--export-table + -Wl,--allow-undefined + --sysroot=${WASI_SYSROOT} + -o "${out}" + "${src}" + COMMAND + "${CMAKE_COMMAND}" -E touch "${layout}" + DEPENDS + wasm_headers + "${src}" + VERBATIM + COMMENT "Building wasm guest ${partition}.wasm" + ) + + add_custom_target("${partition}_wasm" DEPENDS "${out}") + list(APPEND WASM_TARGETS "${partition}_wasm") + install(FILES "${out}" DESTINATION bin) + endforeach() + + add_custom_target( + wasm + DEPENDS + a653lib_main_wasm + p_wamr + p_wasmtime + ${WASM_TARGETS} + ) +endif() + # ### Declare installables # @@ -237,5 +547,10 @@ add_653_partition(partition_b partition_b.c) # install the executables install(TARGETS ${EXECUTABLES} DESTINATION bin) +# install the wasm runtime tools when enabled +if(A653LIB_BUILD_WASM) + install(TARGETS a653lib_main_wasm p_wamr p_wasmtime DESTINATION bin) +endif() + # install the base and the partition init library, and the public header files install(TARGETS a653lib a653lib_partition_init FILE_SET a653lib_headers) diff --git a/a653_config.h b/a653_config.h index 97814e1..a1f3ba2 100644 --- a/a653_config.h +++ b/a653_config.h @@ -14,8 +14,13 @@ #define D_TIME_SLICE 1000000ll /* 1000000ns = 1ms */ +#ifdef __WASM_RT__ +#define PART_NAME_A "wasm32_rt partition_a.wasm" +#define PART_NAME_B "wasm32_rt partition_b.wasm" +#else #define PART_NAME_A "partition_a" #define PART_NAME_B "partition_b" +#endif #define A653_PARTITION_CONFIG_DEF { \ diff --git a/a653_inc/a653Error.h b/a653_inc/a653Error.h index 973ed8d..3627737 100644 --- a/a653_inc/a653Error.h +++ b/a653_inc/a653Error.h @@ -72,26 +72,31 @@ typedef /* function declarations */ +WASM_IMPORT_MODULE("arinc653") extern void REPORT_APPLICATION_MESSAGE ( /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, /*in */ MESSAGE_SIZE_TYPE LENGTH, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void CREATE_ERROR_HANDLER ( /*in */ SYSTEM_ADDRESS_TYPE ENTRY_POINT, /*in */ STACK_SIZE_TYPE STACK_SIZE, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_ERROR_STATUS ( /*out*/ ERROR_STATUS_TYPE *ERROR_STATUS, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void RAISE_APPLICATION_ERROR ( /*in */ ERROR_CODE_TYPE ERROR_CODE, /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, /*in */ ERROR_MESSAGE_SIZE_TYPE LENGTH, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void CONFIGURE_ERROR_HANDLER ( /*in */ ERROR_HANDLER_CONCURRENCY_CONTROL_TYPE CONCURRENCY_CONTROL, /*in */ PROCESSOR_CORE_ID_TYPE PROCESSOR_CORE_ID, diff --git a/a653_inc/a653Init.h b/a653_inc/a653Init.h index 4ef9a3f..100055c 100644 --- a/a653_inc/a653Init.h +++ b/a653_inc/a653Init.h @@ -30,6 +30,8 @@ #ifndef __A653INIT_H__ #define __A653INIT_H__ +#ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ + #include "a653Type.h" //#define S_TRACE 1 @@ -114,4 +116,6 @@ void a653_i_update_partitions(void); void setDebug(int level); void printDebug(int level,const char *format, ... ); +#endif /* #ifndef __wasm__ */ + #endif /* __A653INIT_H__ */ diff --git a/a653_inc/a653Lib.h b/a653_inc/a653Lib.h index a666762..7c935f1 100644 --- a/a653_inc/a653Lib.h +++ b/a653_inc/a653Lib.h @@ -45,7 +45,9 @@ #include #include /* autogenerated */ +#ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ #include +#endif /* #ifndef __wasm__ */ /* defines */ @@ -53,8 +55,10 @@ /* function declarations */ +#ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ extern int a653LibInit (); extern int a653MinimalLibInit (); +#endif /* #ifndef __wasm__ */ #endif /* __A653_LIB_H */ diff --git a/a653_inc/a653Partition.h b/a653_inc/a653Partition.h index 1d94fac..f48bb2f 100644 --- a/a653_inc/a653Partition.h +++ b/a653_inc/a653Partition.h @@ -57,10 +57,12 @@ typedef struct { NUM_CORES_TYPE NUM_ASSIGNED_CORES; } PARTITION_STATUS_TYPE; +WASM_IMPORT_MODULE("arinc653") extern void GET_PARTITION_STATUS ( /*out*/ PARTITION_STATUS_TYPE *PARTITION_STATUS, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void SET_PARTITION_MODE ( /*in */ OPERATING_MODE_TYPE OPERATING_MODE, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); diff --git a/a653_inc/a653Process.h b/a653_inc/a653Process.h index 44a74ca..f7c2f82 100644 --- a/a653_inc/a653Process.h +++ b/a653_inc/a653Process.h @@ -73,78 +73,97 @@ typedef struct { /* function declarations */ +WASM_IMPORT_MODULE("arinc653") extern void CREATE_PROCESS ( /*in */ PROCESS_ATTRIBUTE_TYPE *ATTRIBUTES, /*out*/ PROCESS_ID_TYPE *PROCESS_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void SET_PRIORITY ( /*in */ PROCESS_ID_TYPE PROCESS_ID, /*in */ PRIORITY_TYPE PRIORITY, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void SUSPEND_SELF ( /*in */ SYSTEM_TIME_TYPE TIME_OUT, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void SUSPEND ( /*in */ PROCESS_ID_TYPE PROCESS_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void RESUME ( /*in */ PROCESS_ID_TYPE PROCESS_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void STOP_SELF (void); +WASM_IMPORT_MODULE("arinc653") extern void STOP ( /*in */ PROCESS_ID_TYPE PROCESS_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void START ( /*in */ PROCESS_ID_TYPE PROCESS_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void DELAYED_START ( /*in */ PROCESS_ID_TYPE PROCESS_ID, /*in */ SYSTEM_TIME_TYPE DELAY_TIME, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void LOCK_PREEMPTION ( /*out*/ LOCK_LEVEL_TYPE *LOCK_LEVEL, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void UNLOCK_PREEMPTION ( /*out*/ LOCK_LEVEL_TYPE *LOCK_LEVEL, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_MY_ID ( /*out*/ PROCESS_ID_TYPE *PROCESS_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_PROCESS_ID ( /*in */ PROCESS_NAME_TYPE PROCESS_NAME, /*out*/ PROCESS_ID_TYPE *PROCESS_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_PROCESS_STATUS ( /*in */ PROCESS_ID_TYPE PROCESS_ID, /*out*/ PROCESS_STATUS_TYPE *PROCESS_STATUS, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void INITIALIZE_PROCESS_CORE_AFFINITY ( /*in */ PROCESS_ID_TYPE PROCESS_ID, /*in */ PROCESSOR_CORE_ID_TYPE PROCESSOR_CORE_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_MY_PROCESSOR_CORE_ID ( /*out*/ PROCESSOR_CORE_ID_TYPE *PROCESSOR_CORE_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_MY_INDEX ( /*out*/ PROCESS_INDEX_TYPE *PROCESS_INDEX, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); + +#ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ int a653_prcs_init(void); int a653_sync_prcs(void); @@ -157,5 +176,6 @@ extern void a653TimeMonitorProcGet (PROCESS_ID_TYPE PROCESS_ID, RETURN_CODE_TYPE * RETURN_CODE); extern PROCESS_ID_TYPE procIdFromTaskIdGet (int taskId); extern int taskIdFromProcIdGet (PROCESS_ID_TYPE procId); +#endif /* #ifndef */ #endif /* A653_PROCESS_H */ diff --git a/a653_inc/a653Queuing.h b/a653_inc/a653Queuing.h index 913d753..b615203 100644 --- a/a653_inc/a653Queuing.h +++ b/a653_inc/a653Queuing.h @@ -48,6 +48,8 @@ typedef struct { WAITING_RANGE_TYPE WAITING_PROCESSES; /* max number of processes */ } QUEUING_PORT_STATUS_TYPE; +/* Below is not even used anywhere */ +#ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ /*-----------------------------------------------*/ /* queuing port access function pointer types */ /*-----------------------------------------------*/ @@ -77,7 +79,9 @@ typedef struct q_port_funcs_t { } Q_PORT_FUNCS_TYPE; /* function declarations */ +#endif /* #ifndef __wasm__ */ +WASM_IMPORT_MODULE("arinc653") extern void CREATE_QUEUING_PORT ( /*in */ QUEUING_PORT_NAME_TYPE QUEUING_PORT_NAME, /*in */ MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE, @@ -87,6 +91,7 @@ extern void CREATE_QUEUING_PORT ( /*out*/ QUEUING_PORT_ID_TYPE *QUEUING_PORT_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void SEND_QUEUING_MESSAGE ( /*in */ QUEUING_PORT_ID_TYPE QUEUING_PORT_ID, /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, /* by reference */ @@ -94,6 +99,7 @@ extern void SEND_QUEUING_MESSAGE ( /*in */ SYSTEM_TIME_TYPE TIME_OUT, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void RECEIVE_QUEUING_MESSAGE ( /*in */ QUEUING_PORT_ID_TYPE QUEUING_PORT_ID, /*in */ SYSTEM_TIME_TYPE TIME_OUT, @@ -103,21 +109,25 @@ extern void RECEIVE_QUEUING_MESSAGE ( /*out*/ MESSAGE_SIZE_TYPE *LENGTH, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_QUEUING_PORT_ID ( /*in */ QUEUING_PORT_NAME_TYPE QUEUING_PORT_NAME, /*out*/ QUEUING_PORT_ID_TYPE *QUEUING_PORT_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_QUEUING_PORT_STATUS ( /*in */ QUEUING_PORT_ID_TYPE QUEUING_PORT_ID, /*out*/ QUEUING_PORT_STATUS_TYPE *QUEUING_PORT_STATUS, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void CLEAR_QUEUING_PORT ( /*in */ QUEUING_PORT_ID_TYPE QUEUING_PORT_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +#ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ void create_queuing_port_pp (QUEUING_PORT_NAME_TYPE QUEUING_PORT_NAME, MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE, MESSAGE_RANGE_TYPE MAX_NB_MESSAGE, @@ -137,5 +147,6 @@ void receive_queuing_message_pp (QUEUING_PORT_ID_TYPE QUEUING_PORT_ID, MESSAGE_ADDR_TYPE MESSAGE_ADDR, MESSAGE_SIZE_TYPE * LENGTH, RETURN_CODE_TYPE * RETURN_CODE); +#endif /* #ifndef __wasm__ */ #endif /* A653_QUEUING_H */ diff --git a/a653_inc/a653Sampling.h b/a653_inc/a653Sampling.h index 7306d9a..eb10cde 100644 --- a/a653_inc/a653Sampling.h +++ b/a653_inc/a653Sampling.h @@ -49,7 +49,7 @@ typedef enum VALIDITY_VALUE_TYPE { } VALIDITY_TYPE; /* sampling port status type */ -typedef struct SAMPLING_PORT_STATUS { +typedef struct SAMPLING_PORT_STATUS_TYPE { MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE; /* port size */ PORT_DIRECTION_TYPE PORT_DIRECTION; /* port direction */ SYSTEM_TIME_TYPE REFRESH_PERIOD; /* refresh period */ @@ -68,7 +68,7 @@ typedef enum AGE_VALUE_TYPE { } AGE_TYPE; /* sampling port status type */ -typedef struct SAMPLING_PORT_CURRENT_STATUS { +typedef struct SAMPLING_PORT_CURRENT_STATUS_TYPE { SYSTEM_TIME_TYPE REFRESH_PERIOD; /* refresh period */ SYSTEM_TIME_TYPE TIME_STAMP; /* when message was written */ MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE; /* port max byte size */ @@ -77,6 +77,8 @@ typedef struct SAMPLING_PORT_CURRENT_STATUS { UPDATED_TYPE UPDATED; /* empty, consumed, or new message */ } SAMPLING_PORT_CURRENT_STATUS_TYPE; +#ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ + /*-----------------------------------------------*/ /* sampling port access function pointer types */ /*-----------------------------------------------*/ @@ -110,7 +112,9 @@ typedef struct sample_port_funcs_s { /* function declarations */ void INIT_SAMPLING_PORT (RETURN_CODE_TYPE *RETURN_CODE); +#endif /* #ifndef __wasm__ */ +WASM_IMPORT_MODULE("arinc653") extern void CREATE_SAMPLING_PORT ( /*in */ SAMPLING_PORT_NAME_TYPE SAMPLING_PORT_NAME, /*in */ MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE, @@ -119,12 +123,14 @@ extern void CREATE_SAMPLING_PORT ( /*out*/ SAMPLING_PORT_ID_TYPE *SAMPLING_PORT_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void WRITE_SAMPLING_MESSAGE ( /*in */ SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID, /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, /* by reference */ /*in */ MESSAGE_SIZE_TYPE LENGTH, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void READ_SAMPLING_MESSAGE ( /*in */ SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID, /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, @@ -134,16 +140,19 @@ extern void READ_SAMPLING_MESSAGE ( /*out*/ VALIDITY_TYPE *VALIDITY, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_SAMPLING_PORT_ID ( /*in */ SAMPLING_PORT_NAME_TYPE SAMPLING_PORT_NAME, /*out*/ SAMPLING_PORT_ID_TYPE *SAMPLING_PORT_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_SAMPLING_PORT_STATUS ( /*in */ SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID, /*out*/ SAMPLING_PORT_STATUS_TYPE *SAMPLING_PORT_STATUS, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void READ_UPDATED_SAMPLING_MESSAGE ( /*in */ SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID, /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, @@ -154,12 +163,14 @@ extern void READ_UPDATED_SAMPLING_MESSAGE ( /*out*/ UPDATED_TYPE *UPDATED, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_SAMPLING_PORT_CURRENT_STATUS ( /*in */ SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID, /*out*/ SAMPLING_PORT_CURRENT_STATUS_TYPE *SAMPLING_PORT_CURRENT_STATUS, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void READ_SAMPLING_MESSAGE_CONDITIONAL ( /*in */ SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID, /*in */ SYSTEM_TIME_TYPE REF_TIME_STAMP, @@ -172,6 +183,7 @@ extern void READ_SAMPLING_MESSAGE_CONDITIONAL ( /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +#ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ void create_sampling_port_pp (SAMPLING_PORT_NAME_TYPE SAMPLING_PORT_NAME, MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE, PORT_DIRECTION_TYPE PORT_DIRECTION, @@ -189,5 +201,6 @@ void read_sampling_message_pp(SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID, MESSAGE_SIZE_TYPE * LENGTH, VALIDITY_TYPE * VALIDITY, RETURN_CODE_TYPE * RETURN_CODE); +#endif /* #ifndef __wasm__ */ #endif /* A653_SAMPLING_H */ diff --git a/a653_inc/a653Semaphore.h b/a653_inc/a653Semaphore.h index d84db69..cc4ca19 100644 --- a/a653_inc/a653Semaphore.h +++ b/a653_inc/a653Semaphore.h @@ -47,6 +47,7 @@ typedef struct { SEMAPHORE_VALUE_TYPE MAXIMUM_VALUE; WAITING_RANGE_TYPE WAITING_PROCESSES; } SEMAPHORE_STATUS_TYPE; +WASM_IMPORT_MODULE("arinc653") extern void CREATE_SEMAPHORE ( /*in */ SEMAPHORE_NAME_TYPE SEMAPHORE_NAME, /*in */ SEMAPHORE_VALUE_TYPE CURRENT_VALUE, @@ -55,20 +56,24 @@ extern void CREATE_SEMAPHORE ( /*out*/ SEMAPHORE_ID_TYPE *SEMAPHORE_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void WAIT_SEMAPHORE ( /*in */ SEMAPHORE_ID_TYPE SEMAPHORE_ID, /*in */ SYSTEM_TIME_TYPE TIME_OUT, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void SIGNAL_SEMAPHORE ( /*in */ SEMAPHORE_ID_TYPE SEMAPHORE_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_SEMAPHORE_ID ( /*in */ SEMAPHORE_NAME_TYPE SEMAPHORE_NAME, /*out*/ SEMAPHORE_ID_TYPE *SEMAPHORE_ID, /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_SEMAPHORE_STATUS ( /*in */ SEMAPHORE_ID_TYPE SEMAPHORE_ID, /*out*/ SEMAPHORE_STATUS_TYPE *SEMAPHORE_STATUS, diff --git a/a653_inc/a653Time.h b/a653_inc/a653Time.h index 987c21c..9dbd779 100644 --- a/a653_inc/a653Time.h +++ b/a653_inc/a653Time.h @@ -36,19 +36,25 @@ /* function declarations */ +#ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ extern void initTime(void); +#endif /* #ifndef __wasm__ */ +WASM_IMPORT_MODULE("arinc653") extern void TIMED_WAIT ( /*in */ SYSTEM_TIME_TYPE DELAY_TIME, /* 64bit - 1 nanosecond LSB */ /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void PERIODIC_WAIT ( /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void GET_TIME ( /*out*/ SYSTEM_TIME_TYPE *SYSTEM_TIME, /* 64bit - 1 nanosecond LSB */ /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +WASM_IMPORT_MODULE("arinc653") extern void REPLENISH ( /*in */ SYSTEM_TIME_TYPE BUDGET_TIME, /*out*/ RETURN_CODE_TYPE *RETURN_CODE); diff --git a/a653_inc/a653Type.h b/a653_inc/a653Type.h index f12bca7..be49a19 100644 --- a/a653_inc/a653Type.h +++ b/a653_inc/a653Type.h @@ -33,6 +33,13 @@ /* defines */ +/* clang attribute for the WebAssembly target */ +#ifdef __wasm__ +#define WASM_IMPORT_MODULE(name) __attribute__((import_module(name))) +#else +#define WASM_IMPORT_MODULE(name) +#endif + /* PORT queuing definition */ /* PORT sampling definition */ diff --git a/a653_lib/a653_i_process.c b/a653_lib/a653_i_process.c index e135053..6eb0714 100644 --- a/a653_lib/a653_i_process.c +++ b/a653_lib/a653_i_process.c @@ -61,7 +61,7 @@ extern int64_t time_slice; int number_of_processes = 0; int prcs_id_next = PRCS_START_ID; -static prcs_info_t *prcs_info; +prcs_info_t *prcs_info; static int *prcsHash; static void prcs_main(void); diff --git a/a653_lib/a653_i_sync.c b/a653_lib/a653_i_sync.c index 53128d3..fe65c6d 100644 --- a/a653_lib/a653_i_sync.c +++ b/a653_lib/a653_i_sync.c @@ -88,12 +88,52 @@ void set_core_affinity(int pid, int core_id) { } } +/* + In case there are multiple arguments given for the binary to be executed, we need to split them. + This is required for the WASM case, where the main calls either p_wamr/p_wasmtime and then the *.wasm + */ +static char **split_argv(const char *input, int *argc_out) { + char *buf = strdup(input); + if (!buf) return NULL; + + int count = 0; + for (char *p = buf; *p; ++p) { + if (*p == ' ') count++; + } + + char **argv = calloc((size_t)count + 2, sizeof(char *)); + if (!argv) { + free(buf); + return NULL; + } + + int argc = 0; + char *save = NULL; + for (char *tok = strtok_r(buf, " \t\r\n", &save); + tok != NULL; + tok = strtok_r(NULL, " \t\r\n", &save)) { + argv[argc++] = tok; + } + argv[argc] = NULL; + + if (argc_out) *argc_out = argc; + return argv; // note: argv[0..argc-1] point into buf +} + pid_t start_partition_process(char *p_name) { pid_t pid = -1; - char *argv[] = {p_name, NULL}; // argv[0] sollte meist der Programmname sein + + int argc = 0; + char **argv = split_argv(p_name, &argc); // argv[0] sollte meist der Programmname sein + if (!argv || argc == 0) { + fprintf(stderr, "bad command line: %s\n", p_name); + return -1; + } // Prozess spawnen (file_actions und attrp sind hier NULL für Standardeinstellungen) - int status = posix_spawn(&pid, p_name, NULL, NULL, argv, environ); + int status = posix_spawn(&pid, argv[0], NULL, NULL, argv, environ); + free(argv[0]); + free(argv); if (status == 0) { printDebug(0,"child with PID %d started.\n", pid); diff --git a/a653_lib_wasm32/a653_wamr.c b/a653_lib_wasm32/a653_wamr.c new file mode 100644 index 0000000..98f9b9c --- /dev/null +++ b/a653_lib_wasm32/a653_wamr.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#include +#include +#include +#include +#include +#include "a653_wamr.h" +#include "apex_host_fncs_wasm32.h" + +#define STACK_SIZE (64 * 1024) +#define MAX_PAGES 64 +#define HOST_HEAP 0 + +static char error[128] = {0}; +InstantiationArgs inst_args = { + .default_stack_size = STACK_SIZE, + .host_managed_heap_size = HOST_HEAP, + .max_memory_pages = MAX_PAGES +}; + +typedef struct { + wasm_module_t module; + + /* needs to be at the end due to [] */ + wasm_file_t wasm; +} wamr_data_t; + +void* generate_wasm_runtime_context(wasm_file_t* wasm) +{ + RuntimeInitArgs init_args; + + /* must be cleaned, otherwise .. there are a lot of possible settings */ + memset(&init_args, 0, sizeof(RuntimeInitArgs)); + + init_args.mem_alloc_type = Alloc_With_System_Allocator; + + if ( ! wasm_runtime_full_init(&init_args)) { + fprintf(stderr, "ERR: Failed to initialize WASM runtime!\n"); + return NULL; + } + + NativeSymbol *native_symbols; + unsigned n_native_symbols = getNativeSymbols(&native_symbols); + if ( ! wasm_runtime_register_natives_raw("arinc653", native_symbols, n_native_symbols)) { + fprintf(stderr, "ERR: Failed to initialize WASM host functions!\n"); + return NULL; + } + + wamr_data_t* wamr_data = (wamr_data_t*) malloc (sizeof(wamr_data_t) + wasm->size); + + /* + * Wasmtime copies the loaded binary to somewhere, thus the agnostic main is assuming it can free it. + * WAMR in contrast uses the given origin of the binary, thus we need to copy here to have same behaviour. + */ + wamr_data->wasm.size = wasm->size; + memcpy(wamr_data->wasm.data, wasm->data, wasm->size); + + /** + * https://github.com/bytecodealliance/wasm-micro-runtime/discussions/3697 + * WAMRs approach of having shared linear memory considers to solely set up 1 WASM module. + * Which is then used by any thread .. + */ + if ( ! (wamr_data->module = wasm_runtime_load((uint8_t*)wamr_data->wasm.data, wamr_data->wasm.size, error, sizeof(error)))) { + fprintf(stderr, "ERR[wasm_runtime_load()]: %s\n", error); + return NULL; + } + + return wamr_data; +} + +void cleanup_wasm_runtime_context(void* wasm_runtime_context) +{ + wasm_runtime_destroy(); + free(wasm_runtime_context); +} + +int exec_wasm_guest_func(void* wasm_runtime_context, int32_t idx) +{ + wamr_data_t *wamr_data = (wamr_data_t*)wasm_runtime_context; + +// wasm_runtime_set_wasi_args(wamr_data->module, NULL, 0, NULL, 0, NULL, 0, NULL, 0); + +#if 0 + wasm_module_inst_t module_inst = wasm_runtime_instantiate_ex( + wamr_data->module, &inst_args, error, sizeof(error)); +#else + + wasm_module_inst_t module_inst = wasm_runtime_instantiate( + wamr_data->module, STACK_SIZE, HOST_HEAP, error, sizeof(error)); +#endif + if ( ! module_inst) { + fprintf(stderr, "ERR[wasm_runtime_instantiate()]: %s\n", error); + return -1; + } + + wasm_exec_env_t exec_env = + wasm_runtime_create_exec_env(module_inst, STACK_SIZE); + if (!exec_env) { + fprintf(stderr, "ERR: Failed to create execution environment\n"); + return -1; + } + + if (idx == -1) { +#if 0 + wasm_function_inst_t fnc; + if ( ! (fnc = wasm_runtime_lookup_wasi_start_function(module_inst))) { + fprintf(stderr, "ERR: Failed to lookup main function inside WASM module: %p\n", fnc); + return -1; + } + if ( ! wasm_runtime_call_wasm(exec_env, fnc, 0, NULL)) { + fprintf(stderr, "ERR[wasm_runtime_call_wasm()] %s\n", wasm_runtime_get_exception(module_inst)); + return -1; + } +#else + if ( ! wasm_application_execute_main(module_inst, 0, NULL)) { + fprintf(stderr, "ERR[wasm_application_execute_main()] %s\n", wasm_runtime_get_exception(module_inst)); + return -1; + } +#endif + } + else { + // idx to function name?? wasm_runtime_lookup_function() + + if ( ! wasm_runtime_init_thread_env()) { + fprintf(stderr, "ERR: Failed to initiate thread environment\n"); + } + +#if 1 + if ( ! wasm_runtime_call_indirect(exec_env, idx, 0, NULL)) { + fprintf(stderr, "ERR[wasm_runtime_call_indirect()] %s\n", wasm_runtime_get_exception(module_inst)); + return -1; + } +#else + wasm_table_inst_t wasm_table; + if ( ! wasm_runtime_get_export_table_inst(module_inst, "__indirect_function_table", + &wasm_table)) { + fprintf(stderr, "ERR: Failed to get __indirect_function_table\n"); + } + + wasm_function_inst_t fnc; + if ( ! (fnc = wasm_table_get_func_inst(module_inst, &wasm_table, idx))) { + fprintf(stderr, "ERR: Failed to get function in __indirect_function_table at idx %u\n", idx); + } + + if ( ! wasm_runtime_call_wasm(exec_env, fnc, 0, NULL)) { + fprintf(stderr, "ERR[wasm_runtime_call_wasm()] %s\n", wasm_runtime_get_exception(module_inst)); + return -1; + } +#endif + + wasm_runtime_destroy_thread_env(); + } + + wasm_runtime_destroy_exec_env(exec_env); + + return 0; +} diff --git a/a653_lib_wasm32/a653_wamr.h b/a653_lib_wasm32/a653_wamr.h new file mode 100644 index 0000000..22b884c --- /dev/null +++ b/a653_lib_wasm32/a653_wamr.h @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#ifndef A653_WAMR +#define A653_WAMR + +#include "generic_helper.h" + +void* generate_wasm_runtime_context(wasm_file_t* wasm); +void cleanup_wasm_runtime_context(void* wasm_runtime_context); +/** + * idx = -1 -> default + * otherwise use __indirect_function_table[] + */ +int exec_wasm_guest_func(void* wasm_runtime_context, int32_t idx); + +#endif /* #ifndef A653_WAMR */ diff --git a/a653_lib_wasm32/a653_wasmtime.c b/a653_lib_wasm32/a653_wasmtime.c new file mode 100644 index 0000000..f3b5e97 --- /dev/null +++ b/a653_lib_wasm32/a653_wasmtime.c @@ -0,0 +1,265 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#include +#include +#include "a653_wasmtime.h" +#include "apex_host_fncs_wasm32.h" +#include "generic_helper.h" + +typedef struct { + wasm_engine_t* engine; + wasmtime_sharedmemory_t* shm_memory; + wasmtime_module_t* module; +} wasmtime_data_t; + + +static void print_wasmtime_error(wasmtime_error_t* error) +{ + if (error) { + wasm_byte_vec_t msg; + wasmtime_error_message(error, &msg); + wasmtime_error_delete(error); + fprintf(stderr, "ERR: %.*s\n", (int)msg.size, msg.data); + wasm_byte_vec_delete(&msg); + } else { + fprintf(stderr, "ERR: Unknown\n"); + } +} + +void* generate_wasm_runtime_context(wasm_file_t* wasm) +{ + // Configure WASI + wasm_config_t *wasm_config = wasm_config_new(); + wasmtime_config_wasm_memory64_set(wasm_config, HAS_64BIT_MEM); + wasmtime_config_cranelift_opt_level_set (wasm_config, WASMTIME_OPT_LEVEL_SPEED); + wasmtime_config_shared_memory_set(wasm_config, true); +// wasmtime_config_wasm_threads_set(wasm_config, true); + + // Initialize Wasmtime + wasmtime_data_t* wd = (wasmtime_data_t*) malloc (sizeof(wasmtime_data_t)); + wd->engine = wasm_engine_new_with_config(wasm_config); + + // Create shared memory (required for threading) + wasm_memorytype_t* mem_type; + wasmtime_error_t* err; + if ((err = wasmtime_memorytype_new( + 1 /* min 64KB-pages */, + true /* max present (must for shared) */, + 65536 /* max 64KB-pages -> 4GB */, + HAS_64BIT_MEM /* is_64 */, + true /* is shared ! required for threading */, + 0 /* page_size_log2 (64 KiB pages), 0 = use default (64KB) */, + &mem_type + )) != NULL) { + print_wasmtime_error(err); + return NULL; + } + wd->shm_memory = NULL; + if((err = wasmtime_sharedmemory_new(wd->engine, mem_type, &wd->shm_memory)) != NULL) { + print_wasmtime_error(err); + free(wd); + return NULL; + } + + // Compile the module + if ((err = wasmtime_module_new(wd->engine, (uint8_t*)wasm->data, wasm->size, &wd->module)) != NULL) { + print_wasmtime_error(err); + free(wd); + return NULL; + } + return wd; +} + +void cleanup_wasm_runtime_context(void* wasm_runtime_context) +{ + wasmtime_data_t* _wasm_runtime_context = (wasmtime_data_t*)wasm_runtime_context; + wasmtime_module_delete(_wasm_runtime_context->module); + wasm_engine_delete(_wasm_runtime_context->engine); +} + + +/** + * Either start the default, which is _start() + * Or based on an index into the __indirect_function_table[] + */ +int exec_wasm_guest_func(void* wasm_runtime_context, int32_t idx) +{ + wasmtime_data_t* wd = (wasmtime_data_t*)wasm_runtime_context; + + // Fresh store+context per call, just like WAMR's fresh module_inst + wasmtime_store_t* store = wasmtime_store_new(wd->engine, NULL, NULL); + wasmtime_context_t* context = wasmtime_store_context(store); + + // Configure WASI context (currently given for debugging... not for true avionics) + wasi_config_t* wasi_config = wasi_config_new(); + wasi_config_inherit_argv(wasi_config); + wasi_config_inherit_env(wasi_config); + wasi_config_inherit_stdout(wasi_config); + wasi_config_inherit_stderr(wasi_config); + + wasmtime_error_t* err; + if ((err = wasmtime_context_set_wasi(context, wasi_config)) != NULL) { + print_wasmtime_error(err); + wasmtime_store_delete(store); + return -1; + } + + // Create linker and define WASI + wasmtime_linker_t* linker = wasmtime_linker_new(wd->engine); + if ((err = wasmtime_linker_define_wasi(linker)) != NULL) { + print_wasmtime_error(err); + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + + wasmtime_extern_t import; + import.kind = WASMTIME_EXTERN_SHAREDMEMORY; + import.of.sharedmemory = wd->shm_memory; + + // Link shared memory to "wasi" module (or your module namespace) + if ((err = wasmtime_linker_define(linker, context, "wasi", 4, "memory", 6, &import)) != NULL) { + print_wasmtime_error(err); + printf("shared memory didn't work!\n"); + return - 1; + } + + wasm_valtype_vec_t results; + wasm_valtype_vec_new_empty(&results); + + // Create the host function + wasmtime_extern_t item; + item.kind = WASMTIME_EXTERN_FUNC; + + NativeSymbol* native_symbols; + for (unsigned i = 0; i < getNativeSymbols(&native_symbols); ++i) { + NativeSymbol* ns = &native_symbols[i]; + int parms_c = signature_parameter_count(ns->signature); + if (parms_c == -1) { + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + + wasm_valtype_vec_t params; + wasm_valtype_vec_new_uninitialized(¶ms, parms_c); + + // https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/core/iwasm/common/wasm_runtime_common.c + int j = 0; + for (char* s = (char*)ns->signature; *s != '\0' && j < parms_c; ++s) { + switch (*s) { + case '(': case ')': break; + // 32-bit integer (i32) + // Byte length of the preceding buffer pointer (*), must follow * + case 'i': case '~': params.data[j++] = wasm_valtype_new(WASM_I32); break; + // 64-bit integer (i64) + case 'I': params.data[j++] = wasm_valtype_new(WASM_I64); break; + // 32-bit float (f32) + case 'f': params.data[j++] = wasm_valtype_new(WASM_F32); break; + // 64-bit float (f64) + case 'F': params.data[j++] = wasm_valtype_new(WASM_F64); break; + // externref type (usually a uintptr_t), or GC references + case 'r': params.data[j++] = wasm_valtype_new(WASM_EXTERNREF); break; + // String in WASM memory + // Buffer address (pointer) in WASM memory + case '$': case '*': params.data[j++] = wasm_valtype_new(HAS_64BIT_MEM ? WASM_I64 : WASM_I32); break; + default: fprintf(stderr, "ERR: unknown sig char %c\n", *s); break; + } + } + + wasm_functype_t* func_type = wasm_functype_new(¶ms, &results); + wasmtime_func_new_unchecked(context, func_type, + (wasmtime_func_unchecked_callback_t)ns->func_ptr, + ns->attachment, NULL, &item.of.func); + + if ((err = wasmtime_linker_define(linker, context, "arinc653", strlen("arinc653"), ns->symbol, strlen(ns->symbol), &item)) != NULL) { + print_wasmtime_error(err); + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + } + + // Fresh instantiation per call, same as WAMR's wasm_runtime_instantiate() + wasm_trap_t* trap = NULL; + wasmtime_instance_t instance; + if ((err = wasmtime_linker_instantiate(linker, context, wd->module, &instance, &trap)) != NULL) { + print_wasmtime_error(err); + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + + if (trap) { + // instantiation trapped (e.g. start function failed) + wasm_byte_vec_t msg; + wasm_trap_message(trap, &msg); + fprintf(stderr, "ERR trap: %.*s\n", (int)msg.size, msg.data); + wasm_byte_vec_delete(&msg); + wasm_trap_delete(trap); + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + + wasmtime_func_t fnc; + if (idx == -1) { + // mirrors wasm_application_execute_main() + wasmtime_extern_t ext; + if (!wasmtime_instance_export_get(context, &instance, "_start", strlen("_start"), &ext) + || ext.kind != WASMTIME_EXTERN_FUNC) { + fprintf(stderr, "ERR: _start not found.\n"); + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + fnc = ext.of.func; + } + else { + // mirrors wasm_runtime_call_indirect() + wasmtime_extern_t ext; + if (!wasmtime_instance_export_get(context, &instance, "__indirect_function_table", strlen("__indirect_function_table"), &ext) + || ext.kind != WASMTIME_EXTERN_TABLE) { + fprintf(stderr, "ERR: __indirect_function_table not found.\n"); + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + + wasmtime_val_t val; + if (!wasmtime_table_get(context, &ext.of.table, idx, &val)) { + fprintf(stderr, "ERR: Index %d not in __indirect_function_table.\n", idx); + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + + fnc = val.of.funcref; + } + + trap = NULL; + if ((err = wasmtime_func_call(context, &fnc, NULL, 0, NULL, 0, &trap)) != NULL) { + print_wasmtime_error(err); + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + + if (trap) { + // instantiation trapped (e.g. start function failed) + wasm_byte_vec_t msg; + wasm_trap_message(trap, &msg); + fprintf(stderr, "ERR trap: %.*s\n", (int)msg.size, msg.data); + wasm_byte_vec_delete(&msg); + wasm_trap_delete(trap); + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return -1; + } + + wasmtime_linker_delete(linker); + wasmtime_store_delete(store); + return 0; +} diff --git a/a653_lib_wasm32/a653_wasmtime.h b/a653_lib_wasm32/a653_wasmtime.h new file mode 100644 index 0000000..e949519 --- /dev/null +++ b/a653_lib_wasm32/a653_wasmtime.h @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#ifndef A653_WASMTIME +#define A653_WASMTIME + +#include + +#include "generic_helper.h" + +void* generate_wasm_runtime_context(wasm_file_t* wasm); +void cleanup_wasm_runtime_context(void* wasm_runtime_context); +/** + * idx = -1 -> default + * otherwise use __indirect_function_table[] + */ +int exec_wasm_guest_func(void* wasm_runtime_context, int32_t idx); + +#endif /* #ifndef A653_WASMTIME */ diff --git a/a653_lib_wasm32/apex_host_fncs_wasm32.c b/a653_lib_wasm32/apex_host_fncs_wasm32.c new file mode 100644 index 0000000..791085b --- /dev/null +++ b/a653_lib_wasm32/apex_host_fncs_wasm32.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#include "apex_host_fncs_wasm32.h" +#include "arinc653_part1_apex_time_wasm32.h" +#include "arinc653_part1_apex_process_wasm32.h" +#include "arinc653_part1_apex_partition_wasm32.h" +#include "arinc653_part1_apex_sampling_port_wasm32.h" +#include "arinc653_part1_apex_queuing_port_wasm32.h" +#include "arinc653_part1_apex_buffer_wasm32.h" +#include "arinc653_part1_apex_blackboard_wasm32.h" +#include "arinc653_part1_apex_semaphore_wasm32.h" +#include "arinc653_part1_apex_event_wasm32.h" +#include "arinc653_part1_apex_mutex_wasm32.h" +#include "arinc653_part1_apex_error_wasm32.h" +#include "arinc653_part2_apex_sampling_port_extension_wasm32.h" + +static NativeSymbol native_symbols[] = { +/* APEX (ARINC 653 Part 1): TIME */ + WASM_HOSTFUNC_SIGNATURE( TIMED_WAIT ), + WASM_HOSTFUNC_SIGNATURE( PERIODIC_WAIT ), + WASM_HOSTFUNC_SIGNATURE( GET_TIME ), + WASM_HOSTFUNC_SIGNATURE( REPLENISH ), +/* APEX (ARINC 653 Part 1): PROCESS */ + WASM_HOSTFUNC_SIGNATURE( CREATE_PROCESS ), + WASM_HOSTFUNC_SIGNATURE( SET_PRIORITY ), + WASM_HOSTFUNC_SIGNATURE( SUSPEND_SELF ), + WASM_HOSTFUNC_SIGNATURE( SUSPEND ), + WASM_HOSTFUNC_SIGNATURE( RESUME ), + WASM_HOSTFUNC_SIGNATURE( STOP_SELF ), + WASM_HOSTFUNC_SIGNATURE( STOP ), + WASM_HOSTFUNC_SIGNATURE( START ), + WASM_HOSTFUNC_SIGNATURE( DELAYED_START ), + WASM_HOSTFUNC_SIGNATURE( LOCK_PREEMPTION ), + WASM_HOSTFUNC_SIGNATURE( UNLOCK_PREEMPTION ), + WASM_HOSTFUNC_SIGNATURE( GET_MY_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_PROCESS_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_PROCESS_STATUS ), + WASM_HOSTFUNC_SIGNATURE( INITIALIZE_PROCESS_CORE_AFFINITY ), + WASM_HOSTFUNC_SIGNATURE( GET_MY_PROCESSOR_CORE_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_MY_INDEX ), +/* APEX (ARINC 653 Part 1): PARTITION */ + WASM_HOSTFUNC_SIGNATURE( GET_PARTITION_STATUS ), + WASM_HOSTFUNC_SIGNATURE( SET_PARTITION_MODE ), +/* APEX (ARINC 653 Part 1): SAMPLING PORT */ + WASM_HOSTFUNC_SIGNATURE( CREATE_SAMPLING_PORT ), + WASM_HOSTFUNC_SIGNATURE( WRITE_SAMPLING_MESSAGE ), + WASM_HOSTFUNC_SIGNATURE( READ_SAMPLING_MESSAGE ), + WASM_HOSTFUNC_SIGNATURE( GET_SAMPLING_PORT_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_SAMPLING_PORT_STATUS ), +/* APEX (ARINC 653 Part 1): QUEUING PORT */ + WASM_HOSTFUNC_SIGNATURE( CREATE_QUEUING_PORT ), + WASM_HOSTFUNC_SIGNATURE( SEND_QUEUING_MESSAGE ), + WASM_HOSTFUNC_SIGNATURE( RECEIVE_QUEUING_MESSAGE ), + WASM_HOSTFUNC_SIGNATURE( GET_QUEUING_PORT_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_QUEUING_PORT_STATUS ), + WASM_HOSTFUNC_SIGNATURE( CLEAR_QUEUING_PORT ), +/* APEX (ARINC 653 Part 1): BUFFER */ + WASM_HOSTFUNC_SIGNATURE( CREATE_BUFFER ), + WASM_HOSTFUNC_SIGNATURE( SEND_BUFFER ), + WASM_HOSTFUNC_SIGNATURE( RECEIVE_BUFFER ), + WASM_HOSTFUNC_SIGNATURE( GET_BUFFER_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_BUFFER_STATUS ), +/* APEX (ARINC 653 Part 1): BLACKBOARD */ + WASM_HOSTFUNC_SIGNATURE( CREATE_BLACKBOARD ), + WASM_HOSTFUNC_SIGNATURE( DISPLAY_BLACKBOARD ), + WASM_HOSTFUNC_SIGNATURE( READ_BLACKBOARD ), + WASM_HOSTFUNC_SIGNATURE( CLEAR_BLACKBOARD ), + WASM_HOSTFUNC_SIGNATURE( GET_BLACKBOARD_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_BLACKBOARD_STATUS ), +/* APEX (ARINC 653 Part 1): SEMAPHORE */ + WASM_HOSTFUNC_SIGNATURE( CREATE_SEMAPHORE ), + WASM_HOSTFUNC_SIGNATURE( WAIT_SEMAPHORE ), + WASM_HOSTFUNC_SIGNATURE( SIGNAL_SEMAPHORE ), + WASM_HOSTFUNC_SIGNATURE( GET_SEMAPHORE_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_SEMAPHORE_STATUS ), +/* APEX (ARINC 653 Part 1): EVENT */ + WASM_HOSTFUNC_SIGNATURE( CREATE_EVENT ), + WASM_HOSTFUNC_SIGNATURE( SET_EVENT ), + WASM_HOSTFUNC_SIGNATURE( RESET_EVENT ), + WASM_HOSTFUNC_SIGNATURE( WAIT_EVENT ), + WASM_HOSTFUNC_SIGNATURE( GET_EVENT_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_EVENT_STATUS ), +/* APEX (ARINC 653 Part 1): MUTEX */ + WASM_HOSTFUNC_SIGNATURE( CREATE_MUTEX ), + WASM_HOSTFUNC_SIGNATURE( ACQUIRE_MUTEX ), + WASM_HOSTFUNC_SIGNATURE( RELEASE_MUTEX ), + WASM_HOSTFUNC_SIGNATURE( RESET_MUTEX ), + WASM_HOSTFUNC_SIGNATURE( GET_MUTEX_ID ), + WASM_HOSTFUNC_SIGNATURE( GET_MUTEX_STATUS ), + WASM_HOSTFUNC_SIGNATURE( GET_PROCESS_MUTEX_STATE ), +/* APEX (ARINC 653 Part 1): ERROR */ + WASM_HOSTFUNC_SIGNATURE( REPORT_APPLICATION_MESSAGE ), + WASM_HOSTFUNC_SIGNATURE( CREATE_ERROR_HANDLER ), + WASM_HOSTFUNC_SIGNATURE( GET_ERROR_STATUS ), + WASM_HOSTFUNC_SIGNATURE( RAISE_APPLICATION_ERROR ), + WASM_HOSTFUNC_SIGNATURE( CONFIGURE_ERROR_HANDLER ), + +/* APEX (ARINC 653 Part 2: SAMPLING PORT EXTENSIONS */ + WASM_HOSTFUNC_SIGNATURE( READ_UPDATED_SAMPLING_MESSAGE ), + WASM_HOSTFUNC_SIGNATURE( GET_SAMPLING_PORT_CURRENT_STATUS ), + WASM_HOSTFUNC_SIGNATURE( READ_SAMPLING_MESSAGE_CONDITIONAL ) +}; + +unsigned getNativeSymbols(NativeSymbol** _native_symbols) +{ + *_native_symbols = native_symbols; + return sizeof(native_symbols)/sizeof(native_symbols[0]); +} diff --git a/a653_lib_wasm32/apex_host_fncs_wasm32.h b/a653_lib_wasm32/apex_host_fncs_wasm32.h new file mode 100644 index 0000000..e8c41ae --- /dev/null +++ b/a653_lib_wasm32/apex_host_fncs_wasm32.h @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#ifndef APEX_HOST_FNCS_WASM32 +#define APEX_HOST_FNCS_WASM32 + +#include +#ifdef __WAMR__ +#include + +#define WASM_HOSTFUNC_SIGNATURE( FNC ) { #FNC, (void*)(uintptr_t)WASM32_##FNC, WASM32_SIGNATURE__##FNC, NULL } + +#endif +#ifdef __WASMTIME__ +#include + +/* not equal (see func_ptr), but similar as defined in WAMR */ +/* https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/core/iwasm/include/lib_export.h */ +typedef struct { + const char* symbol; + wasm_trap_t * (*func_ptr)(void *, wasmtime_caller_t *, wasmtime_val_raw_t *, size_t); + const char *signature; + void *attachment; +} NativeSymbol; + +#define WASM_HOSTFUNC_SIGNATURE( FNC ) { #FNC, WASM32_##FNC, WASM32_SIGNATURE__##FNC, NULL } + +#endif + +unsigned getNativeSymbols(NativeSymbol** _native_symbols); + +#endif /* #ifndef APEX_HOST_FNCS_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_blackboard_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_blackboard_wasm32.c new file mode 100644 index 0000000..e67f491 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_blackboard_wasm32.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: BLACKBOARD + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part1_apex_blackboard_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "a653Blackboard.h" + + +WASM32_HOST_FUNCTION(CREATE_BLACKBOARD, wasm_baseaddr, +{ + int32_t BLACKBOARD_NAME; /* is a pointer / address into Wasm linear memory */ + BLACKBOARD_NAME = (int32_t)le32toh(GET_ARG_i32(0)); + MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE; + MAX_MESSAGE_SIZE = (MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(1)); + + BLACKBOARD_ID_TYPE BLACKBOARD_ID; + RETURN_CODE_TYPE RETURN_CODE; + + CREATE_BLACKBOARD( + (char*)&wasm_baseaddr[BLACKBOARD_NAME], + MAX_MESSAGE_SIZE, + &BLACKBOARD_ID, + &RETURN_CODE + ); + + camw32_set__BLACKBOARD_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)BLACKBOARD_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(DISPLAY_BLACKBOARD, wasm_baseaddr, +{ + BLACKBOARD_ID_TYPE BLACKBOARD_ID; + BLACKBOARD_ID = (BLACKBOARD_ID_TYPE)le32toh(GET_ARG_i32(0)); + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = (int32_t)le32toh(GET_ARG_i32(1)); + MESSAGE_SIZE_TYPE LENGTH; + LENGTH = (MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(2)); + + RETURN_CODE_TYPE RETURN_CODE; + + DISPLAY_BLACKBOARD( + BLACKBOARD_ID, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], + LENGTH, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(READ_BLACKBOARD, wasm_baseaddr, +{ + BLACKBOARD_ID_TYPE BLACKBOARD_ID; + BLACKBOARD_ID = (BLACKBOARD_ID_TYPE)le32toh(GET_ARG_i32(0)); + SYSTEM_TIME_TYPE TIME_OUT; + TIME_OUT = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(1)); + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = (int32_t)le32toh(GET_ARG_i32(2)); + + MESSAGE_SIZE_TYPE LENGTH; + RETURN_CODE_TYPE RETURN_CODE; + + READ_BLACKBOARD( + BLACKBOARD_ID, + TIME_OUT, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], + &LENGTH, + &RETURN_CODE + ); + + camw32_set__MESSAGE_SIZE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)LENGTH); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(CLEAR_BLACKBOARD, wasm_baseaddr, +{ + BLACKBOARD_ID_TYPE BLACKBOARD_ID; + BLACKBOARD_ID = (BLACKBOARD_ID_TYPE)le32toh(GET_ARG_i32(0)); + + RETURN_CODE_TYPE RETURN_CODE; + + CLEAR_BLACKBOARD( + BLACKBOARD_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_BLACKBOARD_ID, wasm_baseaddr, +{ + int32_t BLACKBOARD_NAME; /* is a pointer / address into Wasm linear memory */ + BLACKBOARD_NAME = (int32_t)le32toh(GET_ARG_i32(0)); + + BLACKBOARD_ID_TYPE BLACKBOARD_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_BLACKBOARD_ID( + (char*)&wasm_baseaddr[BLACKBOARD_NAME], + &BLACKBOARD_ID, + &RETURN_CODE + ); + + camw32_set__BLACKBOARD_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)BLACKBOARD_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_BLACKBOARD_STATUS, wasm_baseaddr, +{ + BLACKBOARD_ID_TYPE BLACKBOARD_ID; + BLACKBOARD_ID = (BLACKBOARD_ID_TYPE)le32toh(GET_ARG_i32(0)); + + BLACKBOARD_STATUS_TYPE BLACKBOARD_STATUS; + RETURN_CODE_TYPE RETURN_CODE; + + GET_BLACKBOARD_STATUS( + BLACKBOARD_ID, + &BLACKBOARD_STATUS, + &RETURN_CODE + ); + + uint8_t* BLACKBOARD_STATUS_guest = (uint8_t*)&wasm_baseaddr[le32toh(GET_ARG_i32(1))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + camw32_set__BLACKBOARD_STATUS_TYPE__EMPTY_INDICATOR(BLACKBOARD_STATUS_guest, BLACKBOARD_STATUS.EMPTY_INDICATOR); + camw32_set__BLACKBOARD_STATUS_TYPE__MAX_MESSAGE_SIZE(BLACKBOARD_STATUS_guest, BLACKBOARD_STATUS.MAX_MESSAGE_SIZE); + camw32_set__BLACKBOARD_STATUS_TYPE__WAITING_PROCESSES(BLACKBOARD_STATUS_guest, BLACKBOARD_STATUS.WAITING_PROCESSES); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_blackboard_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_blackboard_wasm32.h new file mode 100644 index 0000000..72af4f8 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_blackboard_wasm32.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: BLACKBOARD + +#ifndef ARINC653_PART1_APEX_BLACKBOARD_WASM32 +#define ARINC653_PART1_APEX_BLACKBOARD_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): BLACKBOARD */ +#define WASM32_SIGNATURE__CREATE_BLACKBOARD "(iiii)" +#define WASM32_SIGNATURE__DISPLAY_BLACKBOARD "(iiii)" +#define WASM32_SIGNATURE__READ_BLACKBOARD "(iIiii)" +#define WASM32_SIGNATURE__CLEAR_BLACKBOARD "(ii)" +#define WASM32_SIGNATURE__GET_BLACKBOARD_ID "(iii)" +#define WASM32_SIGNATURE__GET_BLACKBOARD_STATUS "(iii)" + +WASM32_HOST_FUNC_HEADER(CREATE_BLACKBOARD) +WASM32_HOST_FUNC_HEADER(DISPLAY_BLACKBOARD) +WASM32_HOST_FUNC_HEADER(READ_BLACKBOARD) +WASM32_HOST_FUNC_HEADER(CLEAR_BLACKBOARD) +WASM32_HOST_FUNC_HEADER(GET_BLACKBOARD_ID) +WASM32_HOST_FUNC_HEADER(GET_BLACKBOARD_STATUS) + +#endif /* #ifndef ARINC653_PART1_APEX_BLACKBOARD_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_buffer_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_buffer_wasm32.c new file mode 100644 index 0000000..184dbb3 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_buffer_wasm32.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: BUFFER + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part1_apex_buffer_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "a653Buffer.h" + + +WASM32_HOST_FUNCTION(CREATE_BUFFER, wasm_baseaddr, +{ + int32_t BUFFER_NAME; /* is a pointer / address into Wasm linear memory */ + BUFFER_NAME = (int32_t)le32toh(GET_ARG_i32(0)); + MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE; + MAX_MESSAGE_SIZE = (MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(1)); + MESSAGE_RANGE_TYPE MAX_NB_MESSAGE; + MAX_NB_MESSAGE = (MESSAGE_RANGE_TYPE)le32toh(GET_ARG_i32(2)); + QUEUING_DISCIPLINE_TYPE QUEUING_DISCIPLINE; + QUEUING_DISCIPLINE = (QUEUING_DISCIPLINE_TYPE)le32toh(GET_ARG_i32(3)); + + BUFFER_ID_TYPE BUFFER_ID; + RETURN_CODE_TYPE RETURN_CODE; + + CREATE_BUFFER( + (char*)&wasm_baseaddr[BUFFER_NAME], + MAX_MESSAGE_SIZE, + MAX_NB_MESSAGE, + QUEUING_DISCIPLINE, + &BUFFER_ID, + &RETURN_CODE + ); + + camw32_set__BUFFER_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)BUFFER_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(5))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(SEND_BUFFER, wasm_baseaddr, +{ + BUFFER_ID_TYPE BUFFER_ID; + BUFFER_ID = (BUFFER_ID_TYPE)le32toh(GET_ARG_i32(0)); + int32_t MESSAGE_ADDR; + MESSAGE_ADDR = (int32_t)le32toh(GET_ARG_i32(1)); + MESSAGE_SIZE_TYPE LENGTH; + LENGTH = (MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(2)); + SYSTEM_TIME_TYPE TIME_OUT; + TIME_OUT = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(3)); + + RETURN_CODE_TYPE RETURN_CODE; + + SEND_BUFFER( + BUFFER_ID, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], + LENGTH, + TIME_OUT, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(RECEIVE_BUFFER, wasm_baseaddr, +{ + BUFFER_ID_TYPE BUFFER_ID; + BUFFER_ID = (BUFFER_ID_TYPE)le32toh(GET_ARG_i32(0)); + SYSTEM_TIME_TYPE TIME_OUT; + TIME_OUT = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(1)); + int32_t MESSAGE_ADDR; + MESSAGE_ADDR = (int32_t)le32toh(GET_ARG_i32(2)); + + MESSAGE_SIZE_TYPE LENGTH; + RETURN_CODE_TYPE RETURN_CODE; + + RECEIVE_BUFFER( + BUFFER_ID, + TIME_OUT, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], + &LENGTH, + &RETURN_CODE + ); + + camw32_set__MESSAGE_SIZE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)LENGTH); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_BUFFER_ID, wasm_baseaddr, +{ + int32_t BUFFER_NAME; /* is a pointer / address into Wasm linear memory */ + BUFFER_NAME = (int32_t)le32toh(GET_ARG_i32(0)); + + BUFFER_ID_TYPE BUFFER_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_BUFFER_ID( + (char*)&wasm_baseaddr[BUFFER_NAME], + &BUFFER_ID, + &RETURN_CODE + ); + + camw32_set__BUFFER_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)BUFFER_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_BUFFER_STATUS, wasm_baseaddr, +{ + BUFFER_ID_TYPE BUFFER_ID; /* is a pointer / address into Wasm linear memory */ + BUFFER_ID = (int32_t)le32toh(GET_ARG_i32(0)); + + BUFFER_STATUS_TYPE BUFFER_STATUS; + RETURN_CODE_TYPE RETURN_CODE; + + GET_BUFFER_STATUS( + BUFFER_ID, + &BUFFER_STATUS, + &RETURN_CODE + ); + + uint8_t* BUFFER_STATUS_guest = (uint8_t*)&wasm_baseaddr[le32toh(GET_ARG_i32(1))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + camw32_set__BUFFER_STATUS_TYPE__NB_MESSAGE(BUFFER_STATUS_guest, BUFFER_STATUS.NB_MESSAGE); + camw32_set__BUFFER_STATUS_TYPE__MAX_NB_MESSAGE(BUFFER_STATUS_guest, BUFFER_STATUS.MAX_NB_MESSAGE); + camw32_set__BUFFER_STATUS_TYPE__MAX_MESSAGE_SIZE(BUFFER_STATUS_guest, BUFFER_STATUS.MAX_MESSAGE_SIZE); + camw32_set__BUFFER_STATUS_TYPE__WAITING_PROCESSES(BUFFER_STATUS_guest, BUFFER_STATUS.WAITING_PROCESSES); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_buffer_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_buffer_wasm32.h new file mode 100644 index 0000000..3da1aa8 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_buffer_wasm32.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: BUFFER + +#ifndef ARINC653_PART1_APEX_BUFFER_WASM32 +#define ARINC653_PART1_APEX_BUFFER_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): BUFFER */ +#define WASM32_SIGNATURE__CREATE_BUFFER "(iiiiii)" +#define WASM32_SIGNATURE__SEND_BUFFER "(iiiIi)" +#define WASM32_SIGNATURE__RECEIVE_BUFFER "(iIiii)" +#define WASM32_SIGNATURE__GET_BUFFER_ID "(iii)" +#define WASM32_SIGNATURE__GET_BUFFER_STATUS "(iii)" + +WASM32_HOST_FUNC_HEADER(CREATE_BUFFER) +WASM32_HOST_FUNC_HEADER(SEND_BUFFER) +WASM32_HOST_FUNC_HEADER(RECEIVE_BUFFER) +WASM32_HOST_FUNC_HEADER(GET_BUFFER_ID) +WASM32_HOST_FUNC_HEADER(GET_BUFFER_STATUS) + +#endif /* #ifndef ARINC653_PART1_APEX_BUFFER_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_error_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_error_wasm32.c new file mode 100644 index 0000000..7968a44 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_error_wasm32.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: ERROR + +#include +#include +#include +#include +#include "arinc653_wasm32_helper.h" +#include "generic_helper.h" +#include "arinc653_part1_apex_error_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "../a653_inc/a653Error.h" + + +WASM32_HOST_FUNCTION(REPORT_APPLICATION_MESSAGE, wasm_baseaddr, +{ + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = (int32_t)le32toh(GET_ARG_i32(0)); + MESSAGE_SIZE_TYPE LENGTH; + LENGTH = (MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(1)); + RETURN_CODE_TYPE RETURN_CODE; + + REPORT_APPLICATION_MESSAGE( + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], + LENGTH, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + + +extern wasm_prcs_info_t wasm_prcs_info; + +void *error_handler_trampoline(void) { + + uint32_t idx = wasm_prcs_info.ENTRY_POINT_ERROR_HANDLER; + if ( ! exec_wasm_guest_func(wasm_prcs_info.wasm_rt_ctx, idx)) + fprintf(stderr, "ERR: wasm_processid not found\n"); + + return NULL; +} + + +/* + * Note: + * in case one patches ARINC653 CREATE_ERROR_HANLDER() with: + * CREATE_ERROR_HANLDER(__funcref ENTRY_POINT, STACK_SIZE_TYPE STACK_SIZE, RETURN_CODE_TYPE *RETURN_CODE) + * + * then at least in Wasmtime one can use to store the function pointer raw value: + * + * void* wasm_processes.ENTRY_POINT_ERROR_HANDLER; + * wasm_processes.ENTRY_POINT_ERROR_HANDLER = wasmtime_func_to_raw(context, args_and_results[0].funcref); + * + * and recreate the function with: + * + * wasmtime_func_t fn; + * wasmtime_func_from_raw(context, wasm_processes.ENTRY_POINT_ERROR_HANDLER, &fn); + * + * However, WAMR does not support WASM_FUNCREF. + */ +WASM32_HOST_FUNCTION(CREATE_ERROR_HANDLER, wasm_baseaddr, +{ + wasm_prcs_info.ENTRY_POINT_ERROR_HANDLER = le32toh(GET_ARG_i32(0)); + + STACK_SIZE_TYPE STACK_SIZE; + STACK_SIZE = (STACK_SIZE_TYPE)le32toh(GET_ARG_i32(1)); + RETURN_CODE_TYPE RETURN_CODE; + + assert(sizeof(void*) == sizeof(void (*)(void))); + CREATE_ERROR_HANDLER( + (void*)(uintptr_t)error_handler_trampoline, + STACK_SIZE, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_ERROR_STATUS, wasm_baseaddr, +{ + ERROR_STATUS_TYPE ERROR_STATUS; + RETURN_CODE_TYPE RETURN_CODE; + GET_ERROR_STATUS( + &ERROR_STATUS, + &RETURN_CODE + ); + + uint8_t* ERROR_STATUS__guest = &wasm_baseaddr[le32toh(GET_ARG_i32(0))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); + + camw32_set__ERROR_STATUS_TYPE__ERROR_CODE(ERROR_STATUS__guest, (ERROR_MESSAGE_SIZE_TYPE)ERROR_STATUS.ERROR_CODE); + camw32_write__ERROR_STATUS_TYPE__MESSAGE(ERROR_STATUS__guest, ERROR_STATUS.MESSAGE); + camw32_set__ERROR_STATUS_TYPE__LENGTH(ERROR_STATUS__guest, ERROR_STATUS.LENGTH); + camw32_set__ERROR_STATUS_TYPE__FAILED_PROCESS_ID(ERROR_STATUS__guest, ERROR_STATUS.FAILED_PROCESS_ID); + + uint32_t FAILED_ADDRESS_idx = wasm_prcs_info.ENTRY_POINT[ERROR_STATUS.FAILED_PROCESS_ID]; + camw32_set__ERROR_STATUS_TYPE__FAILED_ADDRESS(ERROR_STATUS__guest, FAILED_ADDRESS_idx); +}) + + +WASM32_HOST_FUNCTION(RAISE_APPLICATION_ERROR, wasm_baseaddr, +{ + ERROR_CODE_TYPE ERROR_CODE; + ERROR_CODE = (ERROR_CODE_TYPE)le32toh(GET_ARG_i32(0)); + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = (int32_t)le32toh(GET_ARG_i32(1)); + ERROR_MESSAGE_SIZE_TYPE LENGTH; + LENGTH = (ERROR_MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(2)); + RETURN_CODE_TYPE RETURN_CODE; + + RAISE_APPLICATION_ERROR( + ERROR_CODE, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], // FIXME: only safe as long as char[] + LENGTH, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(CONFIGURE_ERROR_HANDLER, wasm_baseaddr, +{ + ERROR_HANDLER_CONCURRENCY_CONTROL_TYPE CONCURRENCY_CONTROL; + CONCURRENCY_CONTROL = (ERROR_HANDLER_CONCURRENCY_CONTROL_TYPE)le32toh(GET_ARG_i32(0)); + PROCESSOR_CORE_ID_TYPE PROCESSOR_CORE_ID; + PROCESSOR_CORE_ID = (PROCESSOR_CORE_ID_TYPE)le32toh(GET_ARG_i32(1)); + RETURN_CODE_TYPE RETURN_CODE; + + CONFIGURE_ERROR_HANDLER( + CONCURRENCY_CONTROL, + PROCESSOR_CORE_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_error_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_error_wasm32.h new file mode 100644 index 0000000..2c30e5d --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_error_wasm32.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: ERROR + +#ifndef ARINC653_PART1_APEX_ERROR_WASM32 +#define ARINC653_PART1_APEX_ERROR_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): ERROR */ +#define WASM32_SIGNATURE__REPORT_APPLICATION_MESSAGE "(iii)" +#define WASM32_SIGNATURE__CREATE_ERROR_HANDLER "(iii)" +#define WASM32_SIGNATURE__GET_ERROR_STATUS "(ii)" +#define WASM32_SIGNATURE__RAISE_APPLICATION_ERROR "(iiii)" +#define WASM32_SIGNATURE__CONFIGURE_ERROR_HANDLER "(iii)" + +WASM32_HOST_FUNC_HEADER(REPORT_APPLICATION_MESSAGE) +WASM32_HOST_FUNC_HEADER(CREATE_ERROR_HANDLER) +WASM32_HOST_FUNC_HEADER(GET_ERROR_STATUS) +WASM32_HOST_FUNC_HEADER(RAISE_APPLICATION_ERROR) +WASM32_HOST_FUNC_HEADER(CONFIGURE_ERROR_HANDLER) + +#endif /* #ifndef ARINC653_PART1_APEX_ERROR_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_event_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_event_wasm32.c new file mode 100644 index 0000000..2d5c6ae --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_event_wasm32.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: EVENT + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part1_apex_event_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "a653Event.h" + + +WASM32_HOST_FUNCTION(CREATE_EVENT, wasm_baseaddr, +{ + int32_t EVENT_NAME; /* is a pointer / address into Wasm linear memory */ + EVENT_NAME = (int32_t)le32toh(GET_ARG_i32(0)); + + EVENT_ID_TYPE EVENT_ID; + RETURN_CODE_TYPE RETURN_CODE; + + CREATE_EVENT( + (char*)&wasm_baseaddr[EVENT_NAME], + &EVENT_ID, + &RETURN_CODE + ); + + camw32_set__EVENT_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)EVENT_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(SET_EVENT, wasm_baseaddr, +{ + EVENT_ID_TYPE EVENT_ID; + EVENT_ID = (EVENT_ID_TYPE)le32toh(GET_ARG_i32(0)); + + RETURN_CODE_TYPE RETURN_CODE; + + SET_EVENT( + EVENT_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(RESET_EVENT, wasm_baseaddr, +{ + EVENT_ID_TYPE EVENT_ID; + EVENT_ID = (EVENT_ID_TYPE)le32toh(GET_ARG_i32(0)); + + RETURN_CODE_TYPE RETURN_CODE; + + RESET_EVENT( + EVENT_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(WAIT_EVENT, wasm_baseaddr, +{ + EVENT_ID_TYPE EVENT_ID; + EVENT_ID = (EVENT_ID_TYPE)le32toh(GET_ARG_i32(0)); + SYSTEM_TIME_TYPE TIME_OUT; + TIME_OUT = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(0)); + + RETURN_CODE_TYPE RETURN_CODE; + + WAIT_EVENT( + EVENT_ID, + TIME_OUT, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_EVENT_ID, wasm_baseaddr, +{ + int32_t EVENT_NAME; /* is a pointer / address into Wasm linear memory */ + EVENT_NAME = (int32_t)le32toh(GET_ARG_i32(0)); + + EVENT_ID_TYPE EVENT_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_EVENT_ID( + (char*)&wasm_baseaddr[EVENT_NAME], + &EVENT_ID, + &RETURN_CODE + ); + + camw32_set__EVENT_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)EVENT_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_EVENT_STATUS, wasm_baseaddr, +{ + EVENT_ID_TYPE EVENT_ID; + EVENT_ID = (EVENT_ID_TYPE)le32toh(GET_ARG_i32(0)); + + EVENT_STATUS_TYPE EVENT_STATUS; + RETURN_CODE_TYPE RETURN_CODE; + + GET_EVENT_STATUS( + EVENT_ID, + &EVENT_STATUS, + &RETURN_CODE + ); + + uint8_t* EVENT_STATUS_guest = (uint8_t*)&wasm_baseaddr[le32toh(GET_ARG_i32(1))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + camw32_set__EVENT_STATUS_TYPE__EVENT_STATE(EVENT_STATUS_guest, EVENT_STATUS.EVENT_STATE); + camw32_set__EVENT_STATUS_TYPE__WAITING_PROCESSES(EVENT_STATUS_guest, EVENT_STATUS.WAITING_PROCESSES); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_event_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_event_wasm32.h new file mode 100644 index 0000000..5956f0b --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_event_wasm32.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: EVENT + +#ifndef ARINC653_PART1_APEX_EVENT_WASM32 +#define ARINC653_PART1_APEX_EVENT_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): EVENT */ +#define WASM32_SIGNATURE__CREATE_EVENT "(iii)" +#define WASM32_SIGNATURE__SET_EVENT "(ii)" +#define WASM32_SIGNATURE__RESET_EVENT "(ii)" +#define WASM32_SIGNATURE__WAIT_EVENT "(iIi)" +#define WASM32_SIGNATURE__GET_EVENT_ID "(iii)" +#define WASM32_SIGNATURE__GET_EVENT_STATUS "(iii)" + +WASM32_HOST_FUNC_HEADER(CREATE_EVENT) +WASM32_HOST_FUNC_HEADER(SET_EVENT) +WASM32_HOST_FUNC_HEADER(RESET_EVENT) +WASM32_HOST_FUNC_HEADER(WAIT_EVENT) +WASM32_HOST_FUNC_HEADER(GET_EVENT_ID) +WASM32_HOST_FUNC_HEADER(GET_EVENT_STATUS) + +#endif /* #ifndef ARINC653_PART1_APEX_EVENT_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_mutex_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_mutex_wasm32.c new file mode 100644 index 0000000..3cf3d42 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_mutex_wasm32.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: MUTEX + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part1_apex_mutex_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "a653Mutex.h" + + +WASM32_HOST_FUNCTION(CREATE_MUTEX, wasm_baseaddr, +{ + int32_t MUTEX_NAME; /* is a pointer / address into Wasm linear memory */ + MUTEX_NAME = (int32_t)le32toh(GET_ARG_i32(0)); + PRIORITY_TYPE MUTEX_PRIORITY; + MUTEX_PRIORITY = (PRIORITY_TYPE)le32toh(GET_ARG_i32(1)); + QUEUING_DISCIPLINE_TYPE QUEUING_DISCIPLINE; + QUEUING_DISCIPLINE = (QUEUING_DISCIPLINE_TYPE)le32toh(GET_ARG_i32(2)); + + MUTEX_ID_TYPE MUTEX_ID; + RETURN_CODE_TYPE RETURN_CODE; + + CREATE_MUTEX( + (char*)&wasm_baseaddr[MUTEX_NAME], + MUTEX_PRIORITY, + QUEUING_DISCIPLINE, + &MUTEX_ID, + &RETURN_CODE + ); + + camw32_set__MUTEX_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)MUTEX_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(ACQUIRE_MUTEX, wasm_baseaddr, +{ + MUTEX_ID_TYPE MUTEX_ID; + MUTEX_ID = (MUTEX_ID_TYPE)le32toh(GET_ARG_i32(0)); + SYSTEM_TIME_TYPE TIME_OUT; + TIME_OUT = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(1)); + + RETURN_CODE_TYPE RETURN_CODE; + + ACQUIRE_MUTEX( + MUTEX_ID, + TIME_OUT, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(RELEASE_MUTEX, wasm_baseaddr, +{ + MUTEX_ID_TYPE MUTEX_ID; + MUTEX_ID = (MUTEX_ID_TYPE)le32toh(GET_ARG_i32(0)); + + RETURN_CODE_TYPE RETURN_CODE; + + RELEASE_MUTEX( + MUTEX_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(RESET_MUTEX, wasm_baseaddr, +{ + MUTEX_ID_TYPE MUTEX_ID; + MUTEX_ID = (MUTEX_ID_TYPE)le32toh(GET_ARG_i32(0)); + PROCESS_ID_TYPE PROCESS_ID; + PROCESS_ID = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(1)); + + RETURN_CODE_TYPE RETURN_CODE; + + RESET_MUTEX( + MUTEX_ID, + PROCESS_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_MUTEX_ID, wasm_baseaddr, +{ + int32_t MUTEX_NAME; /* is a pointer / address into Wasm linear memory */ + MUTEX_NAME = (int32_t)le32toh(GET_ARG_i32(0)); + + MUTEX_ID_TYPE MUTEX_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_MUTEX_ID( + (char*)&wasm_baseaddr[MUTEX_NAME], + &MUTEX_ID, + &RETURN_CODE + ); + + camw32_set__MUTEX_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)MUTEX_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_MUTEX_STATUS, wasm_baseaddr, +{ + MUTEX_ID_TYPE MUTEX_ID; + MUTEX_ID = (MUTEX_ID_TYPE)le32toh(GET_ARG_i32(0)); + + MUTEX_STATUS_TYPE MUTEX_STATUS; + RETURN_CODE_TYPE RETURN_CODE; + + GET_MUTEX_STATUS( + MUTEX_ID, + &MUTEX_STATUS, + &RETURN_CODE + ); + + uint8_t* MUTEX_STATUS_guest = (uint8_t*)&wasm_baseaddr[le32toh(GET_ARG_i32(1))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + camw32_set__MUTEX_STATUS_TYPE__MUTEX_OWNER(MUTEX_STATUS_guest, MUTEX_STATUS.MUTEX_OWNER); + camw32_set__MUTEX_STATUS_TYPE__MUTEX_STATE(MUTEX_STATUS_guest, MUTEX_STATUS.MUTEX_STATE); + camw32_set__MUTEX_STATUS_TYPE__MUTEX_PRIORITY(MUTEX_STATUS_guest, MUTEX_STATUS.MUTEX_PRIORITY); + camw32_set__MUTEX_STATUS_TYPE__LOCK_COUNT(MUTEX_STATUS_guest, MUTEX_STATUS.LOCK_COUNT); + camw32_set__MUTEX_STATUS_TYPE__WAITING_PROCESSES(MUTEX_STATUS_guest, MUTEX_STATUS.WAITING_PROCESSES); +}) + + +WASM32_HOST_FUNCTION(GET_PROCESS_MUTEX_STATE, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + PROCESS_ID = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(0)); + + MUTEX_ID_TYPE MUTEX_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_PROCESS_MUTEX_STATE( + PROCESS_ID, + &MUTEX_ID, + &RETURN_CODE + ); + + camw32_set__MUTEX_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)MUTEX_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_mutex_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_mutex_wasm32.h new file mode 100644 index 0000000..b076d0f --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_mutex_wasm32.h @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: MUTEX + +#ifndef ARINC653_PART1_APEX_MUTEX_WASM32 +#define ARINC653_PART1_APEX_MUTEX_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): MUTEX */ +#define WASM32_SIGNATURE__CREATE_MUTEX "(iiiii)" +#define WASM32_SIGNATURE__ACQUIRE_MUTEX "(iIi)" +#define WASM32_SIGNATURE__RELEASE_MUTEX "(ii)" +#define WASM32_SIGNATURE__RESET_MUTEX "(iii)" +#define WASM32_SIGNATURE__GET_MUTEX_ID "(iii)" +#define WASM32_SIGNATURE__GET_MUTEX_STATUS "(iii)" +#define WASM32_SIGNATURE__GET_PROCESS_MUTEX_STATE "(iii)" + +WASM32_HOST_FUNC_HEADER(CREATE_MUTEX) +WASM32_HOST_FUNC_HEADER(ACQUIRE_MUTEX) +WASM32_HOST_FUNC_HEADER(RELEASE_MUTEX) +WASM32_HOST_FUNC_HEADER(RESET_MUTEX) +WASM32_HOST_FUNC_HEADER(GET_MUTEX_ID) +WASM32_HOST_FUNC_HEADER(GET_MUTEX_STATUS) +WASM32_HOST_FUNC_HEADER(GET_PROCESS_MUTEX_STATE) + +#endif /* #ifndef ARINC653_PART1_APEX_MUTEX_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_partition_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_partition_wasm32.c new file mode 100644 index 0000000..8161be6 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_partition_wasm32.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: PARTITION + + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part1_apex_partition_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "../a653_inc/a653Partition.h" + + +WASM32_HOST_FUNCTION(GET_PARTITION_STATUS, wasm_baseaddr, +{ + PARTITION_STATUS_TYPE STATUS; + RETURN_CODE_TYPE RETURN_CODE; + + GET_PARTITION_STATUS( + &STATUS, + &RETURN_CODE + ); + + uint8_t* STATUS_guest = &wasm_baseaddr[le32toh(GET_ARG_i32(0))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); + + camw32_set__PARTITION_STATUS_TYPE__PERIOD(STATUS_guest, STATUS.PERIOD); + camw32_set__PARTITION_STATUS_TYPE__DURATION(STATUS_guest, STATUS.DURATION); + camw32_set__PARTITION_STATUS_TYPE__IDENTIFIER(STATUS_guest, STATUS.IDENTIFIER); + camw32_set__PARTITION_STATUS_TYPE__LOCK_LEVEL(STATUS_guest, STATUS.LOCK_LEVEL); + camw32_set__PARTITION_STATUS_TYPE__OPERATING_MODE(STATUS_guest, STATUS.OPERATING_MODE); + camw32_set__PARTITION_STATUS_TYPE__START_CONDITION(STATUS_guest, STATUS.START_CONDITION); + camw32_set__PARTITION_STATUS_TYPE__NUM_ASSIGNED_CORES(STATUS_guest, STATUS.NUM_ASSIGNED_CORES); +}) + + +WASM32_HOST_FUNCTION(SET_PARTITION_MODE, wasm_baseaddr, +{ + OPERATING_MODE_TYPE OPERATING_MODE; + OPERATING_MODE = (OPERATING_MODE_TYPE)le32toh(GET_ARG_i32(0)); + RETURN_CODE_TYPE RETURN_CODE; + + SET_PARTITION_MODE( + OPERATING_MODE, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_partition_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_partition_wasm32.h new file mode 100644 index 0000000..7405f51 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_partition_wasm32.h @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: PARTITION + +#ifndef ARINC653_PART1_APEX_PARTITION_WASM32 +#define ARINC653_PART1_APEX_PARTITION_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): PARTITION */ +#define WASM32_SIGNATURE__GET_PARTITION_STATUS "(ii)" +#define WASM32_SIGNATURE__SET_PARTITION_MODE "(ii)" + +WASM32_HOST_FUNC_HEADER(GET_PARTITION_STATUS) +WASM32_HOST_FUNC_HEADER(SET_PARTITION_MODE) + +#endif /* #ifndef ARINC653_PART1_APEX_PARTITION_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.c new file mode 100644 index 0000000..70aece9 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.c @@ -0,0 +1,332 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: PROCESS + +#include +#include +#include +#include +#include "arinc653_wasm32_helper.h" +#include "generic_helper.h" +#include "arinc653_part1_apex_process_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "../a653_lib/a653_i_process.h" +#include "../a653_inc/a653Process.h" + + +WASM32_HOST_FUNCTION(GET_PROCESS_ID, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_PROCESS_ID( + (char*)&wasm_baseaddr[le32toh(GET_ARG_i32(0))], // FIXME: only safe as long as char[] + &PROCESS_ID, + &RETURN_CODE + ); + + camw32_set__PROCESS_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)PROCESS_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + + +extern wasm_prcs_info_t wasm_prcs_info; +extern prcs_info_t *prcs_info; + +void *wasm_trampoline(void) { + /* trying to reverse engineer the index within the a653lib */ + pthread_t tid = pthread_self(); + + int ret = 0; + for (unsigned i = 0; i < MAX_PRCS; ++i) { + if(prcs_info[i].t_ctx == tid) { + int64_t idx = wasm_prcs_info.ENTRY_POINT[prcs_info[i].id]; + ret = exec_wasm_guest_func(wasm_prcs_info.wasm_rt_ctx, idx); + break; + } + } + if ( ! ret) + fprintf(stderr, "ERR: wasm_processid not found\n"); + + return NULL; +} + + +WASM32_HOST_FUNCTION(GET_PROCESS_STATUS, wasm_baseaddr, +{ + PROCESS_ID_TYPE pid; + pid = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(0)); + RETURN_CODE_TYPE RETURN_CODE; + + PROCESS_STATUS_TYPE PROCESS_STATUS; + GET_PROCESS_STATUS( + pid, + &PROCESS_STATUS, + &RETURN_CODE + ); + + uint8_t* PROCESS_STATUS_guest = (uint8_t*)&wasm_baseaddr[le32toh(GET_ARG_i32(1))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + camw32_set__PROCESS_STATUS_TYPE__DEADLINE_TIME(PROCESS_STATUS_guest, PROCESS_STATUS.DEADLINE_TIME); + camw32_set__PROCESS_STATUS_TYPE__CURRENT_PRIORITY(PROCESS_STATUS_guest, PROCESS_STATUS.CURRENT_PRIORITY); + camw32_set__PROCESS_STATUS_TYPE__PROCESS_STATE(PROCESS_STATUS_guest, PROCESS_STATUS.PROCESS_STATE); + + uint8_t* ATTRIBUTES_guest = camw32_get_struct_base_addr__PROCESS_STATUS_TYPE__ATTRIBUTES(PROCESS_STATUS_guest); + camw32_set__PROCESS_ATTRIBUTE_TYPE__PERIOD(ATTRIBUTES_guest, PROCESS_STATUS.ATTRIBUTES.PERIOD); + camw32_set__PROCESS_ATTRIBUTE_TYPE__TIME_CAPACITY(ATTRIBUTES_guest, PROCESS_STATUS.ATTRIBUTES.TIME_CAPACITY); + uint32_t ENTRY_POINT_idx = wasm_prcs_info.ENTRY_POINT[pid]; + camw32_set__PROCESS_ATTRIBUTE_TYPE__ENTRY_POINT(ATTRIBUTES_guest, ENTRY_POINT_idx); + camw32_set__PROCESS_ATTRIBUTE_TYPE__STACK_SIZE(ATTRIBUTES_guest, PROCESS_STATUS.ATTRIBUTES.STACK_SIZE); + camw32_set__PROCESS_ATTRIBUTE_TYPE__BASE_PRIORITY(ATTRIBUTES_guest, PROCESS_STATUS.ATTRIBUTES.BASE_PRIORITY); + camw32_set__PROCESS_ATTRIBUTE_TYPE__DEADLINE(ATTRIBUTES_guest, PROCESS_STATUS.ATTRIBUTES.DEADLINE); + camw32_write__PROCESS_ATTRIBUTE_TYPE__NAME(ATTRIBUTES_guest, (uint8_t*)PROCESS_STATUS.ATTRIBUTES.NAME); +}) + + +WASM32_HOST_FUNCTION(CREATE_PROCESS, wasm_baseaddr, +{ + uint8_t* ATTRIBUTES__guest = (uint8_t*)&wasm_baseaddr[le32toh(GET_ARG_i32(0))]; + + PROCESS_ATTRIBUTE_TYPE ATTRIBUTES; + ATTRIBUTES.PERIOD = camw32_get__PROCESS_ATTRIBUTE_TYPE__PERIOD(ATTRIBUTES__guest); + ATTRIBUTES.TIME_CAPACITY = camw32_get__PROCESS_ATTRIBUTE_TYPE__TIME_CAPACITY(ATTRIBUTES__guest); + ATTRIBUTES.ENTRY_POINT = (typeof(ATTRIBUTES.ENTRY_POINT))(uintptr_t)&wasm_trampoline; + assert(sizeof(ATTRIBUTES.ENTRY_POINT) == sizeof(&wasm_trampoline)); + uint32_t ENTRY_POINT_idx = (uint32_t)camw32_get__PROCESS_ATTRIBUTE_TYPE__ENTRY_POINT(ATTRIBUTES__guest); + + ATTRIBUTES.STACK_SIZE = camw32_get__PROCESS_ATTRIBUTE_TYPE__STACK_SIZE(ATTRIBUTES__guest); + ATTRIBUTES.BASE_PRIORITY = camw32_get__PROCESS_ATTRIBUTE_TYPE__BASE_PRIORITY(ATTRIBUTES__guest); + ATTRIBUTES.DEADLINE = camw32_get__PROCESS_ATTRIBUTE_TYPE__DEADLINE(ATTRIBUTES__guest); + camw32_read__PROCESS_ATTRIBUTE_TYPE__NAME(ATTRIBUTES__guest, (uint8_t*)ATTRIBUTES.NAME); + + PROCESS_ID_TYPE PROCESS_ID; + RETURN_CODE_TYPE RETURN_CODE; + + CREATE_PROCESS( + &ATTRIBUTES, + &PROCESS_ID, + &RETURN_CODE + ); + + camw32_set__PROCESS_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)PROCESS_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + // we get the pid late, and the real start of the thread will be in CREATE_PROCESS + wasm_prcs_info.ENTRY_POINT[PROCESS_ID] = ENTRY_POINT_idx; +}) + + +WASM32_HOST_FUNCTION(SET_PRIORITY, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + PROCESS_ID = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(0)); + PRIORITY_TYPE PRIORITY; + PRIORITY = (PRIORITY_TYPE)le32toh(GET_ARG_i32(1)); + RETURN_CODE_TYPE RETURN_CODE; + + SET_PRIORITY( + PROCESS_ID, + PRIORITY, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(SUSPEND_SELF, wasm_baseaddr, +{ + SYSTEM_TIME_TYPE TIME_OUT; + TIME_OUT = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(0)); + RETURN_CODE_TYPE RETURN_CODE; + + SUSPEND_SELF( + TIME_OUT, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(SUSPEND, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + PROCESS_ID = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(0)); + RETURN_CODE_TYPE RETURN_CODE; + + SUSPEND( + PROCESS_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(RESUME, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + PROCESS_ID = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(0)); + RETURN_CODE_TYPE RETURN_CODE; + + RESUME( + PROCESS_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(STOP_SELF, wasm_baseaddr, +{ + (void)wasm_baseaddr; + + STOP_SELF( + ); +}) + + +WASM32_HOST_FUNCTION(STOP, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + PROCESS_ID = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(0)); + RETURN_CODE_TYPE RETURN_CODE; + + STOP( + PROCESS_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(START, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + PROCESS_ID = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(0)); + RETURN_CODE_TYPE RETURN_CODE; + + START( + PROCESS_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(DELAYED_START, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + PROCESS_ID = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(0)); + SYSTEM_TIME_TYPE DELAY_TIME; + DELAY_TIME = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(1)); + RETURN_CODE_TYPE RETURN_CODE; + + DELAYED_START( + PROCESS_ID, + DELAY_TIME, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(LOCK_PREEMPTION, wasm_baseaddr, +{ + LOCK_LEVEL_TYPE LOCK_LEVEL; + RETURN_CODE_TYPE RETURN_CODE; + + LOCK_PREEMPTION( + &LOCK_LEVEL, + &RETURN_CODE + ); + + camw32_set__LOCK_LEVEL_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(0))], (int32_t)LOCK_LEVEL); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(UNLOCK_PREEMPTION, wasm_baseaddr, +{ + LOCK_LEVEL_TYPE LOCK_LEVEL; + RETURN_CODE_TYPE RETURN_CODE; + + LOCK_PREEMPTION( + &LOCK_LEVEL, + &RETURN_CODE + ); + + camw32_set__LOCK_LEVEL_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(0))], (int32_t)LOCK_LEVEL); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_MY_ID, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_MY_ID( + &PROCESS_ID, + &RETURN_CODE + ); + + camw32_set__PROCESS_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(0))], (int32_t)PROCESS_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(INITIALIZE_PROCESS_CORE_AFFINITY, wasm_baseaddr, +{ + PROCESS_ID_TYPE PROCESS_ID; + PROCESS_ID = (PROCESS_ID_TYPE)le32toh(GET_ARG_i32(0)); + PROCESSOR_CORE_ID_TYPE PROCESSOR_CORE_ID; + PROCESSOR_CORE_ID = (PROCESSOR_CORE_ID_TYPE)le32toh(GET_ARG_i32(1)); + RETURN_CODE_TYPE RETURN_CODE; + + INITIALIZE_PROCESS_CORE_AFFINITY( + PROCESS_ID, + PROCESSOR_CORE_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_MY_PROCESSOR_CORE_ID, wasm_baseaddr, +{ + PROCESSOR_CORE_ID_TYPE PROCESSOR_CORE_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_MY_PROCESSOR_CORE_ID( + &PROCESSOR_CORE_ID, + &RETURN_CODE + ); + + camw32_set__PROCESSOR_CORE_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(0))], (int32_t)PROCESSOR_CORE_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_MY_INDEX, wasm_baseaddr, +{ + PROCESS_INDEX_TYPE PROCESS_INDEX; + RETURN_CODE_TYPE RETURN_CODE; + + GET_MY_INDEX( + &PROCESS_INDEX, + &RETURN_CODE + ); + + camw32_set__PROCESS_INDEX_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(0))], (int32_t)PROCESS_INDEX); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.h new file mode 100644 index 0000000..3390e2c --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.h @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: PROCESS + +#ifndef ARINC653_PART1_APEX_PROCESS_WASM32 +#define ARINC653_PART1_APEX_PROCESS_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): PROCESS */ +#define WASM32_SIGNATURE__GET_PROCESS_ID "(iii)" +#define WASM32_SIGNATURE__GET_PROCESS_STATUS "(iii)" +#define WASM32_SIGNATURE__CREATE_PROCESS "(iii)" +#define WASM32_SIGNATURE__SET_PRIORITY "(iii)" +#define WASM32_SIGNATURE__SUSPEND_SELF "(Ii)" +#define WASM32_SIGNATURE__SUSPEND "(ii)" +#define WASM32_SIGNATURE__RESUME "(ii)" +#define WASM32_SIGNATURE__STOP_SELF "()" +#define WASM32_SIGNATURE__STOP "(ii)" +#define WASM32_SIGNATURE__START "(ii)" +#define WASM32_SIGNATURE__DELAYED_START "(iIi)" +#define WASM32_SIGNATURE__LOCK_PREEMPTION "(ii)" +#define WASM32_SIGNATURE__UNLOCK_PREEMPTION "(ii)" +#define WASM32_SIGNATURE__GET_MY_ID "(ii)" +#define WASM32_SIGNATURE__INITIALIZE_PROCESS_CORE_AFFINITY "(iii)" +#define WASM32_SIGNATURE__GET_MY_PROCESSOR_CORE_ID "(ii)" +#define WASM32_SIGNATURE__GET_MY_INDEX "(ii)" + +WASM32_HOST_FUNC_HEADER(GET_PROCESS_ID) +WASM32_HOST_FUNC_HEADER(GET_PROCESS_STATUS) +WASM32_HOST_FUNC_HEADER(CREATE_PROCESS) +WASM32_HOST_FUNC_HEADER(SET_PRIORITY) +WASM32_HOST_FUNC_HEADER(SUSPEND_SELF) +WASM32_HOST_FUNC_HEADER(SUSPEND) +WASM32_HOST_FUNC_HEADER(RESUME) +WASM32_HOST_FUNC_HEADER(STOP_SELF) +WASM32_HOST_FUNC_HEADER(STOP) +WASM32_HOST_FUNC_HEADER(START) +WASM32_HOST_FUNC_HEADER(DELAYED_START) +WASM32_HOST_FUNC_HEADER(LOCK_PREEMPTION) +WASM32_HOST_FUNC_HEADER(UNLOCK_PREEMPTION) +WASM32_HOST_FUNC_HEADER(GET_MY_ID) +WASM32_HOST_FUNC_HEADER(INITIALIZE_PROCESS_CORE_AFFINITY) +WASM32_HOST_FUNC_HEADER(GET_MY_PROCESSOR_CORE_ID) +WASM32_HOST_FUNC_HEADER(GET_MY_INDEX) + +#endif /* #ifndef ARINC653_PART1_APEX_PROCESS_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_queuing_port_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_queuing_port_wasm32.c new file mode 100644 index 0000000..10843d4 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_queuing_port_wasm32.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: QUEUING PORT + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part1_apex_queuing_port_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "../a653_inc/a653Queuing.h" + + +WASM32_HOST_FUNCTION(CREATE_QUEUING_PORT, wasm_baseaddr, +{ + MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE; + MAX_MESSAGE_SIZE = (MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(1)); + MESSAGE_RANGE_TYPE MAX_NB_MESSAGE; + MAX_NB_MESSAGE = (MESSAGE_RANGE_TYPE)le32toh(GET_ARG_i32(2)); + PORT_DIRECTION_TYPE PORT_DIRECTION; + PORT_DIRECTION = (PORT_DIRECTION_TYPE)le32toh(GET_ARG_i32(3)); + QUEUING_DISCIPLINE_TYPE QUEUING_DISCIPLINE; + QUEUING_DISCIPLINE = (QUEUING_DISCIPLINE_TYPE)le32toh(GET_ARG_i32(4)); + QUEUING_PORT_ID_TYPE QUEUING_PORT_ID; + RETURN_CODE_TYPE RETURN_CODE; + + CREATE_QUEUING_PORT( + (char*)&wasm_baseaddr[le32toh(GET_ARG_i32(0))], // FIXME: only safe as long as char[] + MAX_MESSAGE_SIZE, + MAX_NB_MESSAGE, + PORT_DIRECTION, + QUEUING_DISCIPLINE, + &QUEUING_PORT_ID, + &RETURN_CODE + ); + + camw32_set__QUEUING_PORT_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(5))], (int32_t)QUEUING_PORT_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(6))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(SEND_QUEUING_MESSAGE, wasm_baseaddr, +{ + QUEUING_PORT_ID_TYPE QUEUING_PORT_ID; + QUEUING_PORT_ID = (QUEUING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = le32toh(GET_ARG_i32(1)); + MESSAGE_SIZE_TYPE LENGTH; + LENGTH = (MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(2)); + SYSTEM_TIME_TYPE TIME_OUT; + TIME_OUT = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(3)); + RETURN_CODE_TYPE RETURN_CODE; + + SEND_QUEUING_MESSAGE( + QUEUING_PORT_ID, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], // FIXME: only safe as long as char[] + LENGTH, + TIME_OUT, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(RECEIVE_QUEUING_MESSAGE, wasm_baseaddr, +{ + QUEUING_PORT_ID_TYPE QUEUING_PORT_ID; + QUEUING_PORT_ID = (QUEUING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + SYSTEM_TIME_TYPE TIME_OUT; + TIME_OUT = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(1)); + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = le32toh(GET_ARG_i32(2)); + MESSAGE_SIZE_TYPE LENGTH; + RETURN_CODE_TYPE RETURN_CODE; + + RECEIVE_QUEUING_MESSAGE( + QUEUING_PORT_ID, + TIME_OUT, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], // FIXME: only safe as long as char[] + &LENGTH, + &RETURN_CODE + ); + + camw32_set__MESSAGE_SIZE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)LENGTH); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_QUEUING_PORT_ID, wasm_baseaddr, +{ + QUEUING_PORT_ID_TYPE QUEUING_PORT_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_QUEUING_PORT_ID( + (char*)&wasm_baseaddr[le32toh(GET_ARG_i32(0))], // FIXME: only safe as long as char[] + &QUEUING_PORT_ID, + &RETURN_CODE + ); + + camw32_set__QUEUING_PORT_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)QUEUING_PORT_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_QUEUING_PORT_STATUS, wasm_baseaddr, +{ + QUEUING_PORT_ID_TYPE QUEUING_PORT_ID; + QUEUING_PORT_ID = (QUEUING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + QUEUING_PORT_STATUS_TYPE QUEUING_PORT_STATUS; + RETURN_CODE_TYPE RETURN_CODE; + + GET_QUEUING_PORT_STATUS( + QUEUING_PORT_ID, + &QUEUING_PORT_STATUS, + &RETURN_CODE + ); + + uint8_t* QUEUING_PORT_STATUS_guest = (uint8_t*)&wasm_baseaddr[le32toh(GET_ARG_i32(1))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + camw32_set__QUEUING_PORT_STATUS_TYPE__NB_MESSAGE(QUEUING_PORT_STATUS_guest, QUEUING_PORT_STATUS.NB_MESSAGE); + camw32_set__QUEUING_PORT_STATUS_TYPE__MAX_NB_MESSAGE(QUEUING_PORT_STATUS_guest, QUEUING_PORT_STATUS.MAX_NB_MESSAGE); + camw32_set__QUEUING_PORT_STATUS_TYPE__MAX_MESSAGE_SIZE(QUEUING_PORT_STATUS_guest, QUEUING_PORT_STATUS.MAX_MESSAGE_SIZE); + camw32_set__QUEUING_PORT_STATUS_TYPE__PORT_DIRECTION(QUEUING_PORT_STATUS_guest, QUEUING_PORT_STATUS.PORT_DIRECTION); + camw32_set__QUEUING_PORT_STATUS_TYPE__WAITING_PROCESSES(QUEUING_PORT_STATUS_guest, QUEUING_PORT_STATUS.WAITING_PROCESSES); +}) + + +WASM32_HOST_FUNCTION(CLEAR_QUEUING_PORT, wasm_baseaddr, +{ + QUEUING_PORT_ID_TYPE QUEUING_PORT_ID; + QUEUING_PORT_ID = (QUEUING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + RETURN_CODE_TYPE RETURN_CODE; + + CLEAR_QUEUING_PORT( + QUEUING_PORT_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_queuing_port_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_queuing_port_wasm32.h new file mode 100644 index 0000000..87716cc --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_queuing_port_wasm32.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: QUEUING PORT + +#ifndef ARINC653_PART1_APEX_QUEUING_PORT_WASM32 +#define ARINC653_PART1_APEX_QUEUING_PORT_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): QUEUING PORT */ +#define WASM32_SIGNATURE__CREATE_QUEUING_PORT "(iiiiiii)" +#define WASM32_SIGNATURE__SEND_QUEUING_MESSAGE "(iiiIi)" +#define WASM32_SIGNATURE__RECEIVE_QUEUING_MESSAGE "(iIiii)" +#define WASM32_SIGNATURE__GET_QUEUING_PORT_ID "(iii)" +#define WASM32_SIGNATURE__GET_QUEUING_PORT_STATUS "(iii)" +#define WASM32_SIGNATURE__CLEAR_QUEUING_PORT "(ii)" + +WASM32_HOST_FUNC_HEADER(CREATE_QUEUING_PORT) +WASM32_HOST_FUNC_HEADER(SEND_QUEUING_MESSAGE) +WASM32_HOST_FUNC_HEADER(RECEIVE_QUEUING_MESSAGE) +WASM32_HOST_FUNC_HEADER(GET_QUEUING_PORT_ID) +WASM32_HOST_FUNC_HEADER(GET_QUEUING_PORT_STATUS) +WASM32_HOST_FUNC_HEADER(CLEAR_QUEUING_PORT) + +#endif /* #ifndef ARINC653_PART1_APEX_QUEUING_PORT_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_sampling_port_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_sampling_port_wasm32.c new file mode 100644 index 0000000..6b5d790 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_sampling_port_wasm32.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: SAMPLING PORT + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part1_apex_sampling_port_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "../a653_inc/a653Sampling.h" + + +WASM32_HOST_FUNCTION(CREATE_SAMPLING_PORT, wasm_baseaddr, +{ + MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE; + MAX_MESSAGE_SIZE = (MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(1)); + PORT_DIRECTION_TYPE PORT_DIRECTION; + PORT_DIRECTION = (PORT_DIRECTION_TYPE)le32toh(GET_ARG_i32(2)); + SYSTEM_TIME_TYPE REFRESH_PERIOD; + REFRESH_PERIOD = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(3)); + SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID; + RETURN_CODE_TYPE RETURN_CODE; + + CREATE_SAMPLING_PORT( + (char*)&wasm_baseaddr[le32toh(GET_ARG_i32(0))], // FIXME: only safe as long as char[] + MAX_MESSAGE_SIZE, + PORT_DIRECTION, + REFRESH_PERIOD, + &SAMPLING_PORT_ID, + &RETURN_CODE + ); + + camw32_set__SAMPLING_PORT_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)SAMPLING_PORT_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(5))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(WRITE_SAMPLING_MESSAGE, wasm_baseaddr, +{ + SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID; + SAMPLING_PORT_ID = (SAMPLING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = le32toh(GET_ARG_i32(1)); + MESSAGE_SIZE_TYPE LENGTH; + LENGTH = (MESSAGE_SIZE_TYPE)le32toh(GET_ARG_i32(2)); + RETURN_CODE_TYPE RETURN_CODE; + + WRITE_SAMPLING_MESSAGE( + SAMPLING_PORT_ID, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], // FIXME: only safe as long as char[] + LENGTH, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(READ_SAMPLING_MESSAGE, wasm_baseaddr, +{ + SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID; + SAMPLING_PORT_ID = (SAMPLING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = le32toh(GET_ARG_i32(1)); + MESSAGE_SIZE_TYPE LENGTH; + VALIDITY_TYPE VALIDITY; + RETURN_CODE_TYPE RETURN_CODE; + + READ_SAMPLING_MESSAGE( + SAMPLING_PORT_ID, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], // FIXME: only safe as long as char[] + &LENGTH, + &VALIDITY, + &RETURN_CODE + ); + + camw32_set__MESSAGE_SIZE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)LENGTH); + camw32_set__VALIDITY_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)VALIDITY); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_SAMPLING_PORT_ID, wasm_baseaddr, +{ + SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_SAMPLING_PORT_ID( + (char*)&wasm_baseaddr[le32toh(GET_ARG_i32(0))], // FIXME: only safe as long as char[] + &SAMPLING_PORT_ID, + &RETURN_CODE + ); + + camw32_set__SAMPLING_PORT_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)SAMPLING_PORT_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_SAMPLING_PORT_STATUS, wasm_baseaddr, +{ + SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID; + SAMPLING_PORT_ID = (SAMPLING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + SAMPLING_PORT_STATUS_TYPE SAMPLING_PORT_STATUS; + RETURN_CODE_TYPE RETURN_CODE; + + GET_SAMPLING_PORT_STATUS( + SAMPLING_PORT_ID, + &SAMPLING_PORT_STATUS, + &RETURN_CODE + ); + + uint8_t* SAMPLING_PORT_STATUS__guest = &wasm_baseaddr[le32toh(GET_ARG_i32(1))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + camw32_set__SAMPLING_PORT_STATUS_TYPE__MAX_MESSAGE_SIZE(SAMPLING_PORT_STATUS__guest, SAMPLING_PORT_STATUS.MAX_MESSAGE_SIZE); + camw32_set__SAMPLING_PORT_STATUS_TYPE__PORT_DIRECTION(SAMPLING_PORT_STATUS__guest, SAMPLING_PORT_STATUS.PORT_DIRECTION); + camw32_set__SAMPLING_PORT_STATUS_TYPE__REFRESH_PERIOD(SAMPLING_PORT_STATUS__guest, SAMPLING_PORT_STATUS.REFRESH_PERIOD); + camw32_set__SAMPLING_PORT_STATUS_TYPE__LAST_MSG_VALIDITY(SAMPLING_PORT_STATUS__guest, SAMPLING_PORT_STATUS.LAST_MSG_VALIDITY); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_sampling_port_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_sampling_port_wasm32.h new file mode 100644 index 0000000..04ed3f7 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_sampling_port_wasm32.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: SAMPLING PORT + +#ifndef ARINC653_PART1_APEX_SAMPLING_PORT_WASM32 +#define ARINC653_PART1_APEX_SAMPLING_PORT_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): SAMPLING PORT */ +#define WASM32_SIGNATURE__CREATE_SAMPLING_PORT "(iiiIii)" +#define WASM32_SIGNATURE__WRITE_SAMPLING_MESSAGE "(iiii)" +#define WASM32_SIGNATURE__READ_SAMPLING_MESSAGE "(iiiii)" +#define WASM32_SIGNATURE__GET_SAMPLING_PORT_ID "(iii)" +#define WASM32_SIGNATURE__GET_SAMPLING_PORT_STATUS "(iii)" + +WASM32_HOST_FUNC_HEADER(CREATE_SAMPLING_PORT) +WASM32_HOST_FUNC_HEADER(WRITE_SAMPLING_MESSAGE) +WASM32_HOST_FUNC_HEADER(READ_SAMPLING_MESSAGE) +WASM32_HOST_FUNC_HEADER(GET_SAMPLING_PORT_ID) +WASM32_HOST_FUNC_HEADER(GET_SAMPLING_PORT_STATUS) + +#endif /* #ifndef ARINC653_PART1_APEX_SAMPLING_PORT_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_semaphore_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_semaphore_wasm32.c new file mode 100644 index 0000000..a4a405b --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_semaphore_wasm32.c @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: SEMAPHORE + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part1_apex_semaphore_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "../a653_inc/a653Semaphore.h" + + +WASM32_HOST_FUNCTION(CREATE_SEMAPHORE, wasm_baseaddr, +{ + SEMAPHORE_VALUE_TYPE CURRENT_VALUE; + CURRENT_VALUE = (SEMAPHORE_VALUE_TYPE)le32toh(GET_ARG_i32(1)); + SEMAPHORE_VALUE_TYPE MAXIMUM_VALUE; + MAXIMUM_VALUE = (SEMAPHORE_VALUE_TYPE)le32toh(GET_ARG_i32(2)); + QUEUING_DISCIPLINE_TYPE QUEUING_DISCIPLINE; + QUEUING_DISCIPLINE = (QUEUING_DISCIPLINE_TYPE)le32toh(GET_ARG_i32(3)); + SEMAPHORE_ID_TYPE SEMAPHORE_ID; + RETURN_CODE_TYPE RETURN_CODE; + + CREATE_SEMAPHORE( + (char*)&wasm_baseaddr[le32toh(GET_ARG_i32(0))], // FIXME: only safe as long as char[] + CURRENT_VALUE, + MAXIMUM_VALUE, + QUEUING_DISCIPLINE, + &SEMAPHORE_ID, + &RETURN_CODE + ); + + camw32_set__SEMAPHORE_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)SEMAPHORE_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(5))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(WAIT_SEMAPHORE, wasm_baseaddr, +{ + SEMAPHORE_ID_TYPE SEMAPHORE_ID; + SEMAPHORE_ID = (SEMAPHORE_ID_TYPE)le32toh(GET_ARG_i32(0)); + SYSTEM_TIME_TYPE TIME_OUT; + TIME_OUT = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(1)); + RETURN_CODE_TYPE RETURN_CODE; + + WAIT_SEMAPHORE( + SEMAPHORE_ID, + TIME_OUT, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(SIGNAL_SEMAPHORE, wasm_baseaddr, +{ + SEMAPHORE_ID_TYPE SEMAPHORE_ID; + SEMAPHORE_ID = (SEMAPHORE_ID_TYPE)le32toh(GET_ARG_i32(0)); + RETURN_CODE_TYPE RETURN_CODE; + + SIGNAL_SEMAPHORE( + SEMAPHORE_ID, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_SEMAPHORE_ID, wasm_baseaddr, +{ + SEMAPHORE_ID_TYPE SEMAPHORE_ID; + RETURN_CODE_TYPE RETURN_CODE; + + GET_SEMAPHORE_ID( + (char*)&wasm_baseaddr[le32toh(GET_ARG_i32(0))], // FIXME: only safe as long as char[] + &SEMAPHORE_ID, + &RETURN_CODE + ); + + camw32_set__SEMAPHORE_ID_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)SEMAPHORE_ID); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_SEMAPHORE_STATUS, wasm_baseaddr, +{ + SEMAPHORE_ID_TYPE SEMAPHORE_ID; + SEMAPHORE_ID = (SEMAPHORE_ID_TYPE)le32toh(GET_ARG_i32(0)); + SEMAPHORE_STATUS_TYPE SEMAPHORE_STATUS; + RETURN_CODE_TYPE RETURN_CODE; + + GET_SEMAPHORE_STATUS( + SEMAPHORE_ID, + &SEMAPHORE_STATUS, + &RETURN_CODE + ); + + uint8_t* SEMAPHORE_STATUS_guest = (uint8_t*)&wasm_baseaddr[le32toh(GET_ARG_i32(1))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + camw32_set__SEMAPHORE_STATUS_TYPE__CURRENT_VALUE(SEMAPHORE_STATUS_guest, SEMAPHORE_STATUS.CURRENT_VALUE); + camw32_set__SEMAPHORE_STATUS_TYPE__MAXIMUM_VALUE(SEMAPHORE_STATUS_guest, SEMAPHORE_STATUS.MAXIMUM_VALUE); + camw32_set__SEMAPHORE_STATUS_TYPE__WAITING_PROCESSES(SEMAPHORE_STATUS_guest, SEMAPHORE_STATUS.WAITING_PROCESSES); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_semaphore_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_semaphore_wasm32.h new file mode 100644 index 0000000..f847e29 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_semaphore_wasm32.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: SEMAPHORE + +#ifndef ARINC653_PART1_APEX_SEMAPHORE_WASM32 +#define ARINC653_PART1_APEX_SEMAPHORE_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): SEMAPHORE */ +#define WASM32_SIGNATURE__CREATE_SEMAPHORE "(iiiiii)" +#define WASM32_SIGNATURE__WAIT_SEMAPHORE "(iIi)" +#define WASM32_SIGNATURE__SIGNAL_SEMAPHORE "(ii)" +#define WASM32_SIGNATURE__GET_SEMAPHORE_ID "(iii)" +#define WASM32_SIGNATURE__GET_SEMAPHORE_STATUS "(iii)" + +WASM32_HOST_FUNC_HEADER(CREATE_SEMAPHORE) +WASM32_HOST_FUNC_HEADER(WAIT_SEMAPHORE) +WASM32_HOST_FUNC_HEADER(SIGNAL_SEMAPHORE) +WASM32_HOST_FUNC_HEADER(GET_SEMAPHORE_ID) +WASM32_HOST_FUNC_HEADER(GET_SEMAPHORE_STATUS) + +#endif /* #ifndef ARINC653_PART1_APEX_SEMAPHORE_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_time_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_time_wasm32.c new file mode 100644 index 0000000..18b0333 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_time_wasm32.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: TIME + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part1_apex_time_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "../a653_inc/a653Time.h" + + +WASM32_HOST_FUNCTION(TIMED_WAIT, wasm_baseaddr, +{ + SYSTEM_TIME_TYPE DELAY_TIME; + DELAY_TIME = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(0)); + RETURN_CODE_TYPE RETURN_CODE; + + TIMED_WAIT( + DELAY_TIME, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(PERIODIC_WAIT, wasm_baseaddr, +{ + RETURN_CODE_TYPE RETURN_CODE; + + PERIODIC_WAIT( + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(0))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_TIME, wasm_baseaddr, +{ + SYSTEM_TIME_TYPE SYSTEM_TIME; + RETURN_CODE_TYPE RETURN_CODE; + + GET_TIME( + &SYSTEM_TIME, + &RETURN_CODE + ); + + camw32_set__SYSTEM_TIME_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(0))], (int64_t)SYSTEM_TIME); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(REPLENISH, wasm_baseaddr, +{ + SYSTEM_TIME_TYPE BUDGET_TIME; + BUDGET_TIME = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(0)); + RETURN_CODE_TYPE RETURN_CODE; + + REPLENISH( + BUDGET_TIME, + &RETURN_CODE + ); + + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(1))], (int32_t)RETURN_CODE); +}) diff --git a/a653_lib_wasm32/arinc653_part1_apex_time_wasm32.h b/a653_lib_wasm32/arinc653_part1_apex_time_wasm32.h new file mode 100644 index 0000000..457cdf9 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_time_wasm32.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 1: APEX Interface: TIME + +#ifndef ARINC653_PART1_APEX_TIME_WASM32 +#define ARINC653_PART1_APEX_TIME_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 1): TIME */ +#define WASM32_SIGNATURE__TIMED_WAIT "(Ii)" +#define WASM32_SIGNATURE__PERIODIC_WAIT "(i)" +#define WASM32_SIGNATURE__GET_TIME "(ii)" +#define WASM32_SIGNATURE__REPLENISH "(Ii)" + +WASM32_HOST_FUNC_HEADER(TIMED_WAIT) +WASM32_HOST_FUNC_HEADER(PERIODIC_WAIT) +WASM32_HOST_FUNC_HEADER(GET_TIME) +WASM32_HOST_FUNC_HEADER(REPLENISH) + +#endif /* #ifndef ARINC653_PART1_APEX_TIME_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_part2_apex_sampling_port_extension_wasm32.c b/a653_lib_wasm32/arinc653_part2_apex_sampling_port_extension_wasm32.c new file mode 100644 index 0000000..f2c6927 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part2_apex_sampling_port_extension_wasm32.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 2: APEX Interface: SAMPLING PORT EXTENSION + +#include +#include "arinc653_wasm32_helper.h" +#include "arinc653_part2_apex_sampling_port_extension_wasm32.h" +#include "camw32_getset.h" /* auto-generated header */ +#include "../a653_inc/a653Sampling.h" + + +WASM32_HOST_FUNCTION(READ_UPDATED_SAMPLING_MESSAGE, wasm_baseaddr, +{ + SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID; + SAMPLING_PORT_ID = (SAMPLING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = (int32_t)le32toh(GET_ARG_i32(1)); + MESSAGE_SIZE_TYPE LENGTH; + UPDATED_TYPE UPDATED; + RETURN_CODE_TYPE RETURN_CODE; + + READ_UPDATED_SAMPLING_MESSAGE( + SAMPLING_PORT_ID, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], + &LENGTH, + &UPDATED, + &RETURN_CODE + ); + + camw32_set__MESSAGE_SIZE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)LENGTH); + camw32_set__UPDATED_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)UPDATED); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int32_t)RETURN_CODE); +}) + + +WASM32_HOST_FUNCTION(GET_SAMPLING_PORT_CURRENT_STATUS, wasm_baseaddr, +{ + SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID; + SAMPLING_PORT_ID = (SAMPLING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + SAMPLING_PORT_CURRENT_STATUS_TYPE SAMPLING_PORT_CURRENT_STATUS; + RETURN_CODE_TYPE RETURN_CODE; + + GET_SAMPLING_PORT_CURRENT_STATUS( + SAMPLING_PORT_ID, + &SAMPLING_PORT_CURRENT_STATUS, + &RETURN_CODE + ); + + // TODO: could still be an issue, with using the args_and_results[].i32 directly due to LE/BE + uint8_t* SAMPLING_PORT_CURRENT_STATUS__guest = (uint8_t*)&wasm_baseaddr[le32toh(GET_ARG_i32(1))]; + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(2))], (int32_t)RETURN_CODE); + + camw32_set__SAMPLING_PORT_CURRENT_STATUS_TYPE__REFRESH_PERIOD(SAMPLING_PORT_CURRENT_STATUS__guest, SAMPLING_PORT_CURRENT_STATUS.REFRESH_PERIOD); + camw32_set__SAMPLING_PORT_CURRENT_STATUS_TYPE__TIME_STAMP(SAMPLING_PORT_CURRENT_STATUS__guest, SAMPLING_PORT_CURRENT_STATUS.TIME_STAMP); + camw32_set__SAMPLING_PORT_CURRENT_STATUS_TYPE__MAX_MESSAGE_SIZE(SAMPLING_PORT_CURRENT_STATUS__guest, SAMPLING_PORT_CURRENT_STATUS.MAX_MESSAGE_SIZE); + camw32_set__SAMPLING_PORT_CURRENT_STATUS_TYPE__PORT_DIRECTION(SAMPLING_PORT_CURRENT_STATUS__guest, SAMPLING_PORT_CURRENT_STATUS.PORT_DIRECTION); + camw32_set__SAMPLING_PORT_CURRENT_STATUS_TYPE__MESSAGE_AGE(SAMPLING_PORT_CURRENT_STATUS__guest, SAMPLING_PORT_CURRENT_STATUS.MESSAGE_AGE); + camw32_set__SAMPLING_PORT_CURRENT_STATUS_TYPE__UPDATED(SAMPLING_PORT_CURRENT_STATUS__guest, SAMPLING_PORT_CURRENT_STATUS.UPDATED); +}) + + +WASM32_HOST_FUNCTION(READ_SAMPLING_MESSAGE_CONDITIONAL, wasm_baseaddr, +{ + SAMPLING_PORT_ID_TYPE SAMPLING_PORT_ID; + SAMPLING_PORT_ID = (SAMPLING_PORT_ID_TYPE)le32toh(GET_ARG_i32(0)); + SYSTEM_TIME_TYPE REF_TIME_STAMP; + REF_TIME_STAMP = (SYSTEM_TIME_TYPE)le64toh(GET_ARG_i64(1)); + int32_t MESSAGE_ADDR; /* is a pointer / address into Wasm linear memory */ + MESSAGE_ADDR = (int32_t)le32toh(GET_ARG_i32(2)); + MESSAGE_SIZE_TYPE LENGTH; + SYSTEM_TIME_TYPE TIME_STAMP; + RETURN_CODE_TYPE RETURN_CODE; + + READ_SAMPLING_MESSAGE_CONDITIONAL( + SAMPLING_PORT_ID, + REF_TIME_STAMP, + (MESSAGE_ADDR_TYPE)&wasm_baseaddr[MESSAGE_ADDR], + &LENGTH, + &TIME_STAMP, + &RETURN_CODE + ); + + camw32_set__MESSAGE_SIZE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(3))], (int32_t)LENGTH); + camw32_set__SYSTEM_TIME_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(4))], (int64_t)TIME_STAMP); + camw32_set__RETURN_CODE_TYPE(&wasm_baseaddr[le32toh(GET_ARG_i32(5))], (int32_t)RETURN_CODE); +}) diff --git a/a653_lib_wasm32/arinc653_part2_apex_sampling_port_extension_wasm32.h b/a653_lib_wasm32/arinc653_part2_apex_sampling_port_extension_wasm32.h new file mode 100644 index 0000000..535e213 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part2_apex_sampling_port_extension_wasm32.h @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl +// ARINC 653 Part 2: APEX Interface: SAMPLING PORT EXTENSION + +#ifndef ARINC653_PART2_APEX_SAMPLING_PORT_EXTENSION_WASM32 +#define ARINC653_PART2_APEX_SAMPLING_PORT_EXTENSION_WASM32 + +#include "arinc653_wasm32_helper.h" + +/* APEX (ARINC 653 Part 2): SAMPLING PORT EXTENSIONS */ +#define WASM32_SIGNATURE__READ_UPDATED_SAMPLING_MESSAGE "(iiiii)" +#define WASM32_SIGNATURE__GET_SAMPLING_PORT_CURRENT_STATUS "(iii)" +#define WASM32_SIGNATURE__READ_SAMPLING_MESSAGE_CONDITIONAL "(iIiiii)" + +WASM32_HOST_FUNC_HEADER(READ_UPDATED_SAMPLING_MESSAGE) +WASM32_HOST_FUNC_HEADER(GET_SAMPLING_PORT_CURRENT_STATUS) +WASM32_HOST_FUNC_HEADER(READ_SAMPLING_MESSAGE_CONDITIONAL) + +#endif /* #ifndef ARINC653_PART2_APEX_SAMPLING_PORT_EXTENSION_WASM32 */ diff --git a/a653_lib_wasm32/arinc653_wasm32_helper.h b/a653_lib_wasm32/arinc653_wasm32_helper.h new file mode 100644 index 0000000..2b3e4c9 --- /dev/null +++ b/a653_lib_wasm32/arinc653_wasm32_helper.h @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#ifndef ARINC653_WASM32_HELPER + +#ifdef __WAMR__ +#include +#include +#include "a653_wamr.h" + +#define GET_ARG_i32( X ) (*(uint32_t*)&args[X]) +#define GET_ARG_i64( X ) (*(uint64_t*)&args[X]) + +#else // WASMTIME +#include +#include +#include "a653_wasmtime.h" + +#define GET_ARG_i32( X ) args_and_results[X].i32 +#define GET_ARG_i64( X ) args_and_results[X].i64 +#endif + + +#ifdef __WAMR__ + +#define WASM32_HOST_FUNC_HEADER(NAME) \ +void WASM32_##NAME( \ + wasm_exec_env_t exec_env, \ + uint64_t *args); + +#define WASM32_HOST_FUNCTION(NAME, WASM_BASEADDR, CONTENT) \ +void WASM32_##NAME( \ + wasm_exec_env_t exec_env, \ + uint64_t *args) \ +{ \ + wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env); \ + uint8_t* (WASM_BASEADDR) = wasm_runtime_addr_app_to_native(module_inst, 0); \ + \ + CONTENT \ + \ +} + +#else // WASMTIME + +#define WASM32_HOST_FUNC_HEADER(NAME) \ +wasm_trap_t* WASM32_##NAME(void* env, \ + wasmtime_caller_t *caller, \ + wasmtime_val_raw_t *args_and_results, size_t num_args_and_results); + +#define WASM32_HOST_FUNCTION(NAME, WASM_BASEADDR, CONTENT) \ +wasm_trap_t* WASM32_##NAME(void* env, \ + wasmtime_caller_t *caller, \ + wasmtime_val_raw_t *args_and_results, size_t num_args_and_results) \ +{ \ + wasmtime_extern_t ext; \ + const char *m = "memory"; \ + if ( ! wasmtime_caller_export_get(caller, m, strlen(m), &ext)) { \ + fprintf(stderr, "ERR: "#NAME" 'memory' export not found!\n"); \ + return NULL; \ + } \ + \ + if (ext.kind != WASM_EXTERN_MEMORY) { \ + fprintf(stderr, "ERR: "#NAME" export 'memory' is not a memory!\n"); \ + return NULL; \ + } \ + \ + wasmtime_context_t *context = wasmtime_caller_context(caller); \ + uint8_t* (WASM_BASEADDR) = wasmtime_memory_data(context, &ext.of.memory); \ + \ + CONTENT \ + \ + return NULL; \ +} + +#endif + +#endif /* #ifndef ARINC653_WASM32_HELPER */ diff --git a/a653_lib_wasm32/generic_helper.c b/a653_lib_wasm32/generic_helper.c new file mode 100644 index 0000000..f8c3ae0 --- /dev/null +++ b/a653_lib_wasm32/generic_helper.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#include "generic_helper.h" + +#include +#include + +// Helper to load a binary file (e.g., guest.wasm) +wasm_file_t* load_wasm_file(const char* filename) +{ + FILE* file = fopen(filename, "rb"); + if (!file) { + fprintf(stderr, "❌ Failed to open wasm file"); + return NULL; + } + + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + rewind(file); + + wasm_file_t* wasm = (wasm_file_t*) malloc (sizeof(wasm_file_t) + file_size); + wasm->size = file_size; + if (fread(wasm->data, file_size, 1, file) != 1) { + fprintf(stderr, "ERR: Failed to read wasm file!\n"); + free(wasm); + return NULL; + } + fclose(file); + + return wasm; +} + +// https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/doc/export_native_api.md +int signature_parameter_count(const char *signature) { + int parmc = 0; + for (char *s = (char*)signature, *bgn_braket = NULL; *s != '\0'; ++s) { + switch ( *s ) { + case '(': + bgn_braket = s; + break; + case ')': + if (*bgn_braket != '(') { + fprintf(stderr, "ERR: end braket without begin braket!\n"); + return -1; + } + return parmc; // done + break; + case 'i': // 32-bit integer (i32) + case 'I': // 64-bit integer (i64) + case 'f': // 32-bit float (f32) + case 'F': // 64-bit float (f64) + case 'r': // externref type (usually a uintptr_t), or GC references + case '$': // String in WASM memory + ++parmc; + break; + // *~ after a * there is always a ~ + case '*': // Buffer address (pointer) in WASM memory + ++s; + if(*s != '~') { + fprintf(stderr, "ERR: not supported character sequence *%c!\n", *s); + return -1; + } +// parmc += 2; + fprintf(stderr, "ERR: not supported character *~!\n"); + return -1; + default: + case '~': // Byte length of the preceding buffer pointer (*), must follow * + fprintf(stderr, "ERR: not supported character %c!\n", *s); + return -1; + } + } + return -1; +} diff --git a/a653_lib_wasm32/generic_helper.h b/a653_lib_wasm32/generic_helper.h new file mode 100644 index 0000000..fa5b9fa --- /dev/null +++ b/a653_lib_wasm32/generic_helper.h @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#ifndef GENERIC_HELPER +#define GENERIC_HELPER + +#include +#include +#include +#include "../a653_inc/a653Init.h" // MAX_PRCS + +#define HAS_64BIT_MEM false + +typedef struct { + uint32_t ENTRY_POINT[MAX_PRCS]; + uint32_t ENTRY_POINT_ERROR_HANDLER; + void* wasm_rt_ctx; +} wasm_prcs_info_t; + +typedef struct { + size_t size; + unsigned char data[]; +} wasm_file_t; + +wasm_file_t* load_wasm_file(const char* filename); + +int signature_parameter_count(const char *signature); + +#endif /* #ifndef GENERIC_HELPER */ diff --git a/a653_lib_wasm32/wasm32_main.c b/a653_lib_wasm32/wasm32_main.c new file mode 100644 index 0000000..0f93077 --- /dev/null +++ b/a653_lib_wasm32/wasm32_main.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +// SPDX-FileCopyrightText: Copyright 2025 Airbus Defence and Space +// SPDX-FileContributor: Patrick Siegl + +#include +#include + +#include "generic_helper.h" +#ifdef __WAMR__ +#include "a653_wamr.h" +#else +#include "a653_wasmtime.h" +#endif + +/* + * 1. Ugly learning about WASM: re-alloc of memory -> base address moves. + * The guests memory is - obviously - backed by malloc/mmap. + * In case, the guest uses more and more memory, a re-alloc is performed, + * which must not but can very likely lead to a new memory area within the host. + * Consequently, the base address of this memory region is very likely different, + * each time the hosts tries to reference this memory. As of this, we need to + * get over and over again i.e. for each host func call the (new) memory base addr. + * + */ + +// wasmtime_memory_data_size (const wasmtime_context_t *store, const wasmtime_memory_t *memory) // FIXME: could do a bounds check! + +wasm_prcs_info_t wasm_prcs_info; + +int main(int argc, char* argv[]) +{ + // FIXME with proper getopt() + if (argc < 2) { + fprintf(stderr, "Usage: %s guest.wasm\n", argv[0]); + return -1; + } + const char *wasm_file = argv[1]; + + // Load .wasm binary supplied + wasm_file_t* wasm = load_wasm_file(wasm_file); + + wasm_prcs_info.wasm_rt_ctx = generate_wasm_runtime_context(wasm); + free(wasm); + if ( ! wasm_prcs_info.wasm_rt_ctx) + return -1; + + if (exec_wasm_guest_func(wasm_prcs_info.wasm_rt_ctx, -1) != 0 ) + fprintf(stderr, "ERR: wasm_processid not found\n"); + + cleanup_wasm_runtime_context(wasm_prcs_info.wasm_rt_ctx); + free(wasm_prcs_info.wasm_rt_ctx); + + return 0; +} diff --git a/flake.lock b/flake.lock index 0d6d014..82823cc 100644 --- a/flake.lock +++ b/flake.lock @@ -1,9 +1,48 @@ { "nodes": { + "arinc653-wasm": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1761251296, + "narHash": "sha256-e6ixhgT5/bHfRoUz9+vrMMLgFPHXjUV/SLGlwWnMYOk=", + "owner": "psiegl", + "repo": "arinc653-wasm", + "rev": "287a3419c7adc9c51f0c7cc2863fbfa15e3a9d39", + "type": "github" + }, + "original": { + "owner": "psiegl", + "ref": "psiegl-old", + "repo": "arinc653-wasm", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, "locked": { "lastModified": 1710146030, "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", @@ -20,11 +59,27 @@ }, "nixpkgs": { "locked": { - "lastModified": 1763948260, - "narHash": "sha256-dY9qLD0H0zOUgU3vWacPY6Qc421BeQAfm8kBuBtPVE0=", + "lastModified": 1753489912, + "narHash": "sha256-uDCFHeXdRIgJpYmtcUxGEsZ+hYlLPBhR83fdU+vbC1s=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "13e8d35b7d6028b7198f8186bc0347c6abaa2701", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1761468971, + "narHash": "sha256-vY2OLVg5ZTobdroQKQQSipSIkHlxOTrIF1fsMzPh8w8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1c8ba8d3f7634acac4a2094eef7c32ad9106532c", + "rev": "78e34d1667d32d8a0ffc3eba4591ff256e80576e", "type": "github" }, "original": { @@ -36,8 +91,9 @@ }, "root": { "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "arinc653-wasm": "arinc653-wasm", + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs_2" } }, "systems": { @@ -54,6 +110,42 @@ "repo": "default", "type": "github" } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "arinc653-wasm", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1753439394, + "narHash": "sha256-Bv9h1AJegLI8uAhiJ1sZ4XAndYxhgf38tMgCQwiEpmc=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "2673921c03d6e75fdf4aa93e025772608d1482cf", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 61cbccd..d7a7e26 100644 --- a/flake.nix +++ b/flake.nix @@ -3,14 +3,16 @@ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05"; inputs.flake-utils.url = "github:numtide/flake-utils"; +# inputs.arinc653-wasm.url = "github:psiegl/arinc653-wasm/psiegl-old"; - outputs = { self, nixpkgs, flake-utils }: + outputs = { self, nixpkgs, flake-utils }: # arinc653-wasm flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" "powerpc64-linux"] (system: let # import the nixpkgs, passing the current system as arg pkgs = import nixpkgs { inherit system; }; +# arinc653Packages = arinc653-wasm.packages.${system} or {}; in { packages = rec { @@ -18,20 +20,28 @@ default = a653lib; # just call the package with the normal stdenv - a653lib = pkgs.callPackage pkgs/a653lib.nix { }; - + a653lib = pkgs.callPackage ./pkgs/a653lib.nix { }; +# a653lib-wasm = pkgs.callPackage ./pkgs/a653lib.nix { +# enableWasm = true; +# +# clang = pkgs.clang; +# wasiSdk = pkgs.wasi-sdk; +# wasmtime = pkgs.wasmtime; +# wamr = pkgs.wamr; +# cAbiLens = arinc653Packages.c-abi-lens; +# }; # override the stdenv to use an older gcc a653lib-gcc11 = let stdenv = pkgs.overrideCC pkgs.stdenv pkgs.gcc11; in - pkgs.callPackage pkgs/a653lib.nix { inherit stdenv; }; + pkgs.callPackage ./pkgs/a653lib.nix { inherit stdenv; }; # override the build to be with debug symbols (source still missing though) a653lib-debug = pkgs.enableDebugging a653lib; # cross compile for a pre-defined target platform - a653lib-aarch64 = pkgs.pkgsCross.aarch64-multiplatform-musl.pkgsStatic.callPackage pkgs/a653lib.nix { }; + a653lib-aarch64 = pkgs.pkgsCross.aarch64-multiplatform-musl.pkgsStatic.callPackage ./pkgs/a653lib.nix { }; # cross compile for a custom defined target platform a653lib-armv7a = @@ -42,7 +52,7 @@ crossSystem.config = "armv7l-unknown-linux-musleabi"; }; in - pkgsCross.callPackage pkgs/a653lib.nix { }; + pkgsCross.callPackage ./pkgs/a653lib.nix { }; # cross compile for a custom defined target platform a653lib-powerpc64 = @@ -53,7 +63,7 @@ crossSystem.config = "powerpc64-unknown-linux-gnuabielfv2"; }; in - pkgsCross.pkgsStatic.callPackage pkgs/a653lib.nix { }; + pkgsCross.pkgsStatic.callPackage ./pkgs/a653lib.nix { }; }; } ); diff --git a/partition_a.c b/partition_a.c index 8fd1ff4..ba9348f 100644 --- a/partition_a.c +++ b/partition_a.c @@ -12,12 +12,17 @@ #include "a653Lib.h" /* #include "a653_config.h" */ +#ifdef __wasm__ /* Do not expose non APEX functions into WebAssembly; in avionic ideally no stdio */ +#define DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__) +#else +#define DEBUG_PRINT(fmt, ...) printDebug(3, fmt, ##__VA_ARGS__) +#endif + /* a653_global_config_t global_config = A653_PARTITION_CONFIG_DEF; */ /* a653_process_config_t A653_PROCESS_CONFIG[] = A653_PROCESS_CONFIG_DEF; */ /* a653_sampling_port_config_t A653_SP_CONFIG[] = A653_SP_CONFIG_DEF; */ /* a653_queuing_port_config_t A653_QP_CONFIG[] = A653_QP_CONFIG_DEF; */ - void PeriodicProcess(void){ RETURN_CODE_TYPE return_code; MESSAGE_SIZE_TYPE length; @@ -73,7 +78,7 @@ void PeriodicProcess(void){ 0, //timeout &return_code); - printDebug(3,"%06d Prcs A send %s \n",index++,data_sp_tx); + DEBUG_PRINT("%06d Prcs A send %s \n",index++,data_sp_tx); READ_SAMPLING_MESSAGE(sp_id_rx, data_sp_rx, @@ -81,9 +86,9 @@ void PeriodicProcess(void){ &validity, &return_code); if (validity == VALID && length > 0){ - printDebug(3,"Prcs A: SP we got this : >%s<\n",(char *)data_sp_rx); + DEBUG_PRINT("Prcs A: SP we got this : >%s<\n",(char *)data_sp_rx); } else { - printDebug(3,"Prcs A: validity >%d< length >%d<\n",validity,length); + DEBUG_PRINT("Prcs A: validity >%d< length >%d<\n",validity,length); } RECEIVE_QUEUING_MESSAGE(qp_id_rx, @@ -92,13 +97,13 @@ void PeriodicProcess(void){ &length, /* received length */ &return_code); /* return code */ if(return_code == NO_ERROR && length !=0){ - printDebug(3,"Prcs A: QP we got this : >%s<\n",(char *)data_qp_rx); + DEBUG_PRINT("Prcs A: QP we got this : >%s<\n",(char *)data_qp_rx); } else { - printDebug(3,"Prcs A: return >%d<\n",return_code); + DEBUG_PRINT("Prcs A: return >%d<\n",return_code); } GET_TIME (&system_time, &return_code); - printDebug(3,"Prcs A: GET_TIME >%lld<\n",system_time); + DEBUG_PRINT("Prcs A: GET_TIME >%lld<\n",system_time); PERIODIC_WAIT(&return_code); } diff --git a/partition_b.c b/partition_b.c index 7a7b773..379a4ca 100644 --- a/partition_b.c +++ b/partition_b.c @@ -13,6 +13,12 @@ #include "a653Lib.h" /* #include "a653_config.h" */ +#ifdef __wasm__ /* Do not expose non APEX functions into WebAssembly; in avionic ideally no stdio */ +#define DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__) +#else +#define DEBUG_PRINT(fmt, ...) printDebug(3, fmt, ##__VA_ARGS__) +#endif + /* a653_global_config_t global_config = A653_PARTITION_CONFIG_DEF; */ /* a653_process_config_t A653_PROCESS_CONFIG[] = A653_PROCESS_CONFIG_DEF; */ /* a653_sampling_port_config_t A653_SP_CONFIG[] = A653_SP_CONFIG_DEF; */ @@ -76,7 +82,7 @@ void PeriodicProcess(void){ if (validity == VALID && length > 0){ - printDebug(3,"Prcs B: SP we got this : >%s< validity >%d< length >%d<\n",(char *)data_sp_rx,validity,length); + DEBUG_PRINT("Prcs B: SP we got this : >%s< validity >%d< length >%d<\n",(char *)data_sp_rx,validity,length); WRITE_SAMPLING_MESSAGE(sp_id_tx, /* sampling port id */ data_sp_tx, /* pointer to data */ @@ -92,7 +98,7 @@ void PeriodicProcess(void){ &return_code); /* return code */ if(return_code == NO_ERROR && length !=0){ - printDebug(3,"Prcs B: QP we got this : >%s<\n",(char *)data_qp_rx); + DEBUG_PRINT("Prcs B: QP we got this : >%s<\n",(char *)data_qp_rx); SEND_QUEUING_MESSAGE(qp_id_tx, data_qp_tx, @@ -112,7 +118,7 @@ void PeriodicProcess_2(void){ RETURN_CODE_TYPE return_code; while (1){ - printDebug(3,"Prcs C: activated\n"); + DEBUG_PRINT("Prcs C: activated\n"); SIGNAL_SEMAPHORE(semaphore_id, &return_code); PERIODIC_WAIT(&return_code); @@ -126,7 +132,7 @@ void APeriodicProcess(void){ WAIT_SEMAPHORE(semaphore_id, 0, &return_code); - printDebug(3,"Prcs D: activated\n"); + DEBUG_PRINT("Prcs D: activated\n"); TIMED_WAIT(1000000,&return_code); } } @@ -200,7 +206,7 @@ int main (int argc, char *argv[]){ &semaphore_status, &return_code); - printDebug(3,"semaphore: %d : %d\n", + DEBUG_PRINT("semaphore: %d : %d\n", semaphore_status.CURRENT_VALUE, semaphore_status.MAXIMUM_VALUE); diff --git a/pkgs/a653lib.nix b/pkgs/a653lib.nix index d4241e9..e121258 100644 --- a/pkgs/a653lib.nix +++ b/pkgs/a653lib.nix @@ -1,9 +1,24 @@ { + lib, stdenv, cmake, fetchurl, + gnumake, + pkg-config, + clang ? null, + wasiSdk ? null, + wasmtime ? null, + wamr ? null, + cAbiLens ? null, + enableWasm ? false }: +assert !enableWasm || clang != null; +assert !enableWasm || wasiSdk != null; +assert !enableWasm || wasmtime != null; +assert !enableWasm || wamr != null; +assert !enableWasm || cAbiLens != null; + let arinc653Zip = fetchurl { url = "https://brx-content.fullsight.org/site/binaries/content/assets/itc/content/support-files/arinc653.h.zip"; @@ -15,18 +30,30 @@ let }; in stdenv.mkDerivation { - pname = "a653lib"; + pname = if enableWasm then "a653lib-wasm" else "a653lib"; version = "unstable-2025-11-26"; src = ./..; - nativeBuildInputs = [ cmake ]; + nativeBuildInputs = + [ cmake gnumake pkg-config ] + ++ lib.optionals enableWasm [ clang ]; + + buildInputs = + lib.optionals enableWasm [ wasmtime wamr ]; - cmakeFlags = [ - "-DARINC653_ZIP=${arinc653Zip}" - ]; + cmakeFlags = + [ + "-DARINC653_ZIP=${arinc653Zip}" + ] + ++ lib.optionals enableWasm [ + "-DA653LIB_BUILD_WASM=ON" + "-DA653LIB_FETCH_C_ABI_LENS=OFF" + "-DWASM_CLANG=${lib.getExe clang}" + "-DWASI_SYSROOT=${wasiSdk}/share/wasi-sysroot" + "-DC_ABI_LENS_EXECUTABLE=${lib.getExe cAbiLens}" + ]; dontStrip = true; - # TODO investigate why hardening causes crashes hardeningDisable = [ "all" ]; } diff --git a/scripts/process-arinc-header.awk b/scripts/process-arinc-header.awk index f796313..2baa74a 100755 --- a/scripts/process-arinc-header.awk +++ b/scripts/process-arinc-header.awk @@ -21,9 +21,9 @@ BEGIN { } # mark all functions to be importend from the arinc module -#"extern" == $1 && "void" == $2 && $4 ~/^\(/ { -# print "WASM_IMPORT_MODULE(\"arinc653\")" -#} +"extern" == $1 && "void" == $2 && $4 ~/^\(/ { + print "WASM_IMPORT_MODULE(\"arinc653\")" +} # make all implementation dependent defines ifndef based diff --git a/scripts/split-arinc-header.awk b/scripts/split-arinc-header.awk index 2ce2560..c0f3d1e 100755 --- a/scripts/split-arinc-header.awk +++ b/scripts/split-arinc-header.awk @@ -1,4 +1,4 @@ -#!/usr/bin/env -S awk -f +#!/usr/bin/env -S gawk -f # not the nicest, should be rather on the comment .. From c187d36a503aa6ed5880ca2ad5fa1d135963911e Mon Sep 17 00:00:00 2001 From: Patrick Siegl <3261314+psiegl@users.noreply.github.com> Date: Sun, 31 May 2026 22:12:27 +0200 Subject: [PATCH 2/4] cleanup --- CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 00c3c31..9c0ca08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -503,7 +503,6 @@ rm -f "$tmp" foreach(partition IN LISTS A653_WASM_GUESTS) set(src "${CMAKE_CURRENT_SOURCE_DIR}/${partition}.c") set(out "${CMAKE_CURRENT_BINARY_DIR}/${partition}.wasm") - set(layout "${CMAKE_CURRENT_BINARY_DIR}/${partition}.wasm32_struct_layout.txt") add_custom_command( OUTPUT "${out}" "${layout}" @@ -516,8 +515,6 @@ rm -f "$tmp" --sysroot=${WASI_SYSROOT} -o "${out}" "${src}" - COMMAND - "${CMAKE_COMMAND}" -E touch "${layout}" DEPENDS wasm_headers "${src}" From 13c32cee129deca906ad430440e7e47deef76185 Mon Sep 17 00:00:00 2001 From: Patrick Siegl <3261314+psiegl@users.noreply.github.com> Date: Mon, 1 Jun 2026 23:34:54 +0200 Subject: [PATCH 3/4] Using latest DLR-FT/arinc653-wasm -> c-abi-lens with some patches --- CMakeLists.txt | 29 ++++++------------- a653_inc/a653Lib.h | 28 +++++++++--------- .../arinc653_part1_apex_process_wasm32.c | 4 +-- 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c0ca08..6607255 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -362,7 +362,7 @@ if(A653LIB_BUILD_WASM) OUTPUT "${C_ABI_LENS_SRC_DIR}/pkgs/c-abi-lens/Cargo.toml" COMMAND "${GIT_EXECUTABLE}" clone "https://github.com/psiegl/arinc653-wasm.git" - --branch psiegl-old + --branch psiegl-patch-1 "${C_ABI_LENS_SRC_DIR}" VERBATIM COMMENT "Cloning arinc653-wasm repository" @@ -389,32 +389,21 @@ if(A653LIB_BUILD_WASM) endif() endif() - set(GEN_CAMW32_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/gen_camw32_getset.sh") - file(WRITE "${GEN_CAMW32_SCRIPT}" [=[ -#!/bin/sh -set -eu -tool="$1" -header="$2" -out="$3" -tmp="${out}.tmp" -"$tool" "$header" -- --target=wasm32-wasip1 > "$tmp" -sed 's|camw|camw32|g' "$tmp" > "$out" -rm -f "$tmp" -]=]) - execute_process(COMMAND chmod +x "${GEN_CAMW32_SCRIPT}") - add_custom_command( OUTPUT "${CAMW32_GETSET_HEADER}" - COMMAND "${GEN_CAMW32_SCRIPT}" - "${C_ABI_LENS_BIN}" - "${A653_WASM_INCLUDE_DIR}/a653Lib.h" - "${CAMW32_GETSET_HEADER}" + COMMAND + "${C_ABI_LENS_BIN}" + "${A653_WASM_INCLUDE_DIR}/a653Lib.h" + --prefix camw32 + --function-decl-prefix "static inline __attribute__((always_inline))" + -c -o "${CAMW32_GETSET_HEADER}" + -- --target=wasm32-wasip1 DEPENDS wasm_headers c_abi_lens_tool "${A653_WASM_INCLUDE_DIR}/a653Lib.h" + COMMENT "Generating camw32 getters/setters from ${header}" VERBATIM - COMMENT "Generating camw32_getset.h using c-abi-lens" ) add_custom_target(camw32_getset DEPENDS "${CAMW32_GETSET_HEADER}") diff --git a/a653_inc/a653Lib.h b/a653_inc/a653Lib.h index 7c935f1..1a5df1e 100644 --- a/a653_inc/a653Lib.h +++ b/a653_inc/a653Lib.h @@ -31,22 +31,22 @@ #define __A653_LIB_H /* a653 includes */ -#include -#include /* not visible in repo, autogenerated */ -// #include -#include /* autogenerated */ -#include -#include /* autogenerated */ -#include -#include -#include -#include -#include -#include -#include /* autogenerated */ +#include "a653Type.h" +#include "a653Blackboard.h" /* not visible in repo, autogenerated */ +// #include "a653MemoryBlock.h" +#include "a653Buffer.h" /* autogenerated */ +#include "a653Error.h" +#include "a653Event.h" /* autogenerated */ +#include "a653Partition.h" +#include "a653Process.h" +#include "a653Queuing.h" +#include "a653Sampling.h" +#include "a653Semaphore.h" +#include "a653Time.h" +#include "a653Mutex.h" /* autogenerated */ #ifndef __wasm__ /* Do not expose non APEX functions into WebAssembly */ -#include +#include "a653Init.h" #endif /* #ifndef __wasm__ */ /* defines */ diff --git a/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.c b/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.c index 70aece9..717afda 100644 --- a/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.c +++ b/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.c @@ -82,7 +82,7 @@ WASM32_HOST_FUNCTION(GET_PROCESS_STATUS, wasm_baseaddr, camw32_set__PROCESS_ATTRIBUTE_TYPE__STACK_SIZE(ATTRIBUTES_guest, PROCESS_STATUS.ATTRIBUTES.STACK_SIZE); camw32_set__PROCESS_ATTRIBUTE_TYPE__BASE_PRIORITY(ATTRIBUTES_guest, PROCESS_STATUS.ATTRIBUTES.BASE_PRIORITY); camw32_set__PROCESS_ATTRIBUTE_TYPE__DEADLINE(ATTRIBUTES_guest, PROCESS_STATUS.ATTRIBUTES.DEADLINE); - camw32_write__PROCESS_ATTRIBUTE_TYPE__NAME(ATTRIBUTES_guest, (uint8_t*)PROCESS_STATUS.ATTRIBUTES.NAME); + camw32_write__PROCESS_ATTRIBUTE_TYPE__NAME(ATTRIBUTES_guest, (int8_t*)PROCESS_STATUS.ATTRIBUTES.NAME); }) @@ -100,7 +100,7 @@ WASM32_HOST_FUNCTION(CREATE_PROCESS, wasm_baseaddr, ATTRIBUTES.STACK_SIZE = camw32_get__PROCESS_ATTRIBUTE_TYPE__STACK_SIZE(ATTRIBUTES__guest); ATTRIBUTES.BASE_PRIORITY = camw32_get__PROCESS_ATTRIBUTE_TYPE__BASE_PRIORITY(ATTRIBUTES__guest); ATTRIBUTES.DEADLINE = camw32_get__PROCESS_ATTRIBUTE_TYPE__DEADLINE(ATTRIBUTES__guest); - camw32_read__PROCESS_ATTRIBUTE_TYPE__NAME(ATTRIBUTES__guest, (uint8_t*)ATTRIBUTES.NAME); + camw32_read__PROCESS_ATTRIBUTE_TYPE__NAME(ATTRIBUTES__guest, (int8_t*)ATTRIBUTES.NAME); PROCESS_ID_TYPE PROCESS_ID; RETURN_CODE_TYPE RETURN_CODE; From d62d570daf7fefacd7b470f0ca7ab63c8dac00e5 Mon Sep 17 00:00:00 2001 From: Patrick Siegl <3261314+psiegl@users.noreply.github.com> Date: Mon, 1 Jun 2026 23:52:11 +0200 Subject: [PATCH 4/4] Updated README --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 85b6193..0504313 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,10 @@ Refer to [LICENCE](./LICENSE.md) file. ## Operating system and compilers -The liba653 LIBRARY can be built for the following operating systems and compilers: +The liba653 LIBRARY can be built for the following operating systems: +Linux 32/64 bits (RHEL7, ArchLinux, Ubuntu, NixOS) -- Linux 32 bits (RHEL7) -- Linux 64 bits (RHEL7) +In case of the WAMR / Wasmtime variant, clang is the compiler of choice. ## Dependencies @@ -94,4 +94,7 @@ pid: 578773 <1702486050.349254883>: > taskset --cpu-list 1 ./partition_b & : ## Links -[Required Services](https://www.aviation-ia.com/support-files/arinc653h) +## Dependencies + +- [SAE ARINC653 Header](https://www.aviation-ia.com/support-files/arinc653h) +- WAMR/Wasmtime variant: [DLR-FT/arinc653-wasm -> c-abi-lens](https://github.com/DLR-FT/arinc653-wasm)