diff --git a/.github/workflows/nix.yaml b/.github/workflows/nix.yaml index b2fe9ad..969c80a 100644 --- a/.github/workflows/nix.yaml +++ b/.github/workflows/nix.yaml @@ -18,6 +18,17 @@ jobs: - uses: DeterminateSystems/magic-nix-cache-action@main - name: Build run: nix build .#packages.x86_64-linux.a653lib --print-build-logs + x86_64-linux---a653-wasmtime: + name: x86_64-linux.a653-wasmtime + runs-on: + - ubuntu-latest + needs: [] + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - name: Build + run: nix build .#packages.x86_64-linux.a653-wasmtime --print-build-logs x86_64-linux---a653lib-aarch64: name: x86_64-linux.a653lib-aarch64 runs-on: diff --git a/Makefile b/Makefile index cc9b70e..e3bcca3 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ #export COMMON_SWITCH = -D__LITTLE_ENDIAN -m32 -rdynamic export COMMON_SWITCH = -D__LITTLE_ENDIAN -rdynamic +HOME ?= $(shell pwd) # CC_PATH=/home/tools/gnat/bin/ CC_PATH= @@ -38,16 +39,21 @@ export CC OBJS = main.o OBJS_A = partition_a.o init.o OBJS_B = partition_b.o init.o +OBJS_WASM_BOOTSTRAP = MY_BUILD_DIR = $(BUILD_DIR) TARGET = $(BIN_DIR)/a653_main TARGET_A = $(BIN_DIR)/partition_a +TARGET_A_WASM = $(BIN_DIR)/partition_a.wasm TARGET_B = $(BIN_DIR)/partition_b +TARGET_B_WASM = $(BIN_DIR)/partition_b.wasm +TARGET_WASMTIME_CLI = $(BIN_DIR)/p_wasmtime +TARGET_WAMR_CLI = $(BIN_DIR)/p_wamr -all: clean mk_build_dir alib amain part_a part_b +all: mk_build_dir alib amain part_a part_b @echo done! @@ -64,12 +70,61 @@ part_b: $(OBJS_B) cd $(MY_BUILD_DIR); $(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET_B) $(OBJS_B) ./liba653.a $(LDLIBS) -alib: - make -e -C $(SRC_DIR)/a653_lib +# $ yay -S clang lld wasi-libc wasi-compiler-rt # guest compilation +# $ yay -S libwasmtime iwasm # host libraries +all_wasm: mk_build_dir alib amain_wasm part_wasmtime part_wamr $(TARGET_A_WASM) $(TARGET_B_WASM) + # set a default runtime, change link to p_wamr if wamr desired + cd $(BIN_DIR); ln -s p_wasmtime wasm32_rt + +amain_wasm: CFLAGS += -D__WASM_RT__ +amain_wasm: $(OBJS) + @echo build dir $(MY_BUILD_DIR) + cd $(MY_BUILD_DIR); $(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET)_wasm $(OBJS) ./liba653.a $(LDLIBS) + +part_wasmtime: mk_build_dir alib amain_wasm + make -e -C $(SRC_DIR)/a653_lib_wasm32 $(TARGET_WASMTIME_CLI) + +part_wamr: mk_build_dir alib amain_wasm + make -e -C $(SRC_DIR)/a653_lib_wasm32 $(TARGET_WAMR_CLI) + +part_wasm_guest: $(TARGET_A_WASM) $(TARGET_B_WASM) + +WASI_SYSROOT ?= /usr/share/wasi-sysroot + +%.wasm: alib + @echo build dir $(MY_BUILD_DIR) + # 1. we use the wasm32-wasi to include the stdlib (thus having __start() and main() support). + # however, long term for avionics it would make sense to drop and go to wasm32-unknown with likely -Wl,-export=_start or similar + # 2. --allow-undefined is required for symbols (such as WIT functions) that are not yet defined. + cd $(MY_BUILD_DIR); clang -I$(MY_BUILD_DIR)/a653_inc --target=wasm32-wasi -Wl,--export-table -Wl,--allow-undefined --sysroot=$(WASI_SYSROOT) -o $@ $(SRC_DIR)/$(basename $(notdir $@)).c 1> $(basename $(notdir $@)).wasm32_struct_layout.txt # ../../wasm_guest_trampoline.c + +alib: $(TMP_DIR)/download/a653Blackboard.h $(TMP_DIR)/download/a653Buffer.h $(TMP_DIR)/download/a653Event.h $(TMP_DIR)/download/a653Mutex.h cp -r $(SRC_DIR)/a653_inc $(MY_BUILD_DIR) + cp $^ $(MY_BUILD_DIR)/a653_inc # cp -r $(SRC_DIR)/a653_ada $(MY_BUILD_DIR) + # relies on the above headers + make -e -C $(SRC_DIR)/a653_lib + + +# rule to download the ARINC headerfiles +$(TMP_DIR)/download/arinc653.h.zip: + @mkdir -p -- $(@D) + test -f $@ || curl --user-agent 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0' \ + --location --output-dir $(TMP_DIR)/download --remote-name-all \ + https://brx-content.fullsight.org/site/binaries/content/assets/itc/content/support-files/arinc653.h.zip + +# rule to extract the ARINC headerfiles +$(TMP_DIR)/download/ARINC653.h: $(TMP_DIR)/download/arinc653.h.zip + @mkdir -p -- $(@D) + test -f $@ || echo $^ | xargs --max-args=1 bsdtar -x --cd $(TMP_DIR)/download --modification-time --file +# rule to generate our Wasm header file, by making every open type a 32 Bit integer +$(TMP_DIR)/download/ARINC653_patched.h: $(TMP_DIR)/download/ARINC653.h + @mkdir -p -- $(@D) + awk -f $(SRC_DIR)/scripts/process-arinc-header.awk $< > $@ +$(TMP_DIR)/download/a653Blackboard.h $(TMP_DIR)/download/a653Buffer.h $(TMP_DIR)/download/a653Event.h $(TMP_DIR)/download/a653Mutex.h &: $(TMP_DIR)/download/ARINC653_patched.h + cd $(TMP_DIR)/download; awk -f $(SRC_DIR)/scripts/split-arinc-header.awk $< gcc_version: diff --git a/README.md b/README.md index f8cdafd..153f8b2 100644 --- a/README.md +++ b/README.md @@ -88,3 +88,7 @@ pid: 578773 <1702486050.349254883>: > taskset --cpu-list 1 ./partition_b & : ## Tests debugging ## Build with Make + +## Links + +[Required Services](https://www.aviation-ia.com/support-files/arinc653h) diff --git a/a653_config.h b/a653_config.h index 2e35050..69cdfae 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 f9aa477..8107a69 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 ARINC653 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 7ed8541..ebac819 100644 --- a/a653_inc/a653Lib.h +++ b/a653_inc/a653Lib.h @@ -32,19 +32,22 @@ /* a653 includes */ #include - //#include +#include //#include - //#include +#include #include - //#include +#include #include #include #include #include #include #include +#include +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ #include +#endif /* #ifndef __wasm__ */ /* defines */ @@ -52,8 +55,10 @@ /* function declarations */ +#ifndef __wasm__ /* Do not expose non ARINC653 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 990cca5..37ca3f5 100644 --- a/a653_inc/a653Partition.h +++ b/a653_inc/a653Partition.h @@ -62,10 +62,12 @@ typedef 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 ffa6d6a..4c471fb 100644 --- a/a653_inc/a653Process.h +++ b/a653_inc/a653Process.h @@ -37,7 +37,6 @@ typedef NAME_TYPE PROCESS_NAME_TYPE; /* process name type */ typedef A653_INTEGER PROCESS_INDEX_TYPE; -typedef A653_INTEGER PRIORITY_TYPE; /* priority type */ /* process state type */ typedef @@ -75,79 +74,97 @@ typedef /* 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 ARINC653 functions into WebAssembly */ int a653_prcs_init(void); int a653_sync_prcs(void); @@ -160,5 +177,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 377f006..af2d016 100644 --- a/a653_inc/a653Queuing.h +++ b/a653_inc/a653Queuing.h @@ -49,6 +49,8 @@ typedef 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 ARINC653 functions into WebAssembly */ /*-----------------------------------------------*/ /* queuing port access function pointer types */ /*-----------------------------------------------*/ @@ -78,7 +80,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, @@ -88,6 +92,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 */ @@ -95,6 +100,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, @@ -104,21 +110,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 ARINC653 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, @@ -138,5 +148,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 8889e95..8819b88 100644 --- a/a653_inc/a653Sampling.h +++ b/a653_inc/a653Sampling.h @@ -75,6 +75,8 @@ typedef UPDATED_TYPE UPDATED; /* empty, consumed, or new message */ } SAMPLING_PORT_CURRENT_STATUS_TYPE; +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ + /*-----------------------------------------------*/ /* sampling port access function pointer types */ /*-----------------------------------------------*/ @@ -108,7 +110,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, @@ -117,12 +121,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, @@ -132,16 +138,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, @@ -152,12 +161,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, @@ -170,6 +181,7 @@ extern void READ_SAMPLING_MESSAGE_CONDITIONAL ( /*out*/ RETURN_CODE_TYPE *RETURN_CODE ); +#ifndef __wasm__ /* Do not expose non ARINC653 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, @@ -187,5 +199,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 a770472..1436abe 100644 --- a/a653_inc/a653Semaphore.h +++ b/a653_inc/a653Semaphore.h @@ -49,6 +49,7 @@ typedef 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, @@ -57,20 +58,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 d5db4a1..07bf8e6 100644 --- a/a653_inc/a653Time.h +++ b/a653_inc/a653Time.h @@ -36,19 +36,25 @@ /* function declarations */ +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ extern void initTime(void); +#endif /* #ifndef __wasm__ */ +WASM_IMPORT_MODULE("arinc653") extern void TIMED_WAIT ( /*in */ SYSTEM_TIME_TYPE DELAY_TIME, /*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 bc5019d..48c061d 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 */ @@ -98,5 +105,6 @@ typedef A653_BYTE * MEMORY_BLOCK_ADDR_TYPE; typedef A653_INTEGER MEMORY_BLOCK_SIZE_TYPE; typedef NAME_TYPE MEMORY_BLOCK_NAME_TYPE; +typedef A653_INTEGER PRIORITY_TYPE; /* priority type */ #endif /* __A653_TYPES_H */ diff --git a/a653_lib/Makefile b/a653_lib/Makefile index 44534eb..0bc0b44 100644 --- a/a653_lib/Makefile +++ b/a653_lib/Makefile @@ -6,10 +6,10 @@ CC = gcc AR = ar -CFLAGS = -Wall -Wno-unused-function -g2 -O0 -fPIC -c -I../a653_inc $(COMMON_SWITCH) +CFLAGS = -Wall -Wno-unused-function -g2 -O0 -fPIC -c -I$(BUILD_DIR)/a653_inc $(COMMON_SWITCH) LDFLAGS = -g2 #-L /tools/gcc-810-ppc/lib -OBJS = a653_i_semaphore.o a653_i_partition.o a653_i_process.o a653_i_sampling.o a653_i_queuing.o a653_i_time.o a653Init.o a653_i_shm_if.o a653_i_sync.o a653_i_time_lib.o a653_i_error.o +OBJS = a653_i_semaphore.o a653_i_partition.o a653_i_process.o a653_i_sampling.o a653_i_queuing.o a653_i_time.o a653Init.o a653_i_shm_if.o a653_i_sync.o a653_i_time_lib.o a653_i_error.o a653_i_buffer.o a653_i_blackboard.o a653_i_mutex.o a653_i_event.o MY_BUILD_DIR = $(BUILD_DIR)/a653_lib TARGET = $(BUILD_DIR)/liba653.a diff --git a/a653_lib/a653_i_blackboard.c b/a653_lib/a653_i_blackboard.c new file mode 100644 index 0000000..2f419bc --- /dev/null +++ b/a653_lib/a653_i_blackboard.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2022-2023 Airbus Defence and Space + * + * This file is part of liba653. + * + * liba653 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * liba653 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with liba653; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file a653_i_blackboard.c + * @copyright Airbus Defence and Space + * @author patrick.siegl@airbus.com + * @date Mon Nov 3 21:28:21 CET 2025 + * @brief a653 blackboard + * @details + */ + +/* includes */ + +#include "a653Lib.h" +#include "a653Blackboard.h" + +void CREATE_BLACKBOARD ( + /*in */ BLACKBOARD_NAME_TYPE BLACKBOARD_NAME, + /*in */ MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE, + /*out*/ BLACKBOARD_ID_TYPE *BLACKBOARD_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void DISPLAY_BLACKBOARD ( + /*in */ BLACKBOARD_ID_TYPE BLACKBOARD_ID, + /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, /* by reference */ + /*in */ MESSAGE_SIZE_TYPE LENGTH, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void READ_BLACKBOARD ( + /*in */ BLACKBOARD_ID_TYPE BLACKBOARD_ID, + /*in */ SYSTEM_TIME_TYPE TIME_OUT, + /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, + /* The message address is passed IN, although */ + /* the respective message is passed OUT */ + /*out*/ MESSAGE_SIZE_TYPE *LENGTH, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void CLEAR_BLACKBOARD ( + /*in */ BLACKBOARD_ID_TYPE BLACKBOARD_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void GET_BLACKBOARD_ID ( + /*in */ BLACKBOARD_NAME_TYPE BLACKBOARD_NAME, + /*out*/ BLACKBOARD_ID_TYPE *BLACKBOARD_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void GET_BLACKBOARD_STATUS ( + /*in */ BLACKBOARD_ID_TYPE BLACKBOARD_ID, + /*out*/ BLACKBOARD_STATUS_TYPE *BLACKBOARD_STATUS, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} diff --git a/a653_lib/a653_i_buffer.c b/a653_lib/a653_i_buffer.c new file mode 100644 index 0000000..f8fe33e --- /dev/null +++ b/a653_lib/a653_i_buffer.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022-2023 Airbus Defence and Space + * + * This file is part of liba653. + * + * liba653 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * liba653 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with liba653; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file a653_i_buffer.c + * @copyright Airbus Defence and Space + * @author patrick.siegl@airbus.com + * @date Mon Nov 3 21:28:21 CET 2025 + * @brief a653 buffer + * @details + */ + +/* includes */ + +#include "a653Lib.h" +#include "a653Buffer.h" + +void CREATE_BUFFER ( + /*in */ BUFFER_NAME_TYPE BUFFER_NAME, + /*in */ MESSAGE_SIZE_TYPE MAX_MESSAGE_SIZE, + /*in */ MESSAGE_RANGE_TYPE MAX_NB_MESSAGE, + /*in */ QUEUING_DISCIPLINE_TYPE QUEUING_DISCIPLINE, + /*out*/ BUFFER_ID_TYPE *BUFFER_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void SEND_BUFFER ( + /*in */ BUFFER_ID_TYPE BUFFER_ID, + /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, /* by reference */ + /*in */ MESSAGE_SIZE_TYPE LENGTH, + /*in */ SYSTEM_TIME_TYPE TIME_OUT, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void RECEIVE_BUFFER ( + /*in */ BUFFER_ID_TYPE BUFFER_ID, + /*in */ SYSTEM_TIME_TYPE TIME_OUT, + /*in */ MESSAGE_ADDR_TYPE MESSAGE_ADDR, + /* The message address is passed IN, although */ + /* the respective message is passed OUT */ + /*out*/ MESSAGE_SIZE_TYPE *LENGTH, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void GET_BUFFER_ID ( + /*in */ BUFFER_NAME_TYPE BUFFER_NAME, + /*out*/ BUFFER_ID_TYPE *BUFFER_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void GET_BUFFER_STATUS ( + /*in */ BUFFER_ID_TYPE BUFFER_ID, + /*out*/ BUFFER_STATUS_TYPE *BUFFER_STATUS, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} diff --git a/a653_lib/a653_i_event.c b/a653_lib/a653_i_event.c new file mode 100644 index 0000000..e8960f2 --- /dev/null +++ b/a653_lib/a653_i_event.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022-2023 Airbus Defence and Space + * + * This file is part of liba653. + * + * liba653 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * liba653 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with liba653; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file a653_i_event.c + * @copyright Airbus Defence and Space + * @author patrick.siegl@airbus.com + * @date Mon Nov 3 21:28:21 CET 2025 + * @brief a653 event + * @details + */ + +/* includes */ + +#include "a653Lib.h" +#include "a653Event.h" + +void CREATE_EVENT ( + /*in */ EVENT_NAME_TYPE EVENT_NAME, + /*out*/ EVENT_ID_TYPE *EVENT_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void SET_EVENT ( + /*in */ EVENT_ID_TYPE EVENT_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void RESET_EVENT ( + /*in */ EVENT_ID_TYPE EVENT_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void WAIT_EVENT ( + /*in */ EVENT_ID_TYPE EVENT_ID, + /*in */ SYSTEM_TIME_TYPE TIME_OUT, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void GET_EVENT_ID ( + /*in */ EVENT_NAME_TYPE EVENT_NAME, + /*out*/ EVENT_ID_TYPE *EVENT_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void GET_EVENT_STATUS ( + /*in */ EVENT_ID_TYPE EVENT_ID, + /*out*/ EVENT_STATUS_TYPE *EVENT_STATUS, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} diff --git a/a653_lib/a653_i_mutex.c b/a653_lib/a653_i_mutex.c new file mode 100644 index 0000000..dc5ec54 --- /dev/null +++ b/a653_lib/a653_i_mutex.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2022-2023 Airbus Defence and Space + * + * This file is part of liba653. + * + * liba653 is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * liba653 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with liba653; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file a653_i_mutex.c + * @copyright Airbus Defence and Space + * @author patrick.siegl@airbus.com + * @date Mon Nov 3 21:28:21 CET 2025 + * @brief a653 mutex + * @details + */ + +/* includes */ + +#include "a653Lib.h" +#include "a653Mutex.h" + +void CREATE_MUTEX ( + /*in */ MUTEX_NAME_TYPE MUTEX_NAME, + /*in */ PRIORITY_TYPE MUTEX_PRIORITY, + /*in */ QUEUING_DISCIPLINE_TYPE QUEUING_DISCIPLINE, + /*out*/ MUTEX_ID_TYPE *MUTEX_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void ACQUIRE_MUTEX ( + /*in */ MUTEX_ID_TYPE MUTEX_ID, + /*in */ SYSTEM_TIME_TYPE TIME_OUT, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void RELEASE_MUTEX ( + /*in */ MUTEX_ID_TYPE MUTEX_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void RESET_MUTEX ( + /*in */ MUTEX_ID_TYPE MUTEX_ID, + /*in */ PROCESS_ID_TYPE PROCESS_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void GET_MUTEX_ID ( + /*in */ MUTEX_NAME_TYPE MUTEX_NAME, + /*out*/ MUTEX_ID_TYPE *MUTEX_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void GET_MUTEX_STATUS ( + /*in */ MUTEX_ID_TYPE MUTEX_ID, + /*out*/ MUTEX_STATUS_TYPE *MUTEX_STATUS, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} + +void GET_PROCESS_MUTEX_STATE ( + /*in */ PROCESS_ID_TYPE PROCESS_ID, + /*out*/ MUTEX_ID_TYPE *MUTEX_ID, + /*out*/ RETURN_CODE_TYPE *RETURN_CODE ) { + *RETURN_CODE = NO_ACTION; +} diff --git a/a653_lib/a653_i_process.c b/a653_lib/a653_i_process.c index b006752..8796b47 100644 --- a/a653_lib/a653_i_process.c +++ b/a653_lib/a653_i_process.c @@ -38,6 +38,7 @@ #define A653_QUEUING_INTERN #include "a653Init.h" +#include "a653Time.h" #include "a653Type.h" #include "a653Error.h" #include "a653Process.h" @@ -60,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_process.h b/a653_lib/a653_i_process.h index b878cef..673a0fd 100644 --- a/a653_lib/a653_i_process.h +++ b/a653_lib/a653_i_process.h @@ -34,13 +34,6 @@ #include #include -#include "a653Type.h" -#include "a653Error.h" -#include "a653Process.h" -#include "a653Partition.h" -#include "a653Time.h" - - typedef void *(*__start_routine) (void *); typedef void (*func_ptr)(void); diff --git a/a653_lib_wasm32/Makefile b/a653_lib_wasm32/Makefile new file mode 100644 index 0000000..c1ffd3a --- /dev/null +++ b/a653_lib_wasm32/Makefile @@ -0,0 +1,65 @@ +# +# Makfile for liba653_wasm32.a +# + +include ../a653_lib/Makefile + +CFLAGS += -I$(SRC_DIR)/a653_lib -I$(MY_BUILD_DIR) + +OBJS_REL = ../init.o \ + generic_helper.o + +# these *.c files require -D__WAMR__ or -D__WASMTIME__ +OBJS_WASM32_RT_SPECIFIC = \ + apex_host_fncs_wasm32.o \ + arinc653_part1_apex_time_wasm32.o \ + arinc653_part1_apex_process_wasm32.o \ + arinc653_part1_apex_partition_wasm32.o \ + arinc653_part1_apex_sampling_port_wasm32.o \ + arinc653_part2_apex_sampling_port_extension_wasm32.o \ + arinc653_part1_apex_queuing_port_wasm32.o \ + arinc653_part1_apex_semaphore_wasm32.o \ + arinc653_part1_apex_error_wasm32.o \ + arinc653_part1_apex_buffer_wasm32.o \ + arinc653_part1_apex_event_wasm32.o \ + arinc653_part1_apex_blackboard_wasm32.o \ + arinc653_part1_apex_mutex_wasm32.o \ + wasm32_main.o + +$(TMP_DIR)/arinc653-wasm/pkgs/c-abi-lens: + test -d $@ || { cd $(TMP_DIR) && git clone https://github.com/psiegl/arinc653-wasm.git --branch psiegl-old; } + +$(TMP_DIR)/arinc653-wasm/pkgs/c-abi-lens/target/debug/c-abi-lens: $(TMP_DIR)/arinc653-wasm/pkgs/c-abi-lens + test -f $@ || { cd $(TMP_DIR)/arinc653-wasm/pkgs/c-abi-lens && rustup default stable && cargo build; } + +$(MY_BUILD_DIR)/camw32_getset.h: $(TMP_DIR)/arinc653-wasm/pkgs/c-abi-lens/target/debug/c-abi-lens + # not ideal, but currently without --sysroot=/usr/share/wasi-sysroot (should be the same as during wasm compilation) + $(TMP_DIR)/arinc653-wasm/pkgs/c-abi-lens/target/debug/c-abi-lens $(BUILD_DIR)/a653_inc/a653Lib.h -- --target=wasm32-wasi > $@ + sed -i 's|camw|camw32|g' $@ + + +WAMR_OBJS_WASM32 = $(patsubst %, $(MY_BUILD_DIR)/wamr/%, $(notdir $(OBJS_WASM32_RT_SPECIFIC)) a653_wamr.o) +$(WAMR_OBJS_WASM32): | $(MY_BUILD_DIR)/wamr/ $(MY_BUILD_DIR)/camw32_getset.h + +$(MY_BUILD_DIR)/wamr/: + mkdir -p $@ + +$(MY_BUILD_DIR)/wamr/%.o: %.c + $(CC) -c $(CFLAGS) -D__WAMR__ $(CINCL) $< -o $@ + +# Do not use ASAN (-fsanitize=address) ... https://github.com/bytecodealliance/wasm-micro-runtime/issues/4638 +%/p_wamr: $(OBJS_REL) $(WAMR_OBJS_WASM32) + cd $(MY_BUILD_DIR); $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) -liwasm -lm /usr/lib/libiwasm.a $(TMP_DIR)/a653_build/liba653.a + + +WASMTIME_OBJS_WASM32 = $(patsubst %, $(MY_BUILD_DIR)/wasmtime/%, $(notdir $(OBJS_WASM32_RT_SPECIFIC)) a653_wasmtime.o) +$(WASMTIME_OBJS_WASM32): | $(MY_BUILD_DIR)/wasmtime/ $(MY_BUILD_DIR)/camw32_getset.h + +$(MY_BUILD_DIR)/wasmtime/: + mkdir -p $@ + +$(MY_BUILD_DIR)/wasmtime/%.o: %.c + $(CC) -c $(CFLAGS) -D__WASMTIME__ $(CINCL) $< -o $@ + +%/p_wasmtime: $(OBJS_REL) $(WASMTIME_OBJS_WASM32) + cd $(MY_BUILD_DIR); $(CC) $(LDFLAGS) -fsanitize=address -lwasmtime -o $@ $^ $(LDLIBS) $(TMP_DIR)/a653_build/liba653.a 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..92118b8 --- /dev/null +++ b/a653_lib_wasm32/a653_wasmtime.c @@ -0,0 +1,213 @@ +// 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); + + // Initialize Wasmtime + wasmtime_data_t* wasmtime_data = (wasmtime_data_t*) malloc (sizeof(wasmtime_data_t)); + wasmtime_data->engine = wasm_engine_new_with_config(wasm_config); + + // Create shared memory (required for threading) + wasm_memorytype_t *mem_type = 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 */ + ); + wasmtime_data->shm_memory = NULL; + wasmtime_sharedmemory_new(wasmtime_data->engine, mem_type, &wasmtime_data->shm_memory); + + // Compile the module + wasmtime_error_t* err; + if ((err = wasmtime_module_new(wasmtime_data->engine, (uint8_t*)wasm->data, wasm->size, &wasmtime_data->module)) != NULL) { + print_wasmtime_error(err); + free(wasmtime_data); + return NULL; + } + return wasmtime_data; +} + +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* wasmtime_data = (wasmtime_data_t*)wasm_runtime_context; + + // 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_store_t* store = wasmtime_store_new(wasmtime_data->engine, NULL, NULL); + wasmtime_context_t* context = wasmtime_store_context(store); + + wasmtime_error_t* error; + if ((error = wasmtime_context_set_wasi(context, wasi_config)) != NULL) { + print_wasmtime_error(error); + return -1; + } + + // Create linker and define WASI + wasmtime_linker_t* linker = wasmtime_linker_new(wasmtime_data->engine); + if ((error = wasmtime_linker_define_wasi(linker)) != NULL) { + print_wasmtime_error(error); + return -1; + } + + wasmtime_extern_t import; + import.kind = WASMTIME_EXTERN_SHAREDMEMORY; + import.of.sharedmemory = wasmtime_data->shm_memory; + + // Link shared memory to "wasi" module (or your module namespace) + if ((error = wasmtime_linker_define(linker, context, "wasi", 4, "memory", 6, &import)) != NULL) { + print_wasmtime_error(error); + 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* native_symbol = &native_symbols[i]; + + const char *signature = native_symbol->signature; + int parms_c = signature_parameter_count(signature); + + 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 + unsigned j = 0; + for (char *s = (char*)signature; *s != '\0' && j < parms_c; ++s) { + switch ( *s ) { + case '(': + case ')': + break; + case 'i': // 32-bit integer (i32) + case '~': // Byte length of the preceding buffer pointer (*), must follow * + params.data[j++] = wasm_valtype_new(WASM_I32); + break; + case 'I': // 64-bit integer (i64) + params.data[j++] = wasm_valtype_new(WASM_I64); + break; + case 'f': // 32-bit float (f32) + params.data[j++] = wasm_valtype_new(WASM_F32); + break; + case 'F': // 64-bit float (f64) + params.data[j++] = wasm_valtype_new(WASM_F64); + break; + case 'r': // externref type (usually a uintptr_t), or GC references + params.data[j++] = wasm_valtype_new(WASM_EXTERNREF); + break; + case '$': // String in WASM memory + case '*': // Buffer address (pointer) in WASM memory + params.data[j++] = wasm_valtype_new(HAS_64BIT_MEM ? WASM_I64 : WASM_I32); + break; + default: + fprintf(stderr, "ERR: wrong character %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)native_symbol->func_ptr, + native_symbol->attachment, NULL, &item.of.func ); + + error = wasmtime_linker_define(linker, context, "arinc653", strlen("arinc653"), + native_symbol->symbol, strlen(native_symbol->symbol), + &item ); + if (error != NULL) { + print_wasmtime_error(error); + return -1; + } + } + + wasmtime_instance_t instance; + if (// Add the compiled module to the linker + (error = wasmtime_linker_module(linker, context, NULL, 0, wasmtime_data->module)) != NULL + // Instantiate the module; all host functions created don't provide a trap + || (error = wasmtime_linker_instantiate(linker, context, wasmtime_data->module, &instance, NULL)) != NULL) { + print_wasmtime_error(error); + } + + wasmtime_func_t fnc; + if (idx == -1) { + if ((error = wasmtime_linker_get_default(linker, context, NULL, 0, &fnc)) != NULL) { + print_wasmtime_error(error); + return -1; + } + } + else { + 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 could not be found.\n"); + return -1; + } + + wasmtime_val_t val; + if ( ! wasmtime_table_get(context, &ext.of.table, idx, &val)) { + fprintf(stderr, "ERR: Index %u not given in __indirect_function_table.\n", idx); + return -1; + } + + fnc = val.of.funcref; + } + + if ((error = wasmtime_func_call(context, &fnc, NULL, 0, NULL, 0, NULL)) != NULL) { + print_wasmtime_error(error); + return -1; + } + + 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..a441ffa --- /dev/null +++ b/a653_lib_wasm32/apex_host_fncs_wasm32.c @@ -0,0 +1,111 @@ +// 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" + +#define WASM_HOSTFUNC_SIGNATURE( FNC ) { #FNC, WASM32_##FNC, WASM32_SIGNATURE__##FNC, NULL } +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..423aedc --- /dev/null +++ b/a653_lib_wasm32/apex_host_fncs_wasm32.h @@ -0,0 +1,27 @@ +// 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 +#endif +#ifdef __WASMTIME__ +#include + +/* defined in WAMR */ +typedef struct { + const char* symbol; + void* func_ptr; + const char *signature; + void *attachment; +} NativeSymbol; + +#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..9adc2de --- /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..7fadf46 --- /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..9735485 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_error_wasm32.c @@ -0,0 +1,140 @@ +// 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 "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; + + CREATE_ERROR_HANDLER( + 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..f695393 --- /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..cbbd038 --- /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..1632223 --- /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..ae4b555 --- /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..be1a2d2 --- /dev/null +++ b/a653_lib_wasm32/arinc653_part1_apex_process_wasm32.c @@ -0,0 +1,330 @@ +// 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 "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))&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..69e8857 --- /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..7d69ea6 --- /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..288e94b --- /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..e94b67b --- /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..c9cf511 --- /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..240dee7 --- /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..7d5429e --- /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: 'memory' export not found!\n"); \ + return NULL; \ + } \ + \ + if (ext.kind != WASM_EXTERN_MEMORY) { \ + fprintf(stderr, "ERR: 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..ffe8315 --- /dev/null +++ b/a653_lib_wasm32/generic_helper.c @@ -0,0 +1,72 @@ +// 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; +} + + +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; + case '*': // Buffer address (pointer) in WASM memory + ++s; + if(*s != '~') { + fprintf(stderr, "ERR: not supported character sequence *%c!\n", *s); + return -1; + } + parmc += 2; + 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..30e9d11 --- /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)) + 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 29079ae..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,24 +59,41 @@ }, "nixpkgs": { "locked": { - "lastModified": 1713145326, - "narHash": "sha256-m7+IWM6mkWOg22EC5kRUFCycXsXLSU7hWmHdmBfmC3s=", + "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": "53a2c32bc66f5ae41a28d7a9a49d321172af621e", + "rev": "78e34d1667d32d8a0ffc3eba4591ff256e80576e", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-23.11", + "ref": "nixos-25.05", "repo": "nixpkgs", "type": "github" } }, "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 4e42a46..e1ddee9 100644 --- a/flake.nix +++ b/flake.nix @@ -1,10 +1,11 @@ { description = "An ARINC 653 implementation on top of POSIX"; - inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11"; + 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 @@ -20,6 +21,13 @@ # just call the package with the normal stdenv a653lib = pkgs.callPackage pkgs/a653lib.nix { }; + # Add needed build tools via overrideAttrs (do NOT pass nativeBuildInputs to callPackage) + arinc653Packages = arinc653-wasm.packages.${system} or {}; + + a653-wasmtime = pkgs.callPackage pkgs/a653wasmtime.nix { + inherit (arinc653Packages) c-abi-lens; + }; + # override the stdenv to use an older gcc a653lib-gcc11 = let diff --git a/init.c b/init.c index 8be9ec6..f080fc7 100644 --- a/init.c +++ b/init.c @@ -16,6 +16,7 @@ #include #include "a653Init.h" +#include "a653Time.h" #include "a653_config.h" #include "a653Type.h" diff --git a/partition_a.c b/partition_a.c index 8fd1ff4..dd0fc7a 100644 --- a/partition_a.c +++ b/partition_a.c @@ -73,32 +73,40 @@ void PeriodicProcess(void){ 0, //timeout &return_code); +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ printDebug(3,"%06d Prcs A send %s \n",index++,data_sp_tx); +#endif /* #ifndef __wasm__ */ READ_SAMPLING_MESSAGE(sp_id_rx, data_sp_rx, &length, &validity, &return_code); +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ if (validity == VALID && length > 0){ printDebug(3,"Prcs A: SP we got this : >%s<\n",(char *)data_sp_rx); } else { printDebug(3,"Prcs A: validity >%d< length >%d<\n",validity,length); } +#endif /* #ifndef __wasm__ */ RECEIVE_QUEUING_MESSAGE(qp_id_rx, 0, /* time out */ data_qp_rx, /* pointer to data */ &length, /* received length */ &return_code); /* return code */ +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ if(return_code == NO_ERROR && length !=0){ printDebug(3,"Prcs A: QP we got this : >%s<\n",(char *)data_qp_rx); } else { printDebug(3,"Prcs A: return >%d<\n",return_code); } +#endif /* #ifndef __wasm__ */ GET_TIME (&system_time, &return_code); +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ printDebug(3,"Prcs A: GET_TIME >%lld<\n",system_time); +#endif /* #ifndef __wasm__ */ PERIODIC_WAIT(&return_code); } diff --git a/partition_b.c b/partition_b.c index eeea4a1..7029a70 100644 --- a/partition_b.c +++ b/partition_b.c @@ -76,7 +76,9 @@ void PeriodicProcess(void){ if (validity == VALID && length > 0){ +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ printDebug(3,"Prcs B: SP we got this : >%s< validity >%d< length >%d<\n",(char *)data_sp_rx,validity,length); +#endif /* #ifndef __wasm__ */ WRITE_SAMPLING_MESSAGE(sp_id_tx, /* sampling port id */ data_sp_tx, /* pointer to data */ @@ -92,7 +94,9 @@ 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); +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ + printDebug(3,"Prcs B: QP we got this : >%s<\n",(char *)data_qp_rx); +#endif /* #ifndef __wasm__ */ SEND_QUEUING_MESSAGE(qp_id_tx, data_qp_tx, @@ -112,7 +116,9 @@ void PeriodicProcess_2(void){ RETURN_CODE_TYPE return_code; while (1){ +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ printDebug(3,"Prcs C: activated\n"); +#endif /* #ifndef __wasm__ */ SIGNAL_SEMAPHORE(semaphore_id, &return_code); PERIODIC_WAIT(&return_code); @@ -126,7 +132,9 @@ void APeriodicProcess(void){ WAIT_SEMAPHORE(semaphore_id, 0, &return_code); - printDebug(3,"Prcs D: activated\n"); +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ + printDebug(3,"Prcs D: activated\n"); +#endif /* #ifndef __wasm__ */ TIMED_WAIT(1000000,&return_code); } } @@ -200,9 +208,11 @@ int main (int argc, char *argv[]){ &semaphore_status, &return_code); +#ifndef __wasm__ /* Do not expose non ARINC653 functions into WebAssembly */ printDebug(3,"semaphore: %d : %d\n", semaphore_status.CURRENT_VALUE, semaphore_status.MAXIMUM_VALUE); +#endif /* #ifndef __wasm__ */ usleep(50000); diff --git a/pkgs/a653lib.nix b/pkgs/a653lib.nix index d728d07..9056716 100644 --- a/pkgs/a653lib.nix +++ b/pkgs/a653lib.nix @@ -1,4 +1,12 @@ -{ lib, stdenv, fetchFromGitHub, bintools }: +{ lib, stdenv, fetchzip, bintools, gawk }: + +let + arinc653Zip = fetchzip { + url = "https://brx-content.fullsight.org/site/binaries/content/assets/itc/content/support-files/arinc653.h.zip"; + sha256 = "sha256-BGR3haRc+5I9VuyI+P8E/qTNnqVhnJKjP7j7RRCMFwg="; + curlOptsList = [ "--user-agent" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0" ]; + }; +in stdenv.mkDerivation { pname = "a653lib"; @@ -10,9 +18,14 @@ stdenv.mkDerivation { preConfigure = '' mkdir home export HOME="$PWD/home" + + # make the Makefile happy + mkdir --parent -- $HOME/tmp/download + touch $HOME/tmp/download/arinc653.h.zip + cp ${arinc653Zip}/ARINC653.h $HOME/tmp/download/. ''; - buildInputs = [ bintools ]; + buildInputs = [ bintools gawk ]; makeFlags = [ "CC=${stdenv.cc.targetPrefix}gcc" diff --git a/pkgs/a653wasmtime.nix b/pkgs/a653wasmtime.nix new file mode 100755 index 0000000..5800fa7 --- /dev/null +++ b/pkgs/a653wasmtime.nix @@ -0,0 +1,36 @@ +{ lib, stdenv, bintools, c-abi-lens, wasmtime }: + +stdenv.mkDerivation { + pname = "a653-wasmtime"; + version = "unstable-2024-04-17"; + + src = ./..; + + patches = [ ../patches/allow-cc-override.patch ]; + preConfigure = '' + mkdir home + export HOME="$PWD/home" + ''; + + buildInputs = [ bintools wasmtime.dev ]; + + preBuild = '' + mkdir -p $PWD/home/tmp/arinc653-wasm/pkgs/c-abi-lens/target/debug + # Use the pre-built c-abi-lens from the flake input + ln -s ${c-abi-lens}/bin/c-abi-lens $PWD/home/tmp/arinc653-wasm/pkgs/c-abi-lens/target/debug/c-abi-lens + ''; + + makeFlags = [ + "CC=${stdenv.cc.targetPrefix}gcc" + "AR=${stdenv.cc.targetPrefix}ar" + "RANLIB=${stdenv.cc.targetPrefix}ranlib" + ]; + + buildFlags = [ "wasm_host" ]; + + installPhase = '' + mkdir --parent -- $out/bin + mv $HOME/bin/* $out/bin + ''; + dontStrip = true; +} diff --git a/scripts/process-arinc-header.awk b/scripts/process-arinc-header.awk new file mode 100755 index 0000000..2baa74a --- /dev/null +++ b/scripts/process-arinc-header.awk @@ -0,0 +1,63 @@ +#!/usr/bin/env -S awk -f + +BEGIN { + # retain information whether the current section of the header is portable or not + is_impl_dependent = -1; + + # use linux style linendings (just \n, not \r\n) + # ORS = "\n"; + + BINMODE = 0; +} + +# detect that we are in an implementation dependent section of the header +"/*" == $1 && "Implementation" == $2 && "Dependent" == $3 { + is_impl_dependent = 1; +} + +# detect that we are in an implementation portable section of the header +"/*" == $1 && "Implementation" == $2 && "Portable" == $3 { + is_impl_dependent = 0; +} + +# mark all functions to be importend from the arinc module +"extern" == $1 && "void" == $2 && $4 ~/^\(/ { + print "WASM_IMPORT_MODULE(\"arinc653\")" +} + + +# make all implementation dependent defines ifndef based +"#define" == $1 && $2 ~ /^SYSTEM_LIMIT_/ && 1 == is_impl_dependent { + define_ident = $2; + define_value = $3; + + # print the comment + for (i = 4; i <= NF; i++) { + if (i != NF) { + printf("%s ", $i); + } else { + print $i; + } + } + + printf("%-8s %s\n", "#ifndef", define_ident); + printf("%-8s %-38s %s\n", $1, $2, $3); + print "#endif"; + next; +} + + +# always pick `APEX_LONG_INTEGER` (which ist `int64_t`) where there is a choice +{ + gsub("", "A653_INTEGER "); + + # to fit to Airbus a653lib + gsub("APEX_BYTE", "A653_BYTE"); + gsub("APEX_WORD", "A653_WORD"); + gsub("APEX_INTEGER", "A653_INTEGER"); + gsub("APEX_UNSIGNED", "A653_UNSIGNED"); + gsub("APEX_LONG_INTEGER", "A653_LONG_INTEGER"); + print; +} + + diff --git a/scripts/split-arinc-header.awk b/scripts/split-arinc-header.awk new file mode 100755 index 0000000..2ce2560 --- /dev/null +++ b/scripts/split-arinc-header.awk @@ -0,0 +1,34 @@ +#!/usr/bin/env -S awk -f + +# not the nicest, should be rather on the comment .. + +/^#ifndef APEX_/ { + # Close the previous output file if open + if (out) close(out) + + # Extract the name part after APEX_ + match($0, /^#ifndef APEX_([A-Z0-9_]+)/, arr) + name = tolower(arr[1]) + # Capitalize first letter + name = toupper(substr(name, 1, 1)) substr(name, 2) + + # Compose output filename + out = "a653" name ".h" + + # Print the current line to the new output file + print $0 > out + next +} + +# mark all functions to be importend from the arinc module +/^#define APEX_([A-Z0-9_]+)/ { + print $0 > out + print "" > out + print "#include \"a653Type.h\"" > out + next +} + +{ + # Print all other lines to the current output file + if (out) print $0 > out +}