From 37bd6c5dbe2ac51aa7a641494f0486949a54aaf7 Mon Sep 17 00:00:00 2001 From: Koen Zandberg Date: Fri, 10 Dec 2021 16:53:21 +0100 Subject: [PATCH] MERGECOMMIT: pkg/femto-container: initial import of package --- Makefile.include | 1 + makefiles/f12r.inc.mk | 20 ++ pkg/femto-container/Kconfig | 11 + pkg/femto-container/Makefile | 9 + pkg/femto-container/Makefile.dep | 1 + pkg/femto-container/Makefile.femto | 9 + pkg/femto-container/Makefile.include | 3 + pkg/femto-container/contrib/Makefile | 2 + pkg/femto-container/contrib/call.c | 245 ++++++++++++++++++ pkg/femto-container/contrib/store.c | 88 +++++++ pkg/femto-container/doc.txt | 19 ++ pkg/femto-container/femto-container.inc.mk | 36 +++ pkg/femto-container/include/call.h | 44 ++++ pkg/femto-container/include/shared.h | 64 +++++ tests/pkg_femto-container/Makefile | 16 ++ .../pkg_femto-container/application/Makefile | 2 + .../application/fletcher32_fc.c | 53 ++++ tests/pkg_femto-container/main.c | 96 +++++++ 18 files changed, 719 insertions(+) create mode 100644 makefiles/f12r.inc.mk create mode 100644 pkg/femto-container/Kconfig create mode 100644 pkg/femto-container/Makefile create mode 100644 pkg/femto-container/Makefile.dep create mode 100644 pkg/femto-container/Makefile.femto create mode 100644 pkg/femto-container/Makefile.include create mode 100644 pkg/femto-container/contrib/Makefile create mode 100644 pkg/femto-container/contrib/call.c create mode 100644 pkg/femto-container/contrib/store.c create mode 100644 pkg/femto-container/doc.txt create mode 100644 pkg/femto-container/femto-container.inc.mk create mode 100644 pkg/femto-container/include/call.h create mode 100644 pkg/femto-container/include/shared.h create mode 100644 tests/pkg_femto-container/Makefile create mode 100644 tests/pkg_femto-container/application/Makefile create mode 100644 tests/pkg_femto-container/application/fletcher32_fc.c create mode 100644 tests/pkg_femto-container/main.c diff --git a/Makefile.include b/Makefile.include index 7fd80bba7b77..340e7370110a 100644 --- a/Makefile.include +++ b/Makefile.include @@ -662,6 +662,7 @@ endif # variables defined in `riotboot.mk` for `FLASHFILE` before it is evaluated. # It should be included after defining 'BINFILE' for 'riotboot.bin' handling. include $(RIOTMAKE)/boot/riotboot.mk +include $(RIOTMAKE)/f12r.inc.mk # include suit targets ifneq (,$(filter suit, $(USEMODULE))) diff --git a/makefiles/f12r.inc.mk b/makefiles/f12r.inc.mk new file mode 100644 index 000000000000..ea3ea14631e8 --- /dev/null +++ b/makefiles/f12r.inc.mk @@ -0,0 +1,20 @@ +.PHONY: f12r/% + +f12r/%: $$(if $$(filter f123/clean,$$@),,pkg-prepare) + $(Q)for app in $(F12R_DIRS); do \ + /usr/bin/env -i RIOTBASE=$(RIOTBASE) \ + Q=$(Q) QQ=$(QQ) "$(MAKE)" --no-print-directory -C $${app} $*; \ + done; + +clean: f12r/clean + +# Make the F12R_BLOBS depend on the APPS +$(F12R_BLOBS): $(F12R_DIRS) +# Make sure they are all built +$(F12R_DIRS): f12r/all + +# Make sure the BLOBS are built +BUILDDEPS += $(F12R_BLOBS) +# Add the femto-container blobs to BLOBS +BLOBS += $(F12R_BLOBS) + diff --git a/pkg/femto-container/Kconfig b/pkg/femto-container/Kconfig new file mode 100644 index 000000000000..2c7d7aceb674 --- /dev/null +++ b/pkg/femto-container/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2021 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. +# + +config PACKAGE_NANOCBOR + bool "NANOCBOR encoder and decoder library package" + depends on TEST_KCONFIG + depends on HAS_ARCH_32BIT diff --git a/pkg/femto-container/Makefile b/pkg/femto-container/Makefile new file mode 100644 index 000000000000..8e432da20839 --- /dev/null +++ b/pkg/femto-container/Makefile @@ -0,0 +1,9 @@ +PKG_NAME = femto-container +PKG_URL = https://github.com/future-proof-iot/Femto-Container +PKG_VERSION = 6987a20c1b3e3e5721a15a102e40d941c6bd1d81 +PKG_LICENSE = apache + +include $(RIOTBASE)/pkg/pkg.mk + +all: + $(QQ)"$(MAKE)" -C $(PKG_SOURCE_DIR)/src -f $(PKG_DIR)/Makefile.femto MODULE=$(PKG_NAME) diff --git a/pkg/femto-container/Makefile.dep b/pkg/femto-container/Makefile.dep new file mode 100644 index 000000000000..9f689c861424 --- /dev/null +++ b/pkg/femto-container/Makefile.dep @@ -0,0 +1 @@ +#USEMODULE += femto-container_contrib diff --git a/pkg/femto-container/Makefile.femto b/pkg/femto-container/Makefile.femto new file mode 100644 index 000000000000..5afac0c38596 --- /dev/null +++ b/pkg/femto-container/Makefile.femto @@ -0,0 +1,9 @@ +EXTRA_CFLAGS += -Wno-format-nonliteral -Wno-override-init -Wno-pedantic -foptimize-sibling-calls +CFLAGS += $(EXTRA_CFLAGS) +NO_AUTO_SRC := 1 +SRC += bpf.c +SRC += verify.c +SRC += jumptable.c + +include $(RIOTBASE)/Makefile.base + diff --git a/pkg/femto-container/Makefile.include b/pkg/femto-container/Makefile.include new file mode 100644 index 000000000000..e432f3f535ab --- /dev/null +++ b/pkg/femto-container/Makefile.include @@ -0,0 +1,3 @@ +INCLUDES += -I$(RIOTPKG)/femto-container/include +INCLUDES += -I$(PKGDIRBASE)/femto-container/include +#DIRS += $(RIOTPKG)/femto-container/contrib diff --git a/pkg/femto-container/contrib/Makefile b/pkg/femto-container/contrib/Makefile new file mode 100644 index 000000000000..12c2af132e58 --- /dev/null +++ b/pkg/femto-container/contrib/Makefile @@ -0,0 +1,2 @@ +MODULE := femto-container_contrib +include $(RIOTBASE)/Makefile.base diff --git a/pkg/femto-container/contrib/call.c b/pkg/femto-container/contrib/call.c new file mode 100644 index 000000000000..e708746e4040 --- /dev/null +++ b/pkg/femto-container/contrib/call.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2020 Inria + * Copyright (C) 2020 Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include +#include +#include +#include +#include + +#include "femtocontainer/femtocontainer.h" +#include "shared.h" +#include "xtimer.h" + +#ifdef MODULE_GCOAP +#include "net/gcoap.h" +#include "net/nanocoap.h" +#endif +#include "saul.h" +#include "saul_reg.h" +#include "fmt.h" + +#ifdef MODULE_ZTIMER +#include "ztimer.h" +#endif + +uint32_t bpf_vm_memcpy(bpf_t *bpf, uint32_t dest_p, uint32_t src_p, uint32_t size, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a4; + (void)a5; + + void *dest = (void *)(uintptr_t)dest_p; + const void *src = (const void *)(uintptr_t)src_p; + + return (uintptr_t) memcpy(dest, src, size); +} + +#ifdef MODULE_XTIMER +uint32_t bpf_vm_now_ms(bpf_t *bpf, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a1; + (void)a2; + (void)a3; + (void)a4; + (void)a5; + return xtimer_now_usec64()/US_PER_MS; +} +#endif + +#ifdef MODULE_SAUL_REG +uint32_t bpf_vm_saul_reg_find_nth(bpf_t *bpf, uint32_t nth, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a2; + (void)a3; + (void)a4; + (void)a5; + int pos = (int)nth; + saul_reg_t *reg = saul_reg_find_nth(pos); + return (uint32_t)(intptr_t)reg; +} + +uint32_t bpf_vm_saul_reg_find_type(bpf_t *bpf, uint32_t type, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a2; + (void)a3; + (void)a4; + (void)a5; + + saul_reg_t *reg = saul_reg_find_type(type); + return (uint32_t)(intptr_t)reg; +} + +uint32_t bpf_vm_saul_reg_read(bpf_t *bpf, uint32_t dev_p, uint32_t data_p, uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a3; + (void)a4; + (void)a5; + + saul_reg_t *dev = (saul_reg_t*)(intptr_t)dev_p; + phydat_t *data = (phydat_t*)(intptr_t)data_p; + + int res = saul_reg_read(dev, data); + return (uint32_t)res; +} +#endif + +#ifdef MODULE_GCOAP +uint32_t bpf_vm_gcoap_resp_init(bpf_t *bpf, uint32_t coap_ctx_p, uint32_t resp_code_u, uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a3; + (void)a4; + (void)a5; + + bpf_coap_ctx_t *coap_ctx = (bpf_coap_ctx_t *)(intptr_t)coap_ctx_p; + unsigned resp_code = (unsigned)resp_code_u; + + gcoap_resp_init(coap_ctx->pkt, coap_ctx->buf, coap_ctx->buf_len, resp_code); + return 0; +} + +uint32_t bpf_vm_coap_add_format(bpf_t *bpf, uint32_t coap_ctx_p, uint32_t format, uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a3; + (void)a4; + (void)a5; + + bpf_coap_ctx_t *coap_ctx = (bpf_coap_ctx_t *)(intptr_t)coap_ctx_p; + ssize_t res = coap_opt_add_format(coap_ctx->pkt, format); + return (uint32_t)res; +} + +uint32_t bpf_vm_coap_opt_finish(bpf_t *bpf, uint32_t coap_ctx_p, uint32_t flags_u, uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a3; + (void)a4; + (void)a5; + + bpf_coap_ctx_t *coap_ctx = (bpf_coap_ctx_t *)(intptr_t)coap_ctx_p; + uint16_t flags = (uint16_t)flags_u; + + ssize_t res = coap_opt_finish(coap_ctx->pkt, flags); + return (uint32_t)res; +} + +uint32_t bpf_vm_coap_get_pdu(bpf_t *bpf, uint32_t coap_ctx_p, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a2; + (void)a3; + (void)a4; + (void)a5; + + bpf_coap_ctx_t *coap_ctx = (bpf_coap_ctx_t *)(intptr_t)coap_ctx_p; + return (uint32_t)(intptr_t)((coap_pkt_t*)coap_ctx->pkt)->payload; +} +#endif + +#ifdef MODULE_FMT +uint32_t bpf_vm_fmt_s16_dfp(bpf_t *bpf, uint32_t out_p, uint32_t val, uint32_t fp_digits, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a4; + (void)a5; + + char *out = (char*)(intptr_t)out_p; + size_t res = fmt_s16_dfp(out, (int16_t)val, (int)fp_digits); + return (uint32_t)res; +} + +uint32_t bpf_vm_fmt_u32_dec(bpf_t *bpf, uint32_t out_p, uint32_t val, uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a3; + (void)a4; + (void)a5; + + char *out = (char*)(intptr_t)out_p; + size_t res = fmt_u32_dec(out, (uint32_t)val); + return (uint32_t)res; +} +#endif + +#ifdef MODULE_ZTIMER +uint32_t bpf_vm_ztimer_now(bpf_t *bpf, uint32_t a1, uint32_t a2, + uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a1; + (void)a2; + (void)a3; + (void)a4; + (void)a5; + return ztimer_now(ZTIMER_USEC); +} +uint32_t bpf_vm_ztimer_periodic_wakeup(bpf_t *bpf, uint32_t last_wakeup_p, + uint32_t period, + uint32_t a3, uint32_t a4, uint32_t a5) +{ + (void)bpf; + (void)a3; + (void)a4; + (void)a5; + + uint32_t *last = (uint32_t*)(intptr_t)last_wakeup_p; + + ztimer_periodic_wakeup(ZTIMER_USEC, last, period); + return 0; +} +#endif + + +bpf_call_t bpf_get_external_call(uint32_t num) +{ + switch(num) { +#ifdef MODULE_XTIMER + case BPF_FUNC_BPF_NOW_MS: + return &bpf_vm_now_ms; +#endif +#ifdef MODULE_SAUL_REG + case BPF_FUNC_BPF_SAUL_REG_FIND_NTH: + return &bpf_vm_saul_reg_find_nth; + case BPF_FUNC_BPF_SAUL_REG_FIND_TYPE: + return &bpf_vm_saul_reg_find_type; + case BPF_FUNC_BPF_SAUL_REG_READ: + return &bpf_vm_saul_reg_read; +#endif +#ifdef MODULE_GCOAP + case BPF_FUNC_BPF_GCOAP_RESP_INIT: + return &bpf_vm_gcoap_resp_init; + case BPF_FUNC_BPF_COAP_OPT_FINISH: + return &bpf_vm_coap_opt_finish; + case BPF_FUNC_BPF_COAP_ADD_FORMAT: + return &bpf_vm_coap_add_format; + case BPF_FUNC_BPF_COAP_GET_PDU: + return &bpf_vm_coap_get_pdu; +#endif +#ifdef MODULE_FMT + case BPF_FUNC_BPF_FMT_S16_DFP: + return &bpf_vm_fmt_s16_dfp; + case BPF_FUNC_BPF_FMT_U32_DEC: + return &bpf_vm_fmt_u32_dec; +#endif +#ifdef MODULE_ZTIMER + case BPF_FUNC_BPF_ZTIMER_NOW: + return &bpf_vm_ztimer_now; + case BPF_FUNC_BPF_ZTIMER_PERIODIC_WAKEUP: + return &bpf_vm_ztimer_periodic_wakeup; +#endif + default: + return NULL; + } +} diff --git a/pkg/femto-container/contrib/store.c b/pkg/femto-container/contrib/store.c new file mode 100644 index 000000000000..edbafd235814 --- /dev/null +++ b/pkg/femto-container/contrib/store.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2020 Inria + * Copyright (C) 2020 Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#include +#include +#include "btree.h" +#include "bpf.h" +#include "bpf/store.h" +#include "memarray.h" + +static btree_t _global; + +/* Singleton mem array */ +static memarray_t _array; +static bpf_store_keyval_t _vals[CONFIG_BPF_STORE_NUM_VALUES]; + +void bpf_store_init(void) +{ + memarray_init(&_array, _vals, sizeof(bpf_store_keyval_t), + CONFIG_BPF_STORE_NUM_VALUES); +} + +static int _alloc_value(btree_t *tree, uint32_t key, uint32_t value) +{ + bpf_store_keyval_t *keyval = memarray_alloc(&_array); + bpf_store_set_value(keyval, value); + if (!keyval) { + return -1; + } + btree_insert(tree, &keyval->node, key); + return 0; +} + +static int _fetch_value(btree_t *tree, uint32_t key, uint32_t *value) +{ + bpf_store_keyval_t *keyval = (bpf_store_keyval_t*)btree_find_key(tree, key); + if (!keyval) { + *value = 0; + return _alloc_value(tree, key, *value); + } + *value = bpf_store_get_value(keyval); + return 0; +} + +static int _store_value(btree_t *tree, uint32_t key, uint32_t value) +{ + bpf_store_keyval_t *keyval = (bpf_store_keyval_t*)btree_find_key(tree, key); + if (!keyval) { + return _alloc_value(tree, key, value); + } + bpf_store_set_value(keyval, value); + return 0; +} + +int bpf_store_update_global(uint32_t key, uint32_t value) +{ + return _store_value(&_global, key, value); +} + +int bpf_store_update_local(bpf_t *bpf, uint32_t key, uint32_t value) +{ + return _store_value(&bpf->btree, key, value); +} + +int bpf_store_fetch_global(uint32_t key, uint32_t *value) +{ +/* fetch value from the global store if it exists, otherwise add it and return a + * default value */ + return _fetch_value(&_global, key, value); +} + +int bpf_store_fetch_local(bpf_t *bpf, uint32_t key, uint32_t *value) +{ +/* fetch value from the bpf local store if it exists, otherwise add it and return a + * default value */ + return _fetch_value(&bpf->btree, key, value); +} + +void bpf_store_iter_global(btree_cb_t cb, void *ctx) +{ + btree_traverse(&_global, cb, ctx); +} diff --git a/pkg/femto-container/doc.txt b/pkg/femto-container/doc.txt new file mode 100644 index 000000000000..d2040f42f2ee --- /dev/null +++ b/pkg/femto-container/doc.txt @@ -0,0 +1,19 @@ +/** + * @defgroup pkg_nanocbor NanoCBOR library + * @ingroup pkg + * @ingroup sys + * @brief CBOR encoder and decoder library for tiny devices + * + * This package contains the NanoCBOR library for a small CBOR encoder and + * decoder. Flash footprint for encoding and decoding should be below 1K each. + * + * ## Usage + * + * Just add it as a package in your application: + * + * ```makefile + * USEPKG += nanocbor + * ``` + * + * @see https://github.com/bergzand/nanocbor + */ diff --git a/pkg/femto-container/femto-container.inc.mk b/pkg/femto-container/femto-container.inc.mk new file mode 100644 index 000000000000..af266bc4b34d --- /dev/null +++ b/pkg/femto-container/femto-container.inc.mk @@ -0,0 +1,36 @@ +F12R_SOURCES ?= $(wildcard $(CURDIR)/*.c) +F12R_GENFEMTOC ?= $(RIOTBASE)/build/pkg/femto-container/tools/gen_rbf.py + +F12R_BINS = $(F12R_SOURCES:.c=.bin) +F12R_OBJS = $(F12R_SOURCES:.c=.o) + +LLC ?= llc +CLANG ?= clang +INC_FLAGS = -nostdinc -isystem `$(CLANG) -print-file-name=include` +EXTRA_CFLAGS ?= -Os -emit-llvm + +F12RINCLUDE = -I$(RIOTBASE)/build/pkg/femto-container/include \ + -I$(RIOTBASE)/sys/include \ + # + +all: $(F12R_BINS) + +.PHONY: clean + +clean: + rm -f $(F12R_OBJS) $(F12R_BINS) + +INC_FLAGS = -nostdinc -isystem `$(CLANG) -print-file-name=include` + +$(F12R_OBJS): %.o:%.c + $(Q)$(CLANG) $(INC_FLAGS) \ + $(F12RINCLUDE) \ + -Wno-unused-value -Wno-pointer-sign -g3\ + -Wno-compare-distinct-pointer-types \ + -Wno-gnu-variable-sized-type-not-at-end \ + -Wno-address-of-packed-member -Wno-tautological-compare \ + -Wno-unknown-warning-option \ + $(EXTRA_CFLAGS) -c $< -o -| $(LLC) -march=bpf -mcpu=v2 -filetype=obj -o $@ + +$(F12R_BINS): %.bin:%.o + $(Q)$(F12R_GENFEMTOC) generate $< $@ diff --git a/pkg/femto-container/include/call.h b/pkg/femto-container/include/call.h new file mode 100644 index 000000000000..43b14ff1ee59 --- /dev/null +++ b/pkg/femto-container/include/call.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 Inria + * Copyright (C) 2020 Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef BPF_CALL_H +#define BPF_CALL_H + +#include +#include "femtocontainer/femtocontainer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t bpf_vm_printf(bpf_t *bpf, uint32_t fmt, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4); +uint32_t bpf_vm_store_local(bpf_t *bpf, uint32_t fmt, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4); +uint32_t bpf_vm_store_global(bpf_t *bpf, uint32_t fmt, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4); +uint32_t bpf_vm_fetch_local(bpf_t *bpf, uint32_t fmt, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4); +uint32_t bpf_vm_fetch_global(bpf_t *bpf, uint32_t fmt, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4); +uint32_t bpf_vm_memcpy(bpf_t *bpf, uint32_t dest_p, uint32_t src_p, uint32_t size, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_now_ms(bpf_t *bpf, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_saul_reg_find_nth(bpf_t *bpf, uint32_t nth, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_saul_reg_find_type(bpf_t *bpf, uint32_t type, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_saul_reg_read(bpf_t *bpf, uint32_t dev_p, uint32_t data_p, uint32_t a3, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_gcoap_resp_init(bpf_t *bpf, uint32_t coap_ctx_p, uint32_t resp_code_u, uint32_t a3, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_coap_opt_finish(bpf_t *bpf, uint32_t coap_ctx_p, uint32_t flags_u, uint32_t a3, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_fmt_s16_dfp(bpf_t *bpf, uint32_t out_p, uint32_t val, uint32_t fp_digits, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_fmt_u32_dec(bpf_t *bpf, uint32_t out_p, uint32_t val, uint32_t a3, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_coap_add_format(bpf_t *bpf, uint32_t coap_ctx_p, uint32_t format, uint32_t a3, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_coap_get_pdu(bpf_t *bpf, uint32_t coap_ctx_p, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5); + + +uint32_t bpf_vm_ztimer_now(bpf_t *bpf, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5); +uint32_t bpf_vm_ztimer_periodic_wakeup(bpf_t *bpf, uint32_t last_wakeup_p, uint32_t period, uint32_t a3, uint32_t a4, uint32_t a5); +#ifdef __cplusplus +} +#endif +#endif /* BPF_CALL_H */ + diff --git a/pkg/femto-container/include/shared.h b/pkg/femto-container/include/shared.h new file mode 100644 index 000000000000..425e34854eec --- /dev/null +++ b/pkg/femto-container/include/shared.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2020 Inria + * Copyright (C) 2020 Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef BPF_SHARED_H +#define BPF_SHARED_H + +#include +#include +#include "femtocontainer/builtin_shared.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define __bpf_shared_ptr(type, name) \ +union { \ + type name; \ + uint64_t :64; \ +} __attribute__((aligned(8))) + +enum { + /* Aux helper functions (stdlib) */ + BPF_FUNC_BPF_PRINTF = 0x01, + BPF_FUNC_BPF_MEMCPY = 0x02, + + /* Time(r) functions */ + BPF_FUNC_BPF_NOW_MS = 0x20, + + /* Saul functions */ + BPF_FUNC_BPF_SAUL_REG_FIND_NTH = 0x30, + BPF_FUNC_BPF_SAUL_REG_FIND_TYPE = 0x31, + BPF_FUNC_BPF_SAUL_REG_READ = 0x32, + + /* (g)coap functions */ + BPF_FUNC_BPF_GCOAP_RESP_INIT = 0x40, + BPF_FUNC_BPF_COAP_OPT_FINISH = 0x41, + BPF_FUNC_BPF_COAP_ADD_FORMAT = 0x42, + BPF_FUNC_BPF_COAP_GET_PDU = 0x43, + + BPF_FUNC_BPF_FMT_S16_DFP = 0x50, + BPF_FUNC_BPF_FMT_U32_DEC = 0x51, + + /* ZTIMER */ + BPF_FUNC_BPF_ZTIMER_NOW = 0x60, + BPF_FUNC_BPF_ZTIMER_PERIODIC_WAKEUP = 0x61, +}; + +/* Helper structs */ +typedef struct { + __bpf_shared_ptr(void*, pkt); /**< Opaque pointer to the coap_pkt_t struct */ + __bpf_shared_ptr(uint8_t*, buf); /**< Packet buffer */ + size_t buf_len; /**< Packet buffer length */ +} bpf_coap_ctx_t; + +#ifdef __cplusplus +} +#endif +#endif /* BPF_SHARED_H */ diff --git a/tests/pkg_femto-container/Makefile b/tests/pkg_femto-container/Makefile new file mode 100644 index 000000000000..aff35671a776 --- /dev/null +++ b/tests/pkg_femto-container/Makefile @@ -0,0 +1,16 @@ +include ../Makefile.tests_common + +F12R_DIRS += $(CURDIR)/application +F12R_BLOBS += application/fletcher32_fc.bin + +USEMODULE += embunit +USEPKG += femto-container + +USEMODULE += xtimer +USEMODULE += saul +USEMODULE += saul_reg +USEMODULE += saul_default + +CFLAGS += -I$(CURDIR) + +include $(RIOTBASE)/Makefile.include diff --git a/tests/pkg_femto-container/application/Makefile b/tests/pkg_femto-container/application/Makefile new file mode 100644 index 000000000000..68e151b9c246 --- /dev/null +++ b/tests/pkg_femto-container/application/Makefile @@ -0,0 +1,2 @@ +RIOTBASE ?= $(CURDIR)/../../.. +include $(RIOTBASE)/pkg/femto-container/femto-container.inc.mk diff --git a/tests/pkg_femto-container/application/fletcher32_fc.c b/tests/pkg_femto-container/application/fletcher32_fc.c new file mode 100644 index 000000000000..b35076926d58 --- /dev/null +++ b/tests/pkg_femto-container/application/fletcher32_fc.c @@ -0,0 +1,53 @@ +/* + * Copyright 2015 Eistec AB + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup sys_checksum_fletcher32 + * @{ + * + * @file + * @brief Fletcher32 implementation + * + * @author Joakim NohlgĂ„rd + * + * @} + */ + +#include + +#include +#include "femtocontainer/shared.h" + +#include "unaligned.h" + +typedef struct { + __bpf_shared_ptr(const uint16_t *, data); + uint32_t words; +} fletcher32_ctx_t; + +uint32_t fletcher32(fletcher32_ctx_t *ctx) +{ + uint32_t words = ctx->words; + const uint16_t *data = ctx->data; + + uint32_t sum1 = 0xffff, sum2 = 0xffff; + + while (words) { + unsigned tlen = words > 359 ? 359 : words; + words -= tlen; + do { + sum2 += sum1 += unaligned_get_u16(data++); + } while (--tlen); + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + sum2 = (sum2 & 0xffff) + (sum2 >> 16); + } + /* Second reduction step to reduce sums to 16 bits */ + sum1 = (sum1 & 0xffff) + (sum1 >> 16); + sum2 = (sum2 & 0xffff) + (sum2 >> 16); + return (sum2 << 16) | sum1; +} diff --git a/tests/pkg_femto-container/main.c b/tests/pkg_femto-container/main.c new file mode 100644 index 000000000000..7c9053b728c1 --- /dev/null +++ b/tests/pkg_femto-container/main.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2020 Inria + * Copyright (C) 2020 Koen Zandberg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup tests + * @{ + * + * @file + * @brief Tests f12r virtual machine + * + * @author Koen Zandberg + * + * @} + */ +#include +#include +#include +#include "femtocontainer/femtocontainer.h" +#include "shared.h" +#include "embUnit.h" +#include "xtimer.h" + +#include "blob/application/fletcher32_fc.bin.h" + +static const unsigned char __attribute__((aligned(sizeof(uint16_t)))) wrap_around_data[] = + "AD3Awn4kb6FtcsyE0RU25U7f55Yncn3LP3oEx9Gl4qr7iDW7I8L6Pbw9jNnh0sE4DmCKuc" + "d1J8I34vn31W924y5GMS74vUrZQc08805aj4Tf66HgL1cO94os10V2s2GDQ825yNh9Yuq3" + "QHcA60xl31rdA7WskVtCXI7ruH1A4qaR6Uk454hm401lLmv2cGWt5KTJmr93d3JsGaRRPs" + "4HqYi4mFGowo8fWv48IcA3N89Z99nf0A0H2R6P0uI4Tir682Of3Rk78DUB2dIGQRRpdqVT" + "tLhgfET2gUGU65V3edSwADMqRttI9JPVz8JS37g5QZj4Ax56rU1u0m0K8YUs57UYG5645n" + "byNy4yqxu7"; + +static uint8_t _f12r_stack[512]; + +typedef struct { + __bpf_shared_ptr(const uint16_t *, data); + uint32_t words; +} fletcher32_ctx_t; + +static void tests_f12r_run1(void) +{ + fletcher32_ctx_t ctx = { + .data = (const uint16_t*)(uintptr_t) wrap_around_data, + .words = sizeof(wrap_around_data)/2, + }; + f12r_t femtoc = { + .application = fletcher32_fc_bin, + .application_len = sizeof(fletcher32_fc_bin), + .stack = _f12r_stack, + .stack_size = sizeof(_f12r_stack), + }; + f12r_mem_region_t region; + printf("f12r context size: %u, memory region size: %u\n", (unsigned)sizeof(f12r_t), (unsigned)sizeof(f12r_mem_region_t)); + f12r_setup(&femtoc); + + f12r_add_region(&femtoc, ®ion, + (void*)wrap_around_data, sizeof(wrap_around_data), FC_MEM_REGION_READ); + int64_t result = 0; + uint32_t start = xtimer_now_usec(); + int res = 0; + for (unsigned i = 0; i < 1000; i++) { + res = f12r_execute_ctx(&femtoc, &ctx, sizeof(ctx), &result); + } + uint32_t stop = xtimer_now_usec(); + + TEST_ASSERT_EQUAL_INT(0, res); + TEST_ASSERT_EQUAL_INT(0x5bac8c3d, (uint32_t)result); + printf("Result: %"PRIx32"\n", (uint32_t)result); + printf("duration: %"PRIu32" us -> %"PRIu32" us/exec\n", + (stop - start), (stop - start)/1000); +} + +Test *tests_f12r(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(tests_f12r_run1), + }; + + EMB_UNIT_TESTCALLER(f12r_tests, NULL, NULL, fixtures); + return (Test*)&f12r_tests; +} + +int main(void) +{ + TESTS_START(); + TESTS_RUN(tests_f12r()); + TESTS_END(); + + return 0; +}