diff --git a/.github/workflows/arduino-build.yml b/.github/workflows/arduino-build.yml index c9555af7a..e8aeb5733 100644 --- a/.github/workflows/arduino-build.yml +++ b/.github/workflows/arduino-build.yml @@ -87,6 +87,8 @@ jobs: example: ${{ fromJson(needs.discover.outputs.matrix) }} steps: - uses: actions/checkout@v7 + with: + submodules: true # include/MMgr: src/ builds against it - uses: arduino/setup-arduino-cli@v2 # Restore-only: the build job wraps the toolchain in place for ccache, so it must never # save ~/.arduino15 back (a wrapped/half-wrapped tree in the cache is what broke every diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 41802079b..6938c58d3 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -40,6 +40,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v7 + with: + submodules: true # include/MMgr: src/ builds against it - name: Set up Python uses: actions/setup-python@v7 diff --git a/.github/workflows/esp-idf-build.yml b/.github/workflows/esp-idf-build.yml index 61f7604d2..b8564c8e2 100644 --- a/.github/workflows/esp-idf-build.yml +++ b/.github/workflows/esp-idf-build.yml @@ -51,6 +51,8 @@ jobs: idf: [v5.5] steps: - uses: actions/checkout@v7 + with: + submodules: true # include/MMgr: src/ builds against it # arduino-esp32 is fetched from the ESP Component Registry on first build (minutes), and # lands in the example's own managed_components/. Keyed on the manifest, which is what diff --git a/.github/workflows/esp32-build.yml b/.github/workflows/esp32-build.yml index bb022b521..6dd8452c2 100644 --- a/.github/workflows/esp32-build.yml +++ b/.github/workflows/esp32-build.yml @@ -69,6 +69,8 @@ jobs: example: ${{ fromJson(needs.discover.outputs.matrix) }} steps: - uses: actions/checkout@v7 + with: + submodules: true # include/MMgr: src/ builds against it - uses: actions/setup-python@v7 with: python-version: "3.x" diff --git a/.github/workflows/pentest.yml b/.github/workflows/pentest.yml index a809b54c2..bc7cf2364 100644 --- a/.github/workflows/pentest.yml +++ b/.github/workflows/pentest.yml @@ -13,6 +13,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 + with: + submodules: true # include/MMgr: src/ builds against it - name: Set up Python uses: actions/setup-python@v7 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 669a06272..a8a39ab0c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,7 @@ jobs: - name: Checkout Code uses: actions/checkout@v7 with: + submodules: true # include/MMgr: src/ builds against it path: "library-source" # Full history + tags so the release summary can diff against the previous tag. fetch-depth: 0 @@ -102,6 +103,8 @@ jobs: steps: - name: Checkout Code uses: actions/checkout@v7 + with: + submodules: true # include/MMgr: src/ builds against it - name: Check for PlatformIO token id: token diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index 3a3a5b7fc..7195a1c13 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -36,6 +36,7 @@ jobs: steps: - uses: actions/checkout@v7 with: + submodules: true # include/MMgr: src/ builds against it fetch-depth: 0 # full history: SonarCloud attributes findings to new code by commit date - uses: actions/setup-python@v7 diff --git a/.github/workflows/test-report.yml b/.github/workflows/test-report.yml index ece7a6c57..c4353d2b1 100644 --- a/.github/workflows/test-report.yml +++ b/.github/workflows/test-report.yml @@ -52,6 +52,7 @@ jobs: steps: - uses: actions/checkout@v7 with: + submodules: true # include/MMgr: src/ builds against it fetch-depth: 0 # full history: the diff base, the report commit, SonarCloud new-code attribution # Authenticate with the automatic-actions deploy key so the report commit pushes over SSH # (past the protected-main ruleset), which a GITHUB_TOKEN push cannot. diff --git a/.gitmodules b/.gitmodules index 9b8fbdf84..05e6ca01d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ path = include/MMgr url = https://github.com/dstroy0/MMgr.git branch = main +[submodule "include/embedded_types"] + path = include/embedded_types + url = https://github.com/dstroy0/embedded_types.git diff --git a/cspell.json b/cspell.json index 31fe98da9..3def49950 100644 --- a/cspell.json +++ b/cspell.json @@ -1668,6 +1668,7 @@ "**/*.der", "**/*.gz", "test/dep_graph.json", - "test/compile_commands.json" + "test/compile_commands.json", + "docs/CHANGELOG.md" ] } diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 233eabd88..ac6f3ad5b 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -12,18 +12,52 @@ protocore_add_module(include HEADER_ONLY ) -# MMgr is a separate repository, vendored as a submodule, and brings its own build description. Its -# ROOT is the entry, not its src/: that is where mmgr_add_module() is defined, and every directory -# below it calls that. Entering src/ directly fails on the first module. +# MMgr is a separate repository, vendored as a submodule. Its own build description is not entered: +# it builds MMgr once per width environment for MMgr's suites, and it reaches its include root +# through CMAKE_SOURCE_DIR, which names this tree's top rather than MMgr's once it is a +# subdirectory. ProtoCore builds MMgr's sources as one more target under ProtoCore's own flags, as +# the Arduino, PlatformIO and ESP-IDF builds do. # -# ITS BINARY DIRECTORY IS ONE CHARACTER, and that is not tidiness. A Windows path is capped at 260 -# characters, and MMgr's own deepest suite spends 211 of them before the object file: -# test/unit/confinium_exclusivum_infinitas/test_confinium_exclusivum_infinitas/CMakeFiles/ -# test_confinium_exclusivum_infinitas_host.dir - the module name three times over. Two of that -# suite's sources live in test/support/ rather than beside it, so CMake namespaces them under a -# 32-character hash of their directory, and gcc then cannot create the .d file beside the object. -# Five targets failed to compile that way under `/pc_include/mmgr`. Under `/m` they -# fit. Nested one directory deeper and they would not, so this is load bearing. -if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/MMgr/CMakeLists.txt") - add_subdirectory(MMgr "${CMAKE_BINARY_DIR}/m") +# The sources are the ones MMgr's src/CMakeLists.txt enters, module for module. A directory it does +# not enter is not part of MMgr's build, and impensa_ancorae_acus compiles one profile of five, the +# one MMGR_ANCORAE_FORMA names and generic when nothing does, since each defines the same table. +# +# The include roots are the three MMgr's mmgr_add_module() gives a module: include/ for mmgr.h, +# src/ so a module header is reached as /.h, and embedded_types, which mmgr.h +# includes. The capability switches are MMgr's defaults, stated so every translation unit that reads +# them sees the same value. +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/MMgr/src") + if(DEFINED MMGR_ANCORAE_FORMA) + string(TOLOWER "${MMGR_ANCORAE_FORMA}" _pc_mmgr_forma) + else() + set(_pc_mmgr_forma generic) + endif() + set(_pc_mmgr_src "${CMAKE_CURRENT_SOURCE_DIR}/MMgr/src") + add_library(pc_mmgr OBJECT + "${_pc_mmgr_src}/clz/clz.c" + "${_pc_mmgr_src}/impensa_ancorae_acus/impensa_ancorae_acus_${_pc_mmgr_forma}.c" + "${_pc_mmgr_src}/ascii_persona_bitorum/ascii_persona_bitorum.c" + "${_pc_mmgr_src}/bitorum_introitus_exitus/bitorum_introitus_exitus.c" + "${_pc_mmgr_src}/endian/endian.c" + "${_pc_mmgr_src}/proximus_operor/proximus_operor.c" + "${_pc_mmgr_src}/verbum_scrutor/verbum_scrutor.c" + "${_pc_mmgr_src}/memoria_operor/memoria_operor.c" + "${_pc_mmgr_src}/cellularum_laboro/cellularum_laboro.c" + "${_pc_mmgr_src}/spatium/spatium.c" + "${_pc_mmgr_src}/octetus_introitus_exitus/octetus_introitus_exitus.c" + "${_pc_mmgr_src}/locus_carcerum/locus_carcerum.c" + "${_pc_mmgr_src}/memoria_anularis/memoria_anularis.c" + "${_pc_mmgr_src}/memoria_externa/memoria_externa.c" + "${_pc_mmgr_src}/transformo/transformo.c" + "${_pc_mmgr_src}/memoriam_praetereo/memoriam_praetereo.c" + "${_pc_mmgr_src}/memoriam_praetereo/praet_ordo.c" + "${_pc_mmgr_src}/memoriam_praetereo/praet_descriptor.c" + "${_pc_mmgr_src}/fractio/fractio.c" + "${_pc_mmgr_src}/verba_scribo/verba_scribo.c" + "${_pc_mmgr_src}/numeros_scribo/numeros_scribo.c") + target_include_directories(pc_mmgr PUBLIC + "${CMAKE_CURRENT_SOURCE_DIR}/MMgr/include" + "${CMAKE_CURRENT_SOURCE_DIR}/MMgr/src" + "${CMAKE_CURRENT_SOURCE_DIR}/embedded_types/include") + target_compile_definitions(pc_mmgr PUBLIC MMGR_ENABLE_DMA=0 MMGR_ENABLE_EXTRAM=0) endif() diff --git a/include/embedded_types b/include/embedded_types new file mode 160000 index 000000000..b0aacdaaf --- /dev/null +++ b/include/embedded_types @@ -0,0 +1 @@ +Subproject commit b0aacdaafd986b8c5b23f127f312a02a5cfd13e6 diff --git a/include/protocore.h b/include/protocore.h index 0455c275c..d8c8f3354 100644 --- a/include/protocore.h +++ b/include/protocore.h @@ -127,12 +127,7 @@ typedef struct WebServerConfig // protocore.h is the one header an application includes, so every service the library offers is // reachable from it. A feature the build did not enable costs nothing: each service header carries // its own PROTOCORE_ENABLE_ guard, so a disabled one contributes no declarations and no code. -#include "mmgr/arena/arena.h" -#include "mmgr/dma/dma.h" -#include "mmgr/plaintext/plaintext.h" -#include "mmgr/psram_pool/psram_pool.h" -#include "mmgr/secure/secure.h" -#include "mmgr/span/span.h" +#include "locus_carcerum/locus_carcerum.h" #include "network_drivers/application/file_serving/file_serving.h" #include "network_drivers/application/http_range/http_range.h" #include "network_drivers/application/mdns_adaptive/mdns_adaptive.h" diff --git a/sonar-project.properties b/sonar-project.properties index 673bc95ce..0e0661c6c 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -48,6 +48,7 @@ sonar.cfamily.compile-commands=compile_commands.json # measures a subset of src/ and leaves it alone. sonar.coverageReportPaths=test/coverage.xml + # Generated string-literal asset headers and the web wizard are not hand-written. sonar.exclusions=src/network_drivers/application/web_assets.*,src/network_drivers/application/binary_asset_blobs.*,src/web_assets/** @@ -65,21 +66,24 @@ sonar.cpd.exclusions=core_setup/board_profiles/** # --------------------------------------------------------------------------- sonar.issue.ignore.multicriteria=carr,gmut,fptr,cmac,wbnd,hdr,mpar,vptr,rfor,rtyp,dstruct,jstr,aesctx,tdef,mord,sizeu,vlog,cfginc,ntrdecl,ntrloop,ntrjump,ntrnest,ntrcplx,ntrasgn +# The rule keys below are c:, not cpp:. src/ is C, and the analyzer files its findings under the c: +# repository, so a cpp: key suppresses nothing. + # S5945 "use std::array/std::vector instead of a C-style array": this is a no-heap, # no-stdlib, deterministic embedded library (see docs; /STL containers are # banned in src/). Fixed C arrays + static pools ARE the design. -sonar.issue.ignore.multicriteria.carr.ruleKey=cpp:S5945 +sonar.issue.ignore.multicriteria.carr.ruleKey=c:S5945 sonar.issue.ignore.multicriteria.carr.resourceKey=**/* # S5421 "global variables should be const": the owner-context architecture keeps each # subsystem's mutable state in ONE named, internal-linkage owned Ctx instance # (enforced by tools/ci_tooling/check/check_owned_context.py). Those owners are mutable by design. -sonar.issue.ignore.multicriteria.gmut.ruleKey=cpp:S5421 +sonar.issue.ignore.multicriteria.gmut.ruleKey=c:S5421 sonar.issue.ignore.multicriteria.gmut.resourceKey=**/* # S5205 "replace this function pointer with a template parameter or std::function": # std::function allocates; callbacks here are plain C function pointers by design. -sonar.issue.ignore.multicriteria.fptr.ruleKey=cpp:S5205 +sonar.issue.ignore.multicriteria.fptr.ruleKey=c:S5205 sonar.issue.ignore.multicriteria.fptr.resourceKey=**/* # S5028 "replace this macro by const/constexpr/enum": named object-like #define constants @@ -90,47 +94,47 @@ sonar.issue.ignore.multicriteria.fptr.resourceKey=**/* # zero-overhead, header-only, usable in array bounds and switch labels. S5028 flags all of # them without distinguishing an anonymous magic number, so it does not fit this codebase; # suppressed project-wide like the other embedded-convention rules above (S5945/S5421/S5205). -sonar.issue.ignore.multicriteria.cmac.ruleKey=cpp:S5028 +sonar.issue.ignore.multicriteria.cmac.ruleKey=c:S5028 sonar.issue.ignore.multicriteria.cmac.resourceKey=**/* # S3519 "memory copy overflows the destination buffer": FALSE POSITIVE on the bounded # Writer in tls13_msg.cpp - every memcpy is guarded by pos<=cap && n<=cap-pos (no # underflow, no pos+n wrap), but buf/cap are separate params so the analyzer cannot # prove buf has cap bytes. Scoped to that one file (its writer is entirely this pattern). -sonar.issue.ignore.multicriteria.wbnd.ruleKey=cpp:S3519 +sonar.issue.ignore.multicriteria.wbnd.ruleKey=c:S3519 sonar.issue.ignore.multicriteria.wbnd.resourceKey=**/tls13_msg.c # S125 "remove this commented-out code": FALSE POSITIVE on the protocore_config.h section # headers ("// -- Name (services/x) --") - the parens/slashes trip the commented-code # heuristic. They are documentation that organizes 100+ config macros, not dead code. -sonar.issue.ignore.multicriteria.hdr.ruleKey=cpp:S125 +sonar.issue.ignore.multicriteria.hdr.ruleKey=c:S125 sonar.issue.ignore.multicriteria.hdr.resourceKey=**/protocore_config.h # S107 "function has too many parameters": the flat wire codecs (mqtt_build_publish, # coap/dns/snmp build+parse, ...) take the message fields as positional args by design - a # no-heap deterministic library avoids per-call option structs. Same flat-C-API stance as the # S5205 function-pointers above; a codec taking 8-9 wire fields is correct, not a smell. -sonar.issue.ignore.multicriteria.mpar.ruleKey=cpp:S107 +sonar.issue.ignore.multicriteria.mpar.ruleKey=c:S107 sonar.issue.ignore.multicriteria.mpar.resourceKey=**/* # S5008 "replace this void* with a meaningful type": the callback seams pass an opaque # `void *ctx` (smtp/coap/dns send-recv, resource handlers, ...) - a plain-C callback design # (cf. S5205), where a typed context would force templates/std::function, both banned here (no # allocation, C ABI). The void* IS the interface. -sonar.issue.ignore.multicriteria.vptr.ruleKey=cpp:S5008 +sonar.issue.ignore.multicriteria.vptr.ruleKey=c:S5008 sonar.issue.ignore.multicriteria.vptr.resourceKey=**/* # S5566 "change this raw for-loop to a range-for": this C-leaning library uses explicit # index-based loops uniformly (zero range-for across src/). Over a fixed C array range-for is # identical codegen (no performance gain), and adopting it for only the subset the analyzer # recognizes would fragment the deliberate style. Index loops ARE the design. -sonar.issue.ignore.multicriteria.rfor.ruleKey=cpp:S5566 +sonar.issue.ignore.multicriteria.rfor.ruleKey=c:S5566 sonar.issue.ignore.multicriteria.rfor.resourceKey=**/* # S5827 "replace the redundant type with auto": the `auto` keyword is banned in src/ - every # type is spelled out explicitly (same explicit-C stance as the index loops above). This rule's # only fix is to introduce `auto`, which the library's style forbids. -sonar.issue.ignore.multicriteria.rtyp.ruleKey=cpp:S5827 +sonar.issue.ignore.multicriteria.rtyp.ruleKey=c:S5827 sonar.issue.ignore.multicriteria.rtyp.resourceKey=**/* # S1820 "refactor this structure to have fewer than 20 fields": DtlsConn is the single owned @@ -138,14 +142,14 @@ sonar.issue.ignore.multicriteria.rtyp.resourceKey=**/* # epoch, CID, PTO timers, transcript hash, peer address). A flat no-heap connection struct - all # state in one named owner - IS the owner-context design (tools/ci_tooling/check/check_owned_context.py); splitting # it into sub-structs would ripple through every c->field access for no design gain. Scoped to it. -sonar.issue.ignore.multicriteria.dstruct.ruleKey=cpp:S1820 +sonar.issue.ignore.multicriteria.dstruct.ruleKey=c:S1820 sonar.issue.ignore.multicriteria.dstruct.resourceKey=**/dtls_conn.h # S3628 "convert this string literal to a raw string literal": escaped-quote JSON string literals # ("{\"name\":\"") are the uniform style across src/ (196 instances, zero raw strings). Adopting # R"(...)" for only the subset the analyzer flags would fragment the style for no gain; the escaped # form IS the design (same explicit stance as the index loops / no-auto above). -sonar.issue.ignore.multicriteria.jstr.ruleKey=cpp:S3628 +sonar.issue.ignore.multicriteria.jstr.ruleKey=c:S3628 sonar.issue.ignore.multicriteria.jstr.resourceKey=**/* # S5416 "using should be preferred to typedef": src/ has 89 typedefs and 76 of them are C @@ -154,7 +158,7 @@ sonar.issue.ignore.multicriteria.jstr.resourceKey=**/* # the same plain-C stance already documented for S5205 (function pointers) and S5008 (void* context). # The analyzer only sees the subset of files in the merged compile database, so it flags 12 of the 89 - # converting exactly those would fragment one uniform convention into two for no gain. -sonar.issue.ignore.multicriteria.tdef.ruleKey=cpp:S5416 +sonar.issue.ignore.multicriteria.tdef.ruleKey=c:S5416 sonar.issue.ignore.multicriteria.tdef.resourceKey=**/* # S8417 "use memory_order_seq_cst": the lock-free seams (tcp.cpp conn free-slot bitmask, worker.cpp run @@ -162,7 +166,7 @@ sonar.issue.ignore.multicriteria.tdef.resourceKey=**/* # acquire load pairs with the release store that publishes a cleaned slot, and the observability counters # are relaxed because they are statistics, not synchronization. Forcing seq_cst would put a full barrier # on the per-accept hot path this replaced a linear scan to speed up (measured 20 vs 71 cyc on the S3). -sonar.issue.ignore.multicriteria.mord.ruleKey=cpp:S8417 +sonar.issue.ignore.multicriteria.mord.ruleKey=c:S8417 sonar.issue.ignore.multicriteria.mord.resourceKey=**/* # S959 "put this #undef in the file where the macro is defined": board_drivers/board_profiles/derived_sizing.h exists @@ -170,13 +174,13 @@ sonar.issue.ignore.multicriteria.mord.resourceKey=**/* # lifting RX_BUF_SIZE to hold a full TCP window when streaming is compiled in, and so on. #undef + #define # is the only preprocessor mechanism for that, and doing it in the defining file is impossible: the floor # depends on which PROTOCORE_ENABLE_* features are on, which is not known until every default has been seen. -sonar.issue.ignore.multicriteria.sizeu.ruleKey=cpp:S959 +sonar.issue.ignore.multicriteria.sizeu.ruleKey=c:S959 sonar.issue.ignore.multicriteria.sizeu.resourceKey=**/derived_sizing.h # S923 "remove use of ellipsis notation": protocore_log_printf is the library's printf-style logging entry point. # A format-string logger has to take varargs and forward them to vsnprintf; there is no variadic-template # alternative here (templates would instantiate per call site in a no-heap, size-constrained library). -sonar.issue.ignore.multicriteria.vlog.ruleKey=cpp:S923 +sonar.issue.ignore.multicriteria.vlog.ruleKey=c:S923 sonar.issue.ignore.multicriteria.vlog.resourceKey=**/log.c # S954 "move this #include to the top of the file": protocore_config.h includes board_drivers/board_profiles/derived_sizing.h @@ -184,7 +188,7 @@ sonar.issue.ignore.multicriteria.vlog.resourceKey=**/log.c # feature flag and every default in this file has been defined. Moving it to the top inverts that and the # floors silently evaluate against undefined macros. Scoped to protocore_config.h; genuine mid-file includes # elsewhere are fixed, not waived. -sonar.issue.ignore.multicriteria.cfginc.ruleKey=cpp:S954 +sonar.issue.ignore.multicriteria.cfginc.ruleKey=c:S954 sonar.issue.ignore.multicriteria.cfginc.resourceKey=**/protocore_config.h # --------------------------------------------------------------------------- @@ -204,17 +208,17 @@ sonar.issue.ignore.multicriteria.cfginc.resourceKey=**/protocore_config.h # House style elsewhere is decisively one-declaration-per-line (6369 single vs 198 multi across # src/, 97%), so this is a carve-out for vendored code, NOT a relaxation of the convention. # --------------------------------------------------------------------------- -sonar.issue.ignore.multicriteria.ntrdecl.ruleKey=cpp:S1659 +sonar.issue.ignore.multicriteria.ntrdecl.ruleKey=c:S1659 sonar.issue.ignore.multicriteria.ntrdecl.resourceKey=**/sntrup761.c -sonar.issue.ignore.multicriteria.ntrloop.ruleKey=cpp:S5955 +sonar.issue.ignore.multicriteria.ntrloop.ruleKey=c:S5955 sonar.issue.ignore.multicriteria.ntrloop.resourceKey=**/sntrup761.c -sonar.issue.ignore.multicriteria.ntrjump.ruleKey=cpp:S924 +sonar.issue.ignore.multicriteria.ntrjump.ruleKey=c:S924 sonar.issue.ignore.multicriteria.ntrjump.resourceKey=**/sntrup761.c -sonar.issue.ignore.multicriteria.ntrnest.ruleKey=cpp:S134 +sonar.issue.ignore.multicriteria.ntrnest.ruleKey=c:S134 sonar.issue.ignore.multicriteria.ntrnest.resourceKey=**/sntrup761.c -sonar.issue.ignore.multicriteria.ntrcplx.ruleKey=cpp:S3776 +sonar.issue.ignore.multicriteria.ntrcplx.ruleKey=c:S3776 sonar.issue.ignore.multicriteria.ntrcplx.resourceKey=**/sntrup761.c -sonar.issue.ignore.multicriteria.ntrasgn.ruleKey=cpp:S1121 +sonar.issue.ignore.multicriteria.ntrasgn.ruleKey=c:S1121 sonar.issue.ignore.multicriteria.ntrasgn.resourceKey=**/sntrup761.c # S995 in ssh_aesgcm.cpp: aes256_ecb and the GCM helpers (gctr/gcm_core) take a non-const @@ -222,5 +226,5 @@ sonar.issue.ignore.multicriteria.ntrasgn.resourceKey=**/sntrup761.c # mbedtls_aes_context is non-const, so const-propagating the ctx compiles on the native software-AES # path but breaks the mbedtls path (dual-core build). Sonar only sees the native side; the pointer # must stay non-const for portability. -sonar.issue.ignore.multicriteria.aesctx.ruleKey=cpp:S995 +sonar.issue.ignore.multicriteria.aesctx.ruleKey=c:S995 sonar.issue.ignore.multicriteria.aesctx.resourceKey=**/ssh_aesgcm.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 45e651203..ddeb3c30b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,7 +51,6 @@ function(protocore_header_module name) endfunction() add_subdirectory(crypto) -add_subdirectory(mmgr) add_subdirectory(network_drivers) add_subdirectory(protocore) add_subdirectory(server) diff --git a/src/config/memory_sizing/buffer_sizing.h b/src/config/memory_sizing/buffer_sizing.h index c3bdb37e8..e5474f82c 100644 --- a/src/config/memory_sizing/buffer_sizing.h +++ b/src/config/memory_sizing/buffer_sizing.h @@ -4003,7 +4003,7 @@ // significant barrier against heap/BSS spray attacks. // - The DH ephemeral private scalar y lives in ssh_dh[].y and is zeroed // immediately after the shared secret K is derived. -// - crypto_work[] is zeroed via protocore_secure_wipe() after every use so that +// - crypto_work[] is zeroed via mmgr_zero_buf() after every use so that // bignum intermediates (including partial products that contain key // material) do not persist in memory. diff --git a/src/config/platform/types.h b/src/config/platform/types.h index 10559735d..4eb026605 100644 --- a/src/config/platform/types.h +++ b/src/config/platform/types.h @@ -67,6 +67,19 @@ typedef _Bool proto_bool; #define PROTO_TRUE ((proto_bool)1) ///< the true value, spelled so a caller never writes a bare 1 #define PROTO_FALSE ((proto_bool)0) ///< the false value +/** + * @brief Cross-thread access to a ProtoCore field declared `_Atomic`: a slot state, a run flag. + * + * Every read is an acquire load and every write a release store, so the ordering is stated at each + * access rather than left to the default. MMgr keeps its ring atomics inside memoria_anularis and + * exposes none, so the fields ProtoCore owns itself are reached through these two. + * + * `atomic_load_explicit` and `atomic_store_explicit` are ``, which a file using these + * includes itself: this header also reaches C++ sketches, where that header is not C11's. + */ +#define PROTO_ATOMIC_LOAD(p) atomic_load_explicit((p), memory_order_acquire) +#define PROTO_ATOMIC_STORE(p, v) atomic_store_explicit((p), (v), memory_order_release) ///< release store of @p v + /** * @brief Give a header's declarations C linkage, so their symbol names carry no parameter types. * diff --git a/src/crypto/aead/chachapoly/chachapoly.c b/src/crypto/aead/chachapoly/chachapoly.c index acdaac8d4..a9e5a7ad4 100644 --- a/src/crypto/aead/chachapoly/chachapoly.c +++ b/src/crypto/aead/chachapoly/chachapoly.c @@ -43,8 +43,8 @@ static_assert(CHACHAPOLY_OFF_POLY + PROTOCORE_POLY1305_BORROW <= PROTOCORE_CHACH "PROTOCORE_CHACHAPOLY_BORROW is short of the per-packet working set and the two nested " "borrows - raise it in protocore_config.h, which derives PROTOCORE_SECURE_ARENA_SIZE from it"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert( diff --git a/src/crypto/asymmetric/bignum/CMakeLists.txt b/src/crypto/asymmetric/bignum/CMakeLists.txt index bd57901fa..5236c14ea 100644 --- a/src/crypto/asymmetric/bignum/CMakeLists.txt +++ b/src/crypto/asymmetric/bignum/CMakeLists.txt @@ -6,5 +6,5 @@ protocore_add_module(crypto/asymmetric/bignum OPT 2 SOURCES bignum.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/crypto/asymmetric/bignum/bignum.c b/src/crypto/asymmetric/bignum/bignum.c index 43cb0b610..33b8388b0 100644 --- a/src/crypto/asymmetric/bignum/bignum.c +++ b/src/crypto/asymmetric/bignum/bignum.c @@ -17,7 +17,7 @@ #if PROTOCORE_ENABLE_BIGNUM #include "crypto/asymmetric/bignum/bignum.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" PROTOCORE_BEGIN_DECLS @@ -46,8 +46,8 @@ static_assert(BIGNUM_OFF_PM1 + sizeof(protocore_bignum) <= PROTOCORE_BIGNUM_BORR "PROTOCORE_BIGNUM_BORROW is short of the staged operands and p-1 - raise it in " "protocore_config.h, which sums it into the secure arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(BIGNUM_OFF_PM1 % _Alignof(protocore_bignum) == 0, @@ -130,7 +130,7 @@ void protocore_bignum_from_bytes(uint8_t *work) const uint8_t *bytes = BignumV.from_bytes_args.bytes; const size_t len = BignumV.from_bytes_args.len; - mem.set(out->d, 0, sizeof(protocore_bignum)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out->d, .val = 0, .bytes = sizeof(protocore_bignum)); // bytes are big-endian; map to little-endian limbs. size_t blen = len < 256 ? len : 256; for (size_t i = 0; i < blen; i++) diff --git a/src/crypto/asymmetric/rsa/CMakeLists.txt b/src/crypto/asymmetric/rsa/CMakeLists.txt index 8e25cd3c2..6c9c72632 100644 --- a/src/crypto/asymmetric/rsa/CMakeLists.txt +++ b/src/crypto/asymmetric/rsa/CMakeLists.txt @@ -10,5 +10,5 @@ protocore_add_module(crypto/asymmetric/rsa crypto/ct_eq crypto/hash/sha256 crypto/hash/sha512 - mmgr/protomem + mmgr ) diff --git a/src/crypto/asymmetric/rsa/rsa.c b/src/crypto/asymmetric/rsa/rsa.c index c403b7237..686f44706 100644 --- a/src/crypto/asymmetric/rsa/rsa.c +++ b/src/crypto/asymmetric/rsa/rsa.c @@ -24,7 +24,7 @@ #include "crypto/ct_eq/ct_eq.h" // protocore_ct_eq #include "crypto/hash/sha256/sha256.h" #include "crypto/hash/sha512/sha512.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" PROTOCORE_BEGIN_DECLS @@ -66,8 +66,8 @@ static_assert(RSA_OFF_CTX + sizeof(RsaCtx) <= PROTOCORE_RSA_BORROW, "PROTOCORE_RSA_BORROW is short of the two digest regions, the bignum region and the ladder's " "working set - raise it in protocore_config.h, which derives PROTOCORE_SECURE_ARENA_SIZE from it"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(RSA_OFF_CTX % _Alignof(RsaCtx) == 0, @@ -129,7 +129,7 @@ static void rsa_mont(uint8_t *work) ctx->mprime = 0u - inv; uint32_t *t = ctx->rr.d; - mem.zero(t, sizeof(ctx->rr.d)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = t, .val = 0, .bytes = sizeof(ctx->rr.d)); t[0] = 1u; for (int i = 0; i < 2 * PROTOCORE_BN_LIMBS * 32; i++) { @@ -275,7 +275,7 @@ static void rsa_modexp(uint8_t *work) { RsaCtx *ctx = RSA_CTX(work); - mem.zero(ctx->acc.d, sizeof(ctx->acc.d)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = ctx->acc.d, .val = 0, .bytes = sizeof(ctx->acc.d)); ctx->acc.d[0] = 1u; int top_limb = PROTOCORE_BN_LIMBS - 1; @@ -344,10 +344,10 @@ static void rsa_encode(uint8_t *work) const size_t pad_len = PROTOCORE_RSA_KEY_BYTES - 3u - di_len - digest_len; ctx->em[0] = 0x00; ctx->em[1] = 0x01; - mem.set(ctx->em + 2, 0xFF, pad_len); + EMBED_CALL(memor.set, MemoriaCfg, .dst = ctx->em + 2, .val = 0xFF, .bytes = pad_len); ctx->em[2 + pad_len] = 0x00; - mem.cpy(ctx->em + 3 + pad_len, di, di_len); - mem.cpy(ctx->em + 3 + pad_len + di_len, ctx->digest, digest_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = ctx->em + 3 + pad_len, .src = di, .bytes = di_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = ctx->em + 3 + pad_len + di_len, .src = ctx->digest, .bytes = digest_len); } // RFC 8017 sec B.2.1: the mask generation function PSS masks its data block with. Hash(seed || @@ -356,7 +356,7 @@ static void mgf1_sha256(uint8_t *work, const uint8_t *seed, size_t seed_len, uin { uint8_t buf[PROTOCORE_SHA256_DIGEST_LEN + 4u]; uint8_t block[PROTOCORE_SHA256_DIGEST_LEN]; - mem.cpy(buf, seed, seed_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf, .src = seed, .bytes = seed_len); uint32_t counter = 0; for (size_t off = 0; off < mask_len; counter++) { @@ -367,7 +367,7 @@ static void mgf1_sha256(uint8_t *work, const uint8_t *seed, size_t seed_len, uin Sha256.hash(RSA_SHA256(work), buf, seed_len + 4u, block); const size_t left = mask_len - off; const size_t n = left < PROTOCORE_SHA256_DIGEST_LEN ? left : (size_t)PROTOCORE_SHA256_DIGEST_LEN; - mem.cpy(mask + off, block, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = mask + off, .src = block, .bytes = n); off += n; } } @@ -425,9 +425,9 @@ static proto_bool rsa_pss_consistent(uint8_t *work) // steps 11, 12 and 13: M' is eight zero octets, the message digest, then the recovered salt. uint8_t mprime[8u + PROTOCORE_SHA256_DIGEST_LEN + PROTOCORE_SHA256_DIGEST_LEN]; uint8_t hprime[PROTOCORE_SHA256_DIGEST_LEN]; - mem.set(mprime, 0, 8u); - mem.cpy(mprime + 8u, ctx->digest, hlen); - mem.cpy(mprime + 8u + hlen, db + ps + 1u, slen); + EMBED_CALL(memor.set, MemoriaCfg, .dst = mprime, .val = 0, .bytes = 8u); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = mprime + 8u, .src = ctx->digest, .bytes = hlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = mprime + 8u + hlen, .src = db + ps + 1u, .bytes = slen); Sha256.hash(RSA_SHA256(work), mprime, sizeof(mprime), hprime); // step 14 diff --git a/src/crypto/cipher/aes_block/CMakeLists.txt b/src/crypto/cipher/aes_block/CMakeLists.txt index c724cb724..b011d5a13 100644 --- a/src/crypto/cipher/aes_block/CMakeLists.txt +++ b/src/crypto/cipher/aes_block/CMakeLists.txt @@ -7,6 +7,6 @@ protocore_add_module(crypto/cipher/aes_block SOURCES aes_block.c DEPS crypto/cipher/aes_sbox - mmgr/protomem + mmgr PRIVATE_DEPS ) diff --git a/src/crypto/cipher/aes_block/aes_block.h b/src/crypto/cipher/aes_block/aes_block.h index 91af3ac81..defeba069 100644 --- a/src/crypto/cipher/aes_block/aes_block.h +++ b/src/crypto/cipher/aes_block/aes_block.h @@ -5,7 +5,7 @@ #define PROTOCORE_AES_BLOCK_H #include "crypto/cipher/aes_sbox/aes_sbox.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "protocore_config.h" // the entry point: protocore_types.h for the widths PROTOCORE_BEGIN_DECLS @@ -169,7 +169,7 @@ PROTOCORE_INLINE void protocore_aes_encrypt_block(const uint32_t *rk, int nr, co s[i] ^= (uint8_t)(rk[nr * 4 + i / 4] >> (24 - (i % 4) * 8)); } - mem.cpy(out, s, 16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = s, .bytes = 16); } /** @brief Dispatch table. Addressed by offset, so the layout is asserted below. */ diff --git a/src/crypto/cipher/chacha20/chacha20.c b/src/crypto/cipher/chacha20/chacha20.c index 29f10f7fe..2ad9bbb1e 100644 --- a/src/crypto/cipher/chacha20/chacha20.c +++ b/src/crypto/cipher/chacha20/chacha20.c @@ -34,8 +34,8 @@ static_assert(CHACHA20_OFF_KS + PROTOCORE_CHACHA20_BLOCK_LEN <= PROTOCORE_CHACHA "PROTOCORE_CHACHA20_BORROW is short of the state and the keystream block - raise it in " "protocore_config.h, which derives PROTOCORE_SECURE_ARENA_SIZE from it"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(CHACHA20_OFF_CTX % _Alignof(Chacha20Ctx) == 0, diff --git a/src/crypto/ct_eq/CMakeLists.txt b/src/crypto/ct_eq/CMakeLists.txt index 837a6777e..0743a289c 100644 --- a/src/crypto/ct_eq/CMakeLists.txt +++ b/src/crypto/ct_eq/CMakeLists.txt @@ -6,6 +6,6 @@ protocore_add_module(crypto/ct_eq OPT 2 SOURCES ct_eq.c DEPS - mmgr/protomem + mmgr PRIVATE_DEPS ) diff --git a/src/crypto/ct_eq/ct_eq.h b/src/crypto/ct_eq/ct_eq.h index 263ef9480..e3d015ad6 100644 --- a/src/crypto/ct_eq/ct_eq.h +++ b/src/crypto/ct_eq/ct_eq.h @@ -9,8 +9,8 @@ * way. A second copy is a second chance to write the early-out version by accident, and an early-out * compare is a timing oracle no test catches. * - * Zeroing storage is not here: protocore_secure_wipe() is a memory-manager operation and lives in - * mmgr/secure.h, beside the pool that wipes on release. + * Zeroing storage is not here: mmgr_zero_buf() is a memory-manager operation and lives in + * locus_carcerum/locus_carcerum.h, beside the cellblock that zeroes on release. * * The compare is `static inline` here, so it inlines into the caller's loop. ::CtEq is the same * compare reached through the namespace, with the operands on the handle. @@ -26,7 +26,7 @@ #if PROTOCORE_ENABLE_CT_EQ -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" PROTOCORE_BEGIN_DECLS @@ -35,7 +35,7 @@ PROTOCORE_BEGIN_DECLS * independent of where (or whether) they first differ. * * Use this for every secret-dependent comparison - AEAD tags, MACs, digests, signature check values - so a - * timing side channel cannot reveal how many leading bytes matched. Never use mem.cmp() for those (it returns + * timing side channel cannot reveal how many leading bytes matched. Never use memor.cmp() for those (it returns * early on the first mismatch). The XOR-accumulate has no data-dependent branch; only the final all-zero test * (the intended result) is a comparison. */ diff --git a/src/crypto/hash/md/CMakeLists.txt b/src/crypto/hash/md/CMakeLists.txt index b9fc5234c..c9d969696 100644 --- a/src/crypto/hash/md/CMakeLists.txt +++ b/src/crypto/hash/md/CMakeLists.txt @@ -6,7 +6,5 @@ protocore_add_module(crypto/hash/md OPT 2 SOURCES md.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem - mmgr/secure + mmgr ) diff --git a/src/crypto/hash/md/md.c b/src/crypto/hash/md/md.c index 0673c3a33..d11185acf 100644 --- a/src/crypto/hash/md/md.c +++ b/src/crypto/hash/md/md.c @@ -11,9 +11,8 @@ #if PROTOCORE_ENABLE_MD #include "crypto/hash/md/md.h" -#include "mmgr/endian/endian.h" -#include "mmgr/protomem/protomem.h" -#include "mmgr/secure/secure.h" // the secure pool: digest state, wiped on release +#include "endian/endian.h" +#include "memoria_operor/memoria_operor.h" PROTOCORE_BEGIN_DECLS @@ -68,7 +67,7 @@ static void protocore_md5_compress(uint32_t s[4], const uint8_t block[64]) uint32_t m[16]; for (int i = 0; i < 16; i++) { - m[i] = protocore_rd32le(block + i * 4); + m[i] = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = block + i * 4, .width = MMGR_ENDIAN_32); } uint32_t a = s[0]; uint32_t b = s[1]; @@ -127,7 +126,7 @@ static void protocore_md4_compress(uint32_t s[4], const uint8_t block[64]) uint32_t x[16]; for (int i = 0; i < 16; i++) { - x[i] = protocore_rd32le(block + i * 4); + x[i] = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = block + i * 4, .width = MMGR_ENDIAN_32); } uint32_t a = s[0]; uint32_t b = s[1]; @@ -223,7 +222,7 @@ static void md_absorb(struct MdCtx *c, const uint8_t *data, size_t len, md_compr { take = (uint32_t)len; } - mem.cpy(c->buf + c->buf_len, data, take); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = c->buf + c->buf_len, .src = data, .bytes = take); c->buf_len += take; data += take; len -= take; @@ -253,7 +252,7 @@ static void md_finish(struct MdCtx *c, uint8_t out[16], md_compress_fn compress) md_absorb(c, lenbuf, 8, compress); // triggers the final compress for (int i = 0; i < 4; i++) { - protocore_wr32le(out + i * 4, c->state[i]); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + i * 4, .val = c->state[i], .width = MMGR_ENDIAN_32); } } @@ -357,7 +356,7 @@ void protocore_md_hmac_md5(uint8_t *work) uint8_t *inner = MD_INNER(work); struct MdCtx *c = MD_STATE(work); - mem.set(k, 0, 64); + EMBED_CALL(memor.set, MemoriaCfg, .dst = k, .val = 0, .bytes = 64); if (key_len > 64) { // Keys longer than the block are hashed down, leaving 16 bytes and the rest zero. Its state is @@ -369,7 +368,7 @@ void protocore_md_hmac_md5(uint8_t *work) } else { - mem.cpy(k, key, key_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = k, .src = key, .bytes = key_len); } for (int i = 0; i < 64; i++) diff --git a/src/crypto/hash/sha1/CMakeLists.txt b/src/crypto/hash/sha1/CMakeLists.txt index db782671f..a2f619e1b 100644 --- a/src/crypto/hash/sha1/CMakeLists.txt +++ b/src/crypto/hash/sha1/CMakeLists.txt @@ -6,6 +6,5 @@ protocore_add_module(crypto/hash/sha1 OPT 2 SOURCES sha1.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/crypto/hash/sha1/sha1.c b/src/crypto/hash/sha1/sha1.c index c225629a3..654cf26b6 100644 --- a/src/crypto/hash/sha1/sha1.c +++ b/src/crypto/hash/sha1/sha1.c @@ -17,8 +17,8 @@ #if PROTOCORE_HAS_HW_SHA #endif #include "crypto/hash/sha1/sha1.h" -#include "mmgr/endian/endian.h" // the big-endian serializers the framing and the rounds step with -#include "mmgr/protomem/protomem.h" +#include "endian/endian.h" // the big-endian serializers the framing and the rounds step with +#include "memoria_operor/memoria_operor.h" // The one definition of Sha1Ctx - private to this TU. It sits at SHA1_OFF_CTX in the caller's borrow, // so its size never leaves this file and no consumer can name it. @@ -67,7 +67,7 @@ static void sha1_block(uint32_t h[5], const uint8_t block[64]) uint32_t w[80]; for (int i = 0; i < 16; i++) { - w[i] = protocore_rd32be(block + i * 4); + w[i] = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = block + i * 4, .width = MMGR_ENDIAN_32); } for (int i = 16; i < 80; i++) { @@ -146,9 +146,9 @@ static void sha1_run(uint8_t *work, const uint8_t *data, size_t len, uint8_t dig } // Build the padded final block(s) - mem.set(pad, 0, 128); + EMBED_CALL(memor.set, MemoriaCfg, .dst = pad, .val = 0, .bytes = 128); size_t tail = len - blocks * 64; - mem.cpy(pad, data + blocks * 64, tail); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = pad, .src = data + blocks * 64, .bytes = tail); pad[tail] = 0x80; // Bit-length goes in the last 8 bytes of the final block @@ -167,7 +167,7 @@ static void sha1_run(uint8_t *work, const uint8_t *data, size_t len, uint8_t dig for (int i = 0; i < 5; i++) { - protocore_wr32be(digest + i * 4, h[i]); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + i * 4, .val = h[i], .width = MMGR_ENDIAN_32); } } diff --git a/src/crypto/hash/sha256/CMakeLists.txt b/src/crypto/hash/sha256/CMakeLists.txt index 1c0bef517..56831e7f7 100644 --- a/src/crypto/hash/sha256/CMakeLists.txt +++ b/src/crypto/hash/sha256/CMakeLists.txt @@ -6,6 +6,5 @@ protocore_add_module(crypto/hash/sha256 OPT 2 SOURCES sha256.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/crypto/hash/sha256/sha256.c b/src/crypto/hash/sha256/sha256.c index 84156ce20..86b86829e 100644 --- a/src/crypto/hash/sha256/sha256.c +++ b/src/crypto/hash/sha256/sha256.c @@ -18,8 +18,9 @@ #if PROTOCORE_ENABLE_SHA256 #include "crypto/hash/sha256/sha256.h" -#include "mmgr/endian/endian.h" // the big-endian reads and writes both arms' padding and digest use -#include "mmgr/protomem/protomem.h" +#include "endian/endian.h" // the big-endian reads and writes both arms' padding and digest use +#include "memoria_operor/memoria_operor.h" // the state copy and the block fill +#include "proximus_operor/proximus_operor.h" // the unaligned block fill // The one definition, both arms, private to this TU. The accelerator compresses a block; it does not // pad, buffer a partial block, or hold a digest a caller can keep feeding. Those are this file's, so @@ -44,10 +45,10 @@ static_assert(SHA256_OFF_STATE + sizeof(uint32_t) * 8 <= PROTOCORE_SHA256_BORROW "PROTOCORE_SHA256_BORROW is short of the context, the two blocks and the state copy - " "raise it in protocore_config.h, which derives PROTOCORE_SECURE_ARENA_SIZE from it"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so - in arena.c's own words - a borrow is "met by aligning its offset -// alone". The offset is a compile-time constant, so that is a compile-time claim and it belongs -// here rather than in a runtime branch. Both sides are constants; nothing is checked at run time. +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. The offset is a +// compile-time constant, so that is a compile-time claim and it belongs here rather than in a runtime +// branch. Both sides are constants; nothing is checked at run time. // // The size assert above cannot stand in for these. It bounds the far end of the chain and says // nothing about where any region begins, so inserting one odd-sized region earlier leaves every @@ -143,22 +144,22 @@ static inline uint32_t sha256_ssig1(uint32_t x) // so no word is ever moved and the schedule stays sixteen words rather than sixty-four. static void sha256_block(uint32_t h[8], const uint8_t blk[PROTOCORE_SHA256_BLOCK_LEN]) { - uint32_t m0 = protocore_rd32be(blk); - uint32_t m1 = protocore_rd32be(blk + 4); - uint32_t m2 = protocore_rd32be(blk + 8); - uint32_t m3 = protocore_rd32be(blk + 12); - uint32_t m4 = protocore_rd32be(blk + 16); - uint32_t m5 = protocore_rd32be(blk + 20); - uint32_t m6 = protocore_rd32be(blk + 24); - uint32_t m7 = protocore_rd32be(blk + 28); - uint32_t m8 = protocore_rd32be(blk + 32); - uint32_t m9 = protocore_rd32be(blk + 36); - uint32_t m10 = protocore_rd32be(blk + 40); - uint32_t m11 = protocore_rd32be(blk + 44); - uint32_t m12 = protocore_rd32be(blk + 48); - uint32_t m13 = protocore_rd32be(blk + 52); - uint32_t m14 = protocore_rd32be(blk + 56); - uint32_t m15 = protocore_rd32be(blk + 60); + uint32_t m0 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk, .width = MMGR_ENDIAN_32); + uint32_t m1 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 4, .width = MMGR_ENDIAN_32); + uint32_t m2 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 8, .width = MMGR_ENDIAN_32); + uint32_t m3 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 12, .width = MMGR_ENDIAN_32); + uint32_t m4 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 16, .width = MMGR_ENDIAN_32); + uint32_t m5 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 20, .width = MMGR_ENDIAN_32); + uint32_t m6 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 24, .width = MMGR_ENDIAN_32); + uint32_t m7 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 28, .width = MMGR_ENDIAN_32); + uint32_t m8 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 32, .width = MMGR_ENDIAN_32); + uint32_t m9 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 36, .width = MMGR_ENDIAN_32); + uint32_t m10 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 40, .width = MMGR_ENDIAN_32); + uint32_t m11 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 44, .width = MMGR_ENDIAN_32); + uint32_t m12 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 48, .width = MMGR_ENDIAN_32); + uint32_t m13 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 52, .width = MMGR_ENDIAN_32); + uint32_t m14 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 56, .width = MMGR_ENDIAN_32); + uint32_t m15 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 60, .width = MMGR_ENDIAN_32); uint32_t v0 = h[0]; uint32_t v1 = h[1]; @@ -295,7 +296,7 @@ static void sha256_block(uint32_t h[8], const uint8_t blk[PROTOCORE_SHA256_BLOCK static void sha256_state_init(uint8_t *work) { Sha256Ctx *ctx = SHA256_CTX(work); - mem.cpy(ctx->s, H0, sizeof(H0)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = ctx->s, .src = H0, .bytes = sizeof(H0)); ctx->n = 0; ctx->rxlen = 0; } @@ -314,7 +315,7 @@ static void sha256_absorb(uint8_t *work, const uint8_t *data, size_t len) } // rx + rxlen carries no alignment, so this is the raw mover, not the aligned-span one. uint8_t *fill = rx + ctx->rxlen; - proto_raw_read(fill, data, take); + EMBED_CALL(proxim.read, ProximusCfg, .dst = fill, .at = data, .size = take); ctx->rxlen += take; data += take; len -= take; @@ -336,32 +337,32 @@ static void sha256_finish(uint8_t *work, uint8_t digest[PROTOCORE_SHA256_DIGEST_ // The padded blocks compress into a copy of the state, so s, rx, rxlen and n all come out of this // untouched and the hash can keep taking data afterwards. - mem.cpy(fs, ctx->s, sizeof(ctx->s)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = fs, .src = ctx->s, .bytes = sizeof(ctx->s)); // The last block is composed in tx, whole: what rx holds, the mark, zeros, and the length. rx is // read and never written back, so nothing it still carries from an earlier block reaches the wire. - mem.zero(tx, PROTOCORE_SHA256_BLOCK_LEN); - mem.cpy(tx, rx, ctx->rxlen); + EMBED_CALL(memor.set, MemoriaCfg, .dst = tx, .val = 0, .bytes = PROTOCORE_SHA256_BLOCK_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = tx, .src = rx, .bytes = ctx->rxlen); tx[ctx->rxlen] = 0x80; // The bit length occupies the block's last 8 bytes, so a mark at or past that offset takes its own. if (ctx->rxlen >= SHA256_LEN_OFF) { sha256_block(fs, tx); - mem.zero(tx, PROTOCORE_SHA256_BLOCK_LEN); + EMBED_CALL(memor.set, MemoriaCfg, .dst = tx, .val = 0, .bytes = PROTOCORE_SHA256_BLOCK_LEN); } - protocore_wr64be(tx + SHA256_LEN_OFF, bitlen); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = tx + SHA256_LEN_OFF, .val = bitlen, .width = MMGR_ENDIAN_64); sha256_block(fs, tx); - protocore_wr32be(digest, fs[0]); - protocore_wr32be(digest + 4, fs[1]); - protocore_wr32be(digest + 8, fs[2]); - protocore_wr32be(digest + 12, fs[3]); - protocore_wr32be(digest + 16, fs[4]); - protocore_wr32be(digest + 20, fs[5]); - protocore_wr32be(digest + 24, fs[6]); - protocore_wr32be(digest + 28, fs[7]); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest, .val = fs[0], .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 4, .val = fs[1], .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 8, .val = fs[2], .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 12, .val = fs[3], .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 16, .val = fs[4], .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 20, .val = fs[5], .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 24, .val = fs[6], .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 28, .val = fs[7], .width = MMGR_ENDIAN_32); } // --- the entries ----------------------------------------------------------- diff --git a/src/crypto/hash/sha3/sha3.c b/src/crypto/hash/sha3/sha3.c index b9cc696de..54b75747d 100644 --- a/src/crypto/hash/sha3/sha3.c +++ b/src/crypto/hash/sha3/sha3.c @@ -32,8 +32,8 @@ static_assert(SHA3_OFF_CTX + sizeof(struct KeccakCtx) <= PROTOCORE_SHA3_BORROW, "PROTOCORE_SHA3_BORROW is short of the sponge - raise it in protocore_config.h, " "which sums it into the secure arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(SHA3_OFF_CTX % _Alignof(KeccakCtx) == 0, diff --git a/src/crypto/hash/sha384/CMakeLists.txt b/src/crypto/hash/sha384/CMakeLists.txt index 3a866eff8..43752cd77 100644 --- a/src/crypto/hash/sha384/CMakeLists.txt +++ b/src/crypto/hash/sha384/CMakeLists.txt @@ -6,6 +6,5 @@ protocore_add_module(crypto/hash/sha384 OPT 2 SOURCES sha384.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/crypto/hash/sha384/sha384.c b/src/crypto/hash/sha384/sha384.c index 932a27e8a..fbdae621a 100644 --- a/src/crypto/hash/sha384/sha384.c +++ b/src/crypto/hash/sha384/sha384.c @@ -23,8 +23,9 @@ #if PROTOCORE_HAS_HW_SHA #endif #include "crypto/hash/sha384/sha384.h" -#include "mmgr/endian/endian.h" // protocore_rd64be / protocore_wr64be: the block reader and the digest writer -#include "mmgr/protomem/protomem.h" +#include "endian/endian.h" // magna_extremitas.rd / magna_extremitas.wr: the block reader and the digest writer +#include "memoria_operor/memoria_operor.h" +#include "proximus_operor/proximus_operor.h" // The one definition, both arms, private to this TU. The accelerator compresses a block; it does not // pad, buffer a partial block, or hold a digest a caller can keep feeding. Those are this file's, so @@ -49,8 +50,8 @@ static_assert(SHA384_OFF_STATE + sizeof(uint64_t) * 8 <= PROTOCORE_SHA384_BORROW "PROTOCORE_SHA384_BORROW is short of the context, the two blocks and the state copy - " "raise it in protocore_config.h, which derives PROTOCORE_SECURE_ARENA_SIZE from it"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(SHA384_OFF_CTX % _Alignof(Sha384Ctx) == 0, @@ -152,22 +153,22 @@ static inline uint64_t sha384_ssig1(uint64_t x) // and the schedule stays sixteen words rather than eighty. static void sha384_block(uint64_t h[8], const uint8_t blk[PROTOCORE_SHA384_BLOCK_LEN]) { - uint64_t m0 = protocore_rd64be(blk); - uint64_t m1 = protocore_rd64be(blk + 8); - uint64_t m2 = protocore_rd64be(blk + 16); - uint64_t m3 = protocore_rd64be(blk + 24); - uint64_t m4 = protocore_rd64be(blk + 32); - uint64_t m5 = protocore_rd64be(blk + 40); - uint64_t m6 = protocore_rd64be(blk + 48); - uint64_t m7 = protocore_rd64be(blk + 56); - uint64_t m8 = protocore_rd64be(blk + 64); - uint64_t m9 = protocore_rd64be(blk + 72); - uint64_t m10 = protocore_rd64be(blk + 80); - uint64_t m11 = protocore_rd64be(blk + 88); - uint64_t m12 = protocore_rd64be(blk + 96); - uint64_t m13 = protocore_rd64be(blk + 104); - uint64_t m14 = protocore_rd64be(blk + 112); - uint64_t m15 = protocore_rd64be(blk + 120); + uint64_t m0 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk, .width = MMGR_ENDIAN_64); + uint64_t m1 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 8, .width = MMGR_ENDIAN_64); + uint64_t m2 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 16, .width = MMGR_ENDIAN_64); + uint64_t m3 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 24, .width = MMGR_ENDIAN_64); + uint64_t m4 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 32, .width = MMGR_ENDIAN_64); + uint64_t m5 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 40, .width = MMGR_ENDIAN_64); + uint64_t m6 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 48, .width = MMGR_ENDIAN_64); + uint64_t m7 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 56, .width = MMGR_ENDIAN_64); + uint64_t m8 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 64, .width = MMGR_ENDIAN_64); + uint64_t m9 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 72, .width = MMGR_ENDIAN_64); + uint64_t m10 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 80, .width = MMGR_ENDIAN_64); + uint64_t m11 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 88, .width = MMGR_ENDIAN_64); + uint64_t m12 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 96, .width = MMGR_ENDIAN_64); + uint64_t m13 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 104, .width = MMGR_ENDIAN_64); + uint64_t m14 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 112, .width = MMGR_ENDIAN_64); + uint64_t m15 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 120, .width = MMGR_ENDIAN_64); uint64_t v0 = h[0]; uint64_t v1 = h[1]; @@ -326,7 +327,7 @@ static void sha384_absorb(uint8_t *work, const uint8_t *data, size_t len) } // rx + rxlen carries no alignment, so this is the raw mover, not the aligned-span one. uint8_t *fill = rx + ctx->rxlen; - proto_raw_read(fill, data, take); + EMBED_CALL(proxim.read, ProximusCfg, .dst = fill, .at = data, .size = take); ctx->rxlen += take; data += take; len -= take; @@ -352,12 +353,12 @@ static void sha384_finish(uint8_t *work, uint8_t digest[PROTOCORE_SHA384_DIGEST_ // The padded blocks compress into a copy of the state, so s, rx, rxlen and n all come out of this // untouched and the hash can keep taking data afterwards. - mem.cpy(fs, ctx->s, sizeof(ctx->s)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = fs, .src = ctx->s, .bytes = sizeof(ctx->s)); // The last block is composed in tx, whole: what rx holds, the mark, zeros, and the length. rx is // read and never written back, so nothing it still carries from an earlier block reaches the wire. - mem.zero(tx, PROTOCORE_SHA384_BLOCK_LEN); - mem.cpy(tx, rx, ctx->rxlen); + EMBED_CALL(memor.set, MemoriaCfg, .dst = tx, .val = 0, .bytes = PROTOCORE_SHA384_BLOCK_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = tx, .src = rx, .bytes = ctx->rxlen); tx[ctx->rxlen] = 0x80; // The 128-bit length occupies the block's last 16 bytes, so a mark at or past that offset takes @@ -365,21 +366,21 @@ static void sha384_finish(uint8_t *work, uint8_t digest[PROTOCORE_SHA384_DIGEST_ if (ctx->rxlen >= SHA384_LEN_OFF) { sha384_block(fs, tx); - mem.zero(tx, PROTOCORE_SHA384_BLOCK_LEN); + EMBED_CALL(memor.set, MemoriaCfg, .dst = tx, .val = 0, .bytes = PROTOCORE_SHA384_BLOCK_LEN); } - protocore_wr64be(tx + SHA384_LEN_OFF, len_hi); - protocore_wr64be(tx + SHA384_LEN_OFF + 8, len_lo); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = tx + SHA384_LEN_OFF, .val = len_hi, .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = tx + SHA384_LEN_OFF + 8, .val = len_lo, .width = MMGR_ENDIAN_64); sha384_block(fs, tx); // The digest is the first six of the eight state words (RFC 6234 sec 6.4); fs[6] and fs[7] stay in // the state copy and never reach the caller. - protocore_wr64be(digest, fs[0]); - protocore_wr64be(digest + 8, fs[1]); - protocore_wr64be(digest + 16, fs[2]); - protocore_wr64be(digest + 24, fs[3]); - protocore_wr64be(digest + 32, fs[4]); - protocore_wr64be(digest + 40, fs[5]); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest, .val = fs[0], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 8, .val = fs[1], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 16, .val = fs[2], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 24, .val = fs[3], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 32, .val = fs[4], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 40, .val = fs[5], .width = MMGR_ENDIAN_64); } // --- the entries ----------------------------------------------------------- diff --git a/src/crypto/hash/sha512/CMakeLists.txt b/src/crypto/hash/sha512/CMakeLists.txt index c0e21b074..79b288d64 100644 --- a/src/crypto/hash/sha512/CMakeLists.txt +++ b/src/crypto/hash/sha512/CMakeLists.txt @@ -6,6 +6,5 @@ protocore_add_module(crypto/hash/sha512 OPT 2 SOURCES sha512.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/crypto/hash/sha512/sha512.c b/src/crypto/hash/sha512/sha512.c index 8930dc2dd..6777a1524 100644 --- a/src/crypto/hash/sha512/sha512.c +++ b/src/crypto/hash/sha512/sha512.c @@ -20,8 +20,9 @@ #if PROTOCORE_HAS_HW_SHA #endif #include "crypto/hash/sha512/sha512.h" -#include "mmgr/endian/endian.h" // protocore_rd64be / protocore_wr64be: the block reader and the digest writer -#include "mmgr/protomem/protomem.h" +#include "endian/endian.h" // magna_extremitas.rd / magna_extremitas.wr: the block reader and the digest writer +#include "memoria_operor/memoria_operor.h" +#include "proximus_operor/proximus_operor.h" // The one definition, both arms, private to this TU. The accelerator compresses a block; it does not // pad, buffer a partial block, or hold a digest a caller can keep feeding. Those are this file's, so @@ -46,8 +47,8 @@ static_assert(SHA512_OFF_STATE + sizeof(uint64_t) * 8 <= PROTOCORE_SHA512_BORROW "PROTOCORE_SHA512_BORROW is short of the context, the two blocks and the state copy - " "raise it in protocore_config.h, which derives PROTOCORE_SECURE_ARENA_SIZE from it"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(SHA512_OFF_CTX % _Alignof(Sha512Ctx) == 0, @@ -146,22 +147,22 @@ static inline uint64_t sha512_ssig1(uint64_t x) // and the schedule stays sixteen words rather than eighty. static void sha512_block(uint64_t h[8], const uint8_t blk[PROTOCORE_SHA512_BLOCK_LEN]) { - uint64_t m0 = protocore_rd64be(blk); - uint64_t m1 = protocore_rd64be(blk + 8); - uint64_t m2 = protocore_rd64be(blk + 16); - uint64_t m3 = protocore_rd64be(blk + 24); - uint64_t m4 = protocore_rd64be(blk + 32); - uint64_t m5 = protocore_rd64be(blk + 40); - uint64_t m6 = protocore_rd64be(blk + 48); - uint64_t m7 = protocore_rd64be(blk + 56); - uint64_t m8 = protocore_rd64be(blk + 64); - uint64_t m9 = protocore_rd64be(blk + 72); - uint64_t m10 = protocore_rd64be(blk + 80); - uint64_t m11 = protocore_rd64be(blk + 88); - uint64_t m12 = protocore_rd64be(blk + 96); - uint64_t m13 = protocore_rd64be(blk + 104); - uint64_t m14 = protocore_rd64be(blk + 112); - uint64_t m15 = protocore_rd64be(blk + 120); + uint64_t m0 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk, .width = MMGR_ENDIAN_64); + uint64_t m1 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 8, .width = MMGR_ENDIAN_64); + uint64_t m2 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 16, .width = MMGR_ENDIAN_64); + uint64_t m3 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 24, .width = MMGR_ENDIAN_64); + uint64_t m4 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 32, .width = MMGR_ENDIAN_64); + uint64_t m5 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 40, .width = MMGR_ENDIAN_64); + uint64_t m6 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 48, .width = MMGR_ENDIAN_64); + uint64_t m7 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 56, .width = MMGR_ENDIAN_64); + uint64_t m8 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 64, .width = MMGR_ENDIAN_64); + uint64_t m9 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 72, .width = MMGR_ENDIAN_64); + uint64_t m10 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 80, .width = MMGR_ENDIAN_64); + uint64_t m11 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 88, .width = MMGR_ENDIAN_64); + uint64_t m12 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 96, .width = MMGR_ENDIAN_64); + uint64_t m13 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 104, .width = MMGR_ENDIAN_64); + uint64_t m14 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 112, .width = MMGR_ENDIAN_64); + uint64_t m15 = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = blk + 120, .width = MMGR_ENDIAN_64); uint64_t v0 = h[0]; uint64_t v1 = h[1]; @@ -320,7 +321,7 @@ static void sha512_absorb(uint8_t *work, const uint8_t *data, size_t len) } // rx + rxlen carries no alignment, so this is the raw mover, not the aligned-span one. uint8_t *fill = rx + ctx->rxlen; - proto_raw_read(fill, data, take); + EMBED_CALL(proxim.read, ProximusCfg, .dst = fill, .at = data, .size = take); ctx->rxlen += take; data += take; len -= take; @@ -346,12 +347,12 @@ static void sha512_finish(uint8_t *work, uint8_t digest[PROTOCORE_SHA512_DIGEST_ // The padded blocks compress into a copy of the state, so s, rx, rxlen and n all come out of this // untouched and the hash can keep taking data afterwards. - mem.cpy(fs, ctx->s, sizeof(ctx->s)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = fs, .src = ctx->s, .bytes = sizeof(ctx->s)); // The last block is composed in tx, whole: what rx holds, the mark, zeros, and the length. rx is // read and never written back, so nothing it still carries from an earlier block reaches the wire. - mem.zero(tx, PROTOCORE_SHA512_BLOCK_LEN); - mem.cpy(tx, rx, ctx->rxlen); + EMBED_CALL(memor.set, MemoriaCfg, .dst = tx, .val = 0, .bytes = PROTOCORE_SHA512_BLOCK_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = tx, .src = rx, .bytes = ctx->rxlen); tx[ctx->rxlen] = 0x80; // The 128-bit length occupies the block's last 16 bytes, so a mark at or past that offset takes @@ -359,21 +360,21 @@ static void sha512_finish(uint8_t *work, uint8_t digest[PROTOCORE_SHA512_DIGEST_ if (ctx->rxlen >= SHA512_LEN_OFF) { sha512_block(fs, tx); - mem.zero(tx, PROTOCORE_SHA512_BLOCK_LEN); + EMBED_CALL(memor.set, MemoriaCfg, .dst = tx, .val = 0, .bytes = PROTOCORE_SHA512_BLOCK_LEN); } - protocore_wr64be(tx + SHA512_LEN_OFF, len_hi); - protocore_wr64be(tx + SHA512_LEN_OFF + 8, len_lo); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = tx + SHA512_LEN_OFF, .val = len_hi, .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = tx + SHA512_LEN_OFF + 8, .val = len_lo, .width = MMGR_ENDIAN_64); sha512_block(fs, tx); - protocore_wr64be(digest, fs[0]); - protocore_wr64be(digest + 8, fs[1]); - protocore_wr64be(digest + 16, fs[2]); - protocore_wr64be(digest + 24, fs[3]); - protocore_wr64be(digest + 32, fs[4]); - protocore_wr64be(digest + 40, fs[5]); - protocore_wr64be(digest + 48, fs[6]); - protocore_wr64be(digest + 56, fs[7]); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest, .val = fs[0], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 8, .val = fs[1], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 16, .val = fs[2], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 24, .val = fs[3], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 32, .val = fs[4], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 40, .val = fs[5], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 48, .val = fs[6], .width = MMGR_ENDIAN_64); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = digest + 56, .val = fs[7], .width = MMGR_ENDIAN_64); } // --- the entries ----------------------------------------------------------- diff --git a/src/crypto/mac/ghash/CMakeLists.txt b/src/crypto/mac/ghash/CMakeLists.txt index d9618ecf4..a0174c737 100644 --- a/src/crypto/mac/ghash/CMakeLists.txt +++ b/src/crypto/mac/ghash/CMakeLists.txt @@ -6,5 +6,5 @@ protocore_add_module(crypto/mac/ghash OPT 2 SOURCES ghash.c PRIVATE_DEPS - mmgr/endian + mmgr ) diff --git a/src/crypto/mac/ghash/ghash.c b/src/crypto/mac/ghash/ghash.c index b16535567..d4188be93 100644 --- a/src/crypto/mac/ghash/ghash.c +++ b/src/crypto/mac/ghash/ghash.c @@ -22,7 +22,7 @@ #if PROTOCORE_ENABLE_GHASH #include "crypto/mac/ghash/ghash.h" -#include "mmgr/endian/endian.h" // protocore_rd32be / protocore_wr32be +#include "endian/endian.h" // magna_extremitas.rd / magna_extremitas.wr PROTOCORE_BEGIN_DECLS @@ -41,8 +41,8 @@ static_assert(GHASH_OFF_END <= PROTOCORE_GHASH_BORROW, "PROTOCORE_GHASH_BORROW is short of the 4-bit table - raise it in protocore_config.h, " "which derives PROTOCORE_SECURE_ARENA_SIZE from it"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(GHASH_OFF_CTX % _Alignof(GhashCtx) == 0, @@ -62,10 +62,10 @@ static void gf_key_init(uint8_t *work) GhashCtx *t = GHASH_CTX(work); const uint8_t *h = GhashV.key_args.h; // M[8] = H; M[4]=H/x, M[2]=H/x^2, M[1]=H/x^3 (one GF right-shift each, reducing by R=0xe1<<120). - uint32_t z0 = protocore_rd32be(h); - uint32_t z1 = protocore_rd32be(h + 4); - uint32_t z2 = protocore_rd32be(h + 8); - uint32_t z3 = protocore_rd32be(h + 12); + uint32_t z0 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = h, .width = MMGR_ENDIAN_32); + uint32_t z1 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = h + 4, .width = MMGR_ENDIAN_32); + uint32_t z2 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = h + 8, .width = MMGR_ENDIAN_32); + uint32_t z3 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = h + 12, .width = MMGR_ENDIAN_32); t->M[8][0] = z0; t->M[8][1] = z1; t->M[8][2] = z2; @@ -135,10 +135,10 @@ static void gf_mul(uint8_t *work, uint8_t *acc) z2 ^= t->M[hi][2]; z3 ^= t->M[hi][3]; } - protocore_wr32be(acc, z0); - protocore_wr32be(acc + 4, z1); - protocore_wr32be(acc + 8, z2); - protocore_wr32be(acc + 12, z3); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = acc, .val = z0, .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = acc + 4, .val = z1, .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = acc + 8, .val = z2, .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = acc + 12, .val = z3, .width = MMGR_ENDIAN_32); } // --- the entries ----------------------------------------------------------- diff --git a/src/crypto/mac/hmac_sha256/CMakeLists.txt b/src/crypto/mac/hmac_sha256/CMakeLists.txt index 5efbc99b9..b06f8f309 100644 --- a/src/crypto/mac/hmac_sha256/CMakeLists.txt +++ b/src/crypto/mac/hmac_sha256/CMakeLists.txt @@ -7,5 +7,5 @@ protocore_add_module(crypto/mac/hmac_sha256 SOURCES hmac_sha256.c PRIVATE_DEPS crypto/hash/sha256 - mmgr/protomem + mmgr ) diff --git a/src/crypto/mac/hmac_sha256/hmac_sha256.c b/src/crypto/mac/hmac_sha256/hmac_sha256.c index 3475eb6c1..529aaf8d8 100644 --- a/src/crypto/mac/hmac_sha256/hmac_sha256.c +++ b/src/crypto/mac/hmac_sha256/hmac_sha256.c @@ -24,7 +24,7 @@ #include "crypto/hash/sha256/sha256.h" // Sha256 - the digest this MAC drives, and its lengths #include "crypto/mac/hmac_sha256/hmac_sha256.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" // The transient half of the caller's bytes: live inside init and inside final, dead between them. The // two 64-byte key blocks double as key-padding scratch for build_key_block. @@ -45,8 +45,8 @@ static_assert(HMAC_OFF_HASH + PROTOCORE_SHA256_BORROW <= PROTOCORE_HMAC_SHA256_B "PROTOCORE_HMAC_SHA256_BORROW is short of the split - raise it in protocore_config.h, which " "sums it into the secure arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(HMAC_OFF_WORK % _Alignof(HmacWork) == 0, @@ -64,7 +64,7 @@ static_assert(HMAC_OFF_WORK % _Alignof(HmacWork) == 0, static void build_key_block(const uint8_t *key, size_t key_len, uint8_t block[64], uint8_t pad_byte, uint8_t scratch[64], uint8_t *hash_work) { - mem.set(scratch, 0, 64); + EMBED_CALL(memor.set, MemoriaCfg, .dst = scratch, .val = 0, .bytes = 64); if (key_len > 64) { // Keys longer than the block become their SHA-256 hash. diff --git a/src/crypto/mac/hmac_sha384/CMakeLists.txt b/src/crypto/mac/hmac_sha384/CMakeLists.txt index 8671b9388..2d3badae0 100644 --- a/src/crypto/mac/hmac_sha384/CMakeLists.txt +++ b/src/crypto/mac/hmac_sha384/CMakeLists.txt @@ -7,5 +7,5 @@ protocore_add_module(crypto/mac/hmac_sha384 SOURCES hmac_sha384.c PRIVATE_DEPS crypto/hash/sha384 - mmgr/protomem + mmgr ) diff --git a/src/crypto/mac/hmac_sha384/hmac_sha384.c b/src/crypto/mac/hmac_sha384/hmac_sha384.c index 5f310c6b8..9d96bbbdc 100644 --- a/src/crypto/mac/hmac_sha384/hmac_sha384.c +++ b/src/crypto/mac/hmac_sha384/hmac_sha384.c @@ -26,7 +26,7 @@ #include "crypto/hash/sha384/sha384.h" // the Sha384 entries the inner and outer hashes run through #include "crypto/mac/hmac_sha384/hmac_sha384.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" // The transient half of the caller's bytes: live inside init and inside final, dead between them. The // two 128-byte key blocks double as key-padding scratch for build_key_block. @@ -47,8 +47,8 @@ static_assert(HMAC384_OFF_HASH + PROTOCORE_SHA384_BORROW <= PROTOCORE_HMAC_SHA38 "PROTOCORE_HMAC_SHA384_BORROW is short of the split - raise it in protocore_config.h, which " "sums it into the secure arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(HMAC384_OFF_WORK % _Alignof(Hmac384Work) == 0, @@ -67,7 +67,7 @@ static_assert(HMAC384_OFF_WORK % _Alignof(Hmac384Work) == 0, static void build_key_block(const uint8_t *key, size_t key_len, uint8_t block[PROTOCORE_SHA384_BLOCK_LEN], uint8_t pad_byte, uint8_t kpad[PROTOCORE_SHA384_BLOCK_LEN], uint8_t *hw) { - mem.set(kpad, 0, PROTOCORE_SHA384_BLOCK_LEN); + EMBED_CALL(memor.set, MemoriaCfg, .dst = kpad, .val = 0, .bytes = PROTOCORE_SHA384_BLOCK_LEN); if (key_len > PROTOCORE_SHA384_BLOCK_LEN) { // Keys longer than the block become their SHA-384 hash: 48 bytes, the remaining 80 stay zero. @@ -75,7 +75,7 @@ static void build_key_block(const uint8_t *key, size_t key_len, uint8_t block[PR } else { - mem.cpy(kpad, key, key_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = kpad, .src = key, .bytes = key_len); } for (int i = 0; i < PROTOCORE_SHA384_BLOCK_LEN; i++) { diff --git a/src/crypto/mac/hmac_sha512/CMakeLists.txt b/src/crypto/mac/hmac_sha512/CMakeLists.txt index f4f0d2786..d54fb803c 100644 --- a/src/crypto/mac/hmac_sha512/CMakeLists.txt +++ b/src/crypto/mac/hmac_sha512/CMakeLists.txt @@ -7,5 +7,5 @@ protocore_add_module(crypto/mac/hmac_sha512 SOURCES hmac_sha512.c PRIVATE_DEPS crypto/hash/sha512 - mmgr/protomem + mmgr ) diff --git a/src/crypto/mac/hmac_sha512/hmac_sha512.c b/src/crypto/mac/hmac_sha512/hmac_sha512.c index 6b4c95686..bcb34b8b8 100644 --- a/src/crypto/mac/hmac_sha512/hmac_sha512.c +++ b/src/crypto/mac/hmac_sha512/hmac_sha512.c @@ -25,7 +25,7 @@ #include "crypto/hash/sha512/sha512.h" // the Sha512 entries the inner and outer hashes run through #include "crypto/mac/hmac_sha512/hmac_sha512.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" // The transient half of the caller's bytes: live inside init and inside final, dead between them. The // two 128-byte key blocks double as key-padding scratch for build_key_block. @@ -46,8 +46,8 @@ static_assert(HMAC512_OFF_HASH + PROTOCORE_SHA512_BORROW <= PROTOCORE_HMAC_SHA51 "PROTOCORE_HMAC_SHA512_BORROW is short of the split - raise it in protocore_config.h, which " "sums it into the secure arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(HMAC512_OFF_WORK % _Alignof(Hmac512Work) == 0, @@ -66,7 +66,7 @@ static_assert(HMAC512_OFF_WORK % _Alignof(Hmac512Work) == 0, static void build_key_block(const uint8_t *key, size_t key_len, uint8_t block[PROTOCORE_SHA512_BLOCK_LEN], uint8_t pad_byte, uint8_t kpad[PROTOCORE_SHA512_BLOCK_LEN], uint8_t *hw) { - mem.set(kpad, 0, PROTOCORE_SHA512_BLOCK_LEN); + EMBED_CALL(memor.set, MemoriaCfg, .dst = kpad, .val = 0, .bytes = PROTOCORE_SHA512_BLOCK_LEN); if (key_len > PROTOCORE_SHA512_BLOCK_LEN) { // Keys longer than the block become their SHA-512 hash: 64 bytes, the remaining 64 stay zero. @@ -74,7 +74,7 @@ static void build_key_block(const uint8_t *key, size_t key_len, uint8_t block[PR } else { - mem.cpy(kpad, key, key_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = kpad, .src = key, .bytes = key_len); } for (int i = 0; i < PROTOCORE_SHA512_BLOCK_LEN; i++) { diff --git a/src/crypto/mac/poly1305/CMakeLists.txt b/src/crypto/mac/poly1305/CMakeLists.txt index 794f156b8..9899ea688 100644 --- a/src/crypto/mac/poly1305/CMakeLists.txt +++ b/src/crypto/mac/poly1305/CMakeLists.txt @@ -6,5 +6,5 @@ protocore_add_module(crypto/mac/poly1305 OPT 2 SOURCES poly1305.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/crypto/mac/poly1305/poly1305.c b/src/crypto/mac/poly1305/poly1305.c index bb2d22a16..e5f225db8 100644 --- a/src/crypto/mac/poly1305/poly1305.c +++ b/src/crypto/mac/poly1305/poly1305.c @@ -19,7 +19,7 @@ #if PROTOCORE_ENABLE_POLY1305 #include "crypto/mac/poly1305/poly1305.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" // Poly1305 is a hot, pure-integer MAC (the other half of chacha20-poly1305). Like ChaCha it has no vector // path on the S3 and runs materially faster than the framework -Os; it is constant-time by structure @@ -41,8 +41,8 @@ static_assert(POLY1305_OFF_BUF + 16u <= PROTOCORE_POLY1305_BORROW, "PROTOCORE_POLY1305_BORROW is short of the limbs and the padded final block - raise it in " "protocore_config.h, which sums it into the secure arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(POLY1305_OFF_CTX % _Alignof(Poly1305Ctx) == 0, @@ -155,7 +155,7 @@ static void poly1305_absorb(uint8_t *work, const uint8_t *msg, size_t len) } if (len) { - mem.set(buf, 0, 16); + EMBED_CALL(memor.set, MemoriaCfg, .dst = buf, .val = 0, .bytes = 16); for (size_t i = 0; i < len; i++) { buf[i] = msg[i]; diff --git a/src/crypto/pqc/mlkem/CMakeLists.txt b/src/crypto/pqc/mlkem/CMakeLists.txt index e9c180109..d47022eb5 100644 --- a/src/crypto/pqc/mlkem/CMakeLists.txt +++ b/src/crypto/pqc/mlkem/CMakeLists.txt @@ -7,5 +7,5 @@ protocore_add_module(crypto/pqc/mlkem SOURCES mlkem.c PRIVATE_DEPS crypto/hash/sha3 - mmgr/protomem + mmgr ) diff --git a/src/crypto/pqc/mlkem/mlkem.c b/src/crypto/pqc/mlkem/mlkem.c index 82b2f029f..215af394f 100644 --- a/src/crypto/pqc/mlkem/mlkem.c +++ b/src/crypto/pqc/mlkem/mlkem.c @@ -19,7 +19,7 @@ #include "crypto/hash/sha3/sha3.h" #include "crypto/pqc/mlkem/mlkem.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" // ML-KEM-768 parameters (FIPS 203). #define MK_N 256 @@ -251,7 +251,7 @@ static void cbd2(int16_t r[MK_N], const uint8_t buf[128]) static void poly_getnoise(uint8_t *work, int16_t r[MK_N], const uint8_t seed[32], uint8_t nonce) { uint8_t extseed[33]; - mem.cpy(extseed, seed, 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = extseed, .src = seed, .bytes = 32); extseed[32] = nonce; uint8_t buf[MK_ETA * MK_N / 4]; // 128 mk_shake256(work, buf, sizeof(buf), extseed, sizeof(extseed)); @@ -262,7 +262,7 @@ static void poly_getnoise(uint8_t *work, int16_t r[MK_N], const uint8_t seed[32] static void gen_matrix_entry(uint8_t *work, int16_t out[MK_N], const uint8_t rho[32], uint8_t i, uint8_t j) { uint8_t seed[34]; - mem.cpy(seed, rho, 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = seed, .src = rho, .bytes = 32); seed[32] = i; seed[33] = j; mk_shake128_absorb(work, seed, sizeof(seed)); @@ -500,7 +500,7 @@ static void k_pke_keygen(uint8_t *work, uint8_t ek[MLKEM768_EK_BYTES], uint8_t d { // (rho, sigma) = G(d || k). The trailing k byte is the FIPS 203 domain separation on module rank. uint8_t g_in[33]; - mem.cpy(g_in, d, 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = g_in, .src = d, .bytes = 32); g_in[32] = MK_K; uint8_t g_out[64]; mk_sha3_512(work, g_out, g_in, sizeof(g_in)); @@ -545,7 +545,7 @@ static void k_pke_keygen(uint8_t *work, uint8_t ek[MLKEM768_EK_BYTES], uint8_t d } poly_tobytes(ek + i * MK_POLYBYTES, t_row); } - mem.cpy(ek + MK_K * MK_POLYBYTES, rho, 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = ek + MK_K * MK_POLYBYTES, .src = rho, .bytes = 32); for (unsigned i = 0; i < MK_K; i++) { @@ -592,9 +592,9 @@ proto_bool protocore_ml_kem_keygen(uint8_t *work, const uint8_t *d, const uint8_ // dk = dk_PKE || ek || H(ek) || z (FIPS 203 Algorithm 16). k_pke_keygen(work, ek, dk, d); - mem.cpy(dk + MK_K * MK_POLYBYTES, ek, MLKEM768_EK_BYTES); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = dk + MK_K * MK_POLYBYTES, .src = ek, .bytes = MLKEM768_EK_BYTES); mk_sha3_256(work, dk + MK_K * MK_POLYBYTES + MLKEM768_EK_BYTES, ek, MLKEM768_EK_BYTES); - mem.cpy(dk + MK_K * MK_POLYBYTES + MLKEM768_EK_BYTES + 32, z, 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = dk + MK_K * MK_POLYBYTES + MLKEM768_EK_BYTES + 32, .src = z, .bytes = 32); return PROTO_TRUE; } @@ -611,11 +611,11 @@ proto_bool protocore_ml_kem_encaps(uint8_t *work, const uint8_t *ek, const uint8 // (K, r) = G(m || H(ek)); ss = K. uint8_t g_in[64]; - mem.cpy(g_in, m, 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = g_in, .src = m, .bytes = 32); mk_sha3_256(work, g_in + 32, ek, MLKEM768_EK_BYTES); // H(ek) uint8_t g_out[64]; mk_sha3_512(work, g_out, g_in, sizeof(g_in)); - mem.cpy(ss, g_out, 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = ss, .src = g_out, .bytes = 32); k_pke_encrypt(work, ct, ek, m, g_out + 32); return PROTO_TRUE; @@ -637,15 +637,15 @@ proto_bool protocore_ml_kem_decaps(uint8_t *work, const uint8_t *dk, const uint8 uint8_t mprime[32]; k_pke_decrypt(mprime, dk_pke, ct); uint8_t g_in[64]; - mem.cpy(g_in, mprime, 32); - mem.cpy(g_in + 32, h, 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = g_in, .src = mprime, .bytes = 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = g_in + 32, .src = h, .bytes = 32); uint8_t g_out[64]; mk_sha3_512(work, g_out, g_in, sizeof(g_in)); // Implicit-reject key K_bar = J(z || ct) = SHAKE256(z || ct, 32). uint8_t jbuf[32 + MLKEM768_CT_BYTES]; - mem.cpy(jbuf, z, 32); - mem.cpy(jbuf + 32, ct, MLKEM768_CT_BYTES); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = jbuf, .src = z, .bytes = 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = jbuf + 32, .src = ct, .bytes = MLKEM768_CT_BYTES); uint8_t kbar[32]; mk_shake256(work, kbar, sizeof(kbar), jbuf, sizeof(jbuf)); diff --git a/src/crypto/rng/CMakeLists.txt b/src/crypto/rng/CMakeLists.txt index 597c28ed0..edaadf4b2 100644 --- a/src/crypto/rng/CMakeLists.txt +++ b/src/crypto/rng/CMakeLists.txt @@ -7,6 +7,6 @@ protocore_add_module(crypto/rng SOURCES rng.c PRIVATE_DEPS crypto/cipher/chacha20 - mmgr/protomem - mmgr/secure + mmgr + server/core/worker ) diff --git a/src/crypto/rng/rng.c b/src/crypto/rng/rng.c index 414cf7485..d34534606 100644 --- a/src/crypto/rng/rng.c +++ b/src/crypto/rng/rng.c @@ -22,8 +22,9 @@ #include "crypto/cipher/chacha20/chacha20.h" #include "crypto/rng/rng.h" -#include "mmgr/protomem/protomem.h" -#include "mmgr/secure/secure.h" // protocore_secure_wipe +#include "locus_carcerum/locus_carcerum.h" // mmgr_zero_buf: the wipe the compiler cannot drop +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from PROTOCORE_BEGIN_DECLS @@ -56,8 +57,8 @@ static_assert(RNG_OFF_CHACHA + PROTOCORE_CHACHA20_BORROW <= PROTOCORE_RNG_BORROW "the nested borrow - raise it in protocore_config.h, which derives " "PROTOCORE_SECURE_ARENA_SIZE from it"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(RNG_OFF_CTX % _Alignof(RngCtx) == 0, @@ -110,7 +111,7 @@ uint8_t *protocore_rng_span(void) { if (s_rng.span == NULL) { - s_rng.span = protocore_secure_persist_span(PROTOCORE_RNG_BORROW).buf; + s_rng.span = (uint8_t *)protocore_secure_persist(PROTOCORE_RNG_BORROW); } return s_rng.span; } @@ -135,8 +136,8 @@ void protocore_rng_fill(uint8_t *work) } rng_chacha(work, key, iv, 0, NULL, next, PROTOCORE_RAND_SEED_LEN); rng_chacha(work, key, iv, 1, NULL, RngV.fill_args.out, len); - mem.cpy(key, next, PROTOCORE_RAND_SEED_LEN); - protocore_secure_wipe(next, PROTOCORE_RAND_SEED_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = key, .src = next, .bytes = PROTOCORE_RAND_SEED_LEN); + mmgr_zero_buf(next, PROTOCORE_RAND_SEED_LEN); ctx->drawn += len; RngV.ok = PROTO_TRUE; } diff --git a/src/crypto/x509/x509/CMakeLists.txt b/src/crypto/x509/x509/CMakeLists.txt index 7f0cda77d..ec8899bf3 100644 --- a/src/crypto/x509/x509/CMakeLists.txt +++ b/src/crypto/x509/x509/CMakeLists.txt @@ -8,6 +8,6 @@ protocore_add_module(crypto/x509/x509 DEPS crypto/x509/x509_types PRIVATE_DEPS - mmgr/protomem + mmgr shared/der ) diff --git a/src/crypto/x509/x509/x509.c b/src/crypto/x509/x509/x509.c index 6691c530a..6971771f3 100644 --- a/src/crypto/x509/x509/x509.c +++ b/src/crypto/x509/x509/x509.c @@ -12,8 +12,8 @@ #include "crypto/x509/x509/x509.h" -#include "mmgr/protomem/protomem.h" // mem.set: the view is cleared before a parse fills it -#include "shared/der/der.h" // Der: the one reader +#include "memoria_operor/memoria_operor.h" // memor.set: the view is cleared before a parse fills it +#include "shared/der/der.h" // Der: the one reader PROTOCORE_BEGIN_DECLS @@ -282,7 +282,7 @@ void protocore_x509_parse(uint8_t *work) { (void)work; X509V.ok = PROTO_FALSE; - mem.set(&X509V.cert, 0, sizeof(X509V.cert)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &X509V.cert, .val = 0, .bytes = sizeof(X509V.cert)); const uint8_t *der = X509V.parse_args.der; const size_t len = X509V.parse_args.len; diff --git a/src/mmgr/CMakeLists.txt b/src/mmgr/CMakeLists.txt deleted file mode 100644 index b91227c35..000000000 --- a/src/mmgr/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later -# -# The directories below. A new module is a new directory and a line here - nothing central holds a -# list of modules, so there is nothing else to keep in step. - -add_subdirectory(arena) -add_subdirectory(bitio) -add_subdirectory(bytes) -add_subdirectory(dma) -add_subdirectory(endian) -add_subdirectory(float_bits) -add_subdirectory(membuild) -add_subdirectory(plaintext) -add_subdirectory(protoframe) -add_subdirectory(protomem) -add_subdirectory(protostr) -add_subdirectory(psram_pool) -add_subdirectory(rawmemcpy) -add_subdirectory(ring) -add_subdirectory(secure) -add_subdirectory(span) -add_subdirectory(swar) diff --git a/src/mmgr/arena/CMakeLists.txt b/src/mmgr/arena/CMakeLists.txt deleted file mode 100644 index 4a1c9d9ee..000000000 --- a/src/mmgr/arena/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/arena - SOURCES arena.c - PRIVATE_DEPS - mmgr/protomem -) diff --git a/src/mmgr/arena/arena.c b/src/mmgr/arena/arena.c deleted file mode 100644 index 1005838b1..000000000 --- a/src/mmgr/arena/arena.c +++ /dev/null @@ -1,362 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file arena.c - * @brief Unified double-ended server arena. See arena.h for the model. - */ - -#include "mmgr/arena/arena.h" -#include "mmgr/protomem/protomem.h" - -// --------------------------------------------------------------------------- -// Slot identity -// --------------------------------------------------------------------------- -// -// Per-task worker id, for a genuine multi-worker build. Default 0: the user loop(), the lwIP -// thread, and unit tests all read worker 0. -// -// The binding is a table keyed on the platform's own answer to "which execution context is running -// me", not a `_Thread_local`. Both reach the same place on an RTOS - the task's own storage - but a -// thread-local makes the compiler emit __emutls_get_address, and libgcc's emulated-TLS allocates -// each block with malloc and calls abort when it cannot. A build that owns no heap after boot -// cannot link that, so the identity is held here instead. -// -// One entry per worker plus the ghost slot, which is every context that can ever bind one; the -// count is fixed at build time, so this is BSS and the claim is a bounded walk. `s_bound` is the -// counter: a context that has never bound reads worker 0. -#define PROTOCORE_WORKER_BINDINGS (PROTOCORE_WORKER_COUNT + 1) - -static uintptr_t s_ctx[PROTOCORE_WORKER_BINDINGS]; -static int s_ctx_worker[PROTOCORE_WORKER_BINDINGS]; -static int s_bound; - -int protocore_worker_count(void) -{ - return PROTOCORE_WORKER_COUNT; -} - -#if PROTOCORE_WORKER_COUNT != 1 -int protocore_worker_self(void) -{ - const uintptr_t me = protocore_platform_context_id(); - for (int i = 0; i < s_bound; i++) - { - if (s_ctx[i] == me) - { - return s_ctx_worker[i]; - } - } - return 0; -} -#endif - -void protocore_worker_set_self(int id) -{ - const uintptr_t me = protocore_platform_context_id(); - for (int i = 0; i < s_bound; i++) - { - if (s_ctx[i] == me) - { - s_ctx_worker[i] = id; // this context rebinding itself - return; - } - } - if (s_bound < PROTOCORE_WORKER_BINDINGS) - { - s_ctx[s_bound] = me; - s_ctx_worker[s_bound] = id; - s_bound++; - } -} - -// Persistent-pool block header: a chain of these spans [0, persist_end). -typedef struct -{ - size_t size; ///< payload bytes - size_t used; ///< 0 = free, 1 = in use -} ABlk; - -// Header size, rounded up to the arena alignment so payloads stay aligned. -static const size_t AHDR = (sizeof(ABlk) + (PROTOCORE_ARENA_ALIGN - 1)) & ~(size_t)(PROTOCORE_ARENA_ALIGN - 1); - -static inline size_t align_up(size_t n) // persist path only; the scratch path uses protocore_arena_align_up -{ - return (n + (PROTOCORE_ARENA_ALIGN - 1)) & ~(size_t)(PROTOCORE_ARENA_ALIGN - 1); -} - -void protocore_arena_init(protocore_arena *a, void *base, size_t size) -{ - // Align the base up to the strongest supported alignment and the size down, so a - // scratch borrow up to PROTOCORE_ARENA_MAX_ALIGN is met by aligning its offset alone. - uintptr_t b = (uintptr_t)base; - uintptr_t ab = (b + (PROTOCORE_ARENA_MAX_ALIGN - 1)) & ~(uintptr_t)(PROTOCORE_ARENA_MAX_ALIGN - 1); - size_t adj = (size_t)(ab - b); - a->base = (uint8_t *)ab; - a->size = (size > adj) ? ((size - adj) & ~(size_t)(PROTOCORE_ARENA_ALIGN - 1)) : 0; - a->persist_end = 0; - a->scratch_top = a->size; - a->persist_used = 0; - a->persist_hw = 0; - a->scratch_hw = 0; -} - -// --------------------------------------------------------------------------- -// Persistent end (first-fit, grows up from the bottom) -// --------------------------------------------------------------------------- - -void *protocore_arena_persist_alloc(protocore_arena *a, size_t n) -{ - n = align_up(n ? n : PROTOCORE_ARENA_ALIGN); - - // First-fit over the existing block chain. - size_t off = 0; - while (off < a->persist_end) - { - ABlk *b = (ABlk *)(a->base + off); - if (!b->used && b->size >= n) - { - // Split if the remainder can hold another header + a minimum payload. - if (b->size >= n + AHDR + PROTOCORE_ARENA_ALIGN) - { - ABlk *nb = (ABlk *)(a->base + off + AHDR + n); - nb->size = b->size - n - AHDR; - nb->used = 0; - b->size = n; - } - b->used = 1; - a->persist_used += b->size; - void *pl = a->base + off + AHDR; - mem.set(pl, 0, b->size); - return pl; - } - off += AHDR + b->size; - } - - // No reusable block: carve a fresh one from the free middle (grow the boundary up), - // but only if it will not cross the scratch end. - size_t need = AHDR + n; - if (a->persist_end + need <= a->scratch_top && a->persist_end + need >= need) - { - ABlk *b = (ABlk *)(a->base + a->persist_end); - b->size = n; - b->used = 1; - void *pl = a->base + a->persist_end + AHDR; - a->persist_end += need; - if (a->persist_end > a->persist_hw) - { - a->persist_hw = a->persist_end; - } - a->persist_used += n; - mem.set(pl, 0, n); - return pl; - } - return NULL; // fail closed -} - -void protocore_arena_persist_free(protocore_arena *a, void *p) -{ - if (!p) - { - return; - } - ABlk *b = (ABlk *)((uint8_t *)p - AHDR); - if (b->used) - { - b->used = 0; - // The false half is unreachable: persist_used only ever accumulates this same block's - // own size (at alloc time), so it can never be smaller than b->size while b->used was true. - if (a->persist_used >= b->size) - { - a->persist_used -= b->size; - } - } - - // Coalesce adjacent free blocks front-to-back. - size_t off = 0; - while (off < a->persist_end) - { - ABlk *cur = (ABlk *)(a->base + off); - size_t next_off = off + AHDR + cur->size; - if (!cur->used && next_off < a->persist_end) - { - ABlk *nxt = (ABlk *)(a->base + next_off); - if (!nxt->used) - { - cur->size += AHDR + nxt->size; // merge; recheck this block - continue; - } - } - off = next_off; - } - - // If the last block is free, hand it back to the free middle (shrink the boundary). - off = 0; - size_t last = 0; - while (off < a->persist_end) - { - last = off; - ABlk *cur = (ABlk *)(a->base + off); - off += AHDR + cur->size; - } - if (a->persist_end > 0 && !((ABlk *)(a->base + last))->used) - { - a->persist_end = last; - } -} - -// --------------------------------------------------------------------------- -// Scratch end (bump, grows down from the top) -// --------------------------------------------------------------------------- - -void *protocore_arena_scratch_alloc(protocore_arena *a, size_t n) -{ - return protocore_arena_scratch_alloc_aligned(a, n, PROTOCORE_ARENA_ALIGN); -} - -// --------------------------------------------------------------------------- -// Observability -// --------------------------------------------------------------------------- - -size_t protocore_arena_free_bytes(const protocore_arena *a) -{ - size_t mid = (a->scratch_top > a->persist_end) ? a->scratch_top - a->persist_end : 0; - return mid > AHDR ? mid - AHDR : 0; // usable payload of one new persistent block -} - -size_t protocore_arena_persist_used(const protocore_arena *a) -{ - return a->persist_used; -} - -// =========================================================================== -// Multi-region set (DRAM base + PSRAM extension) -// =========================================================================== - -void protocore_arena_set_init(protocore_arena_set *s) -{ - s->count = 0; -} - -proto_bool protocore_arena_set_add(protocore_arena_set *s, void *base, size_t size) -{ - if (s->count >= PROTOCORE_ARENA_MAX_REGIONS) - { - return PROTO_FALSE; - } - protocore_arena *r = &s->region[s->count]; - protocore_arena_init(r, base, size); - if (r->size < AHDR + PROTOCORE_ARENA_ALIGN) - { - return PROTO_FALSE; // too small to hold even one block - } - s->count++; - return PROTO_TRUE; -} - -void *protocore_arena_set_persist_alloc(protocore_arena_set *s, size_t n) -{ - for (size_t i = 0; i < s->count; i++) - { - void *p = protocore_arena_persist_alloc(&s->region[i], n); - if (p) - { - return p; - } - } - return NULL; // fail closed -} - -void protocore_arena_set_persist_free(protocore_arena_set *s, void *p) -{ - if (!p) - { - return; - } - uint8_t *b = (uint8_t *)p; - for (size_t i = 0; i < s->count; i++) - { - protocore_arena *r = &s->region[i]; - if (b >= r->base && b < r->base + r->size) - { - protocore_arena_persist_free(r, p); - return; - } - } -} - -void *protocore_arena_set_scratch_alloc_aligned(protocore_arena_set *s, size_t n, size_t align) -{ - for (size_t i = 0; i < s->count; i++) - { - void *p = protocore_arena_scratch_alloc_aligned(&s->region[i], n, align); - if (p) - { - return p; - } - } - return NULL; // fail closed -} - -void *protocore_arena_set_scratch_alloc(protocore_arena_set *s, size_t n) -{ - return protocore_arena_set_scratch_alloc_aligned(s, n, PROTOCORE_ARENA_ALIGN); -} - -protocore_arena_mark protocore_arena_set_scratch_mark(const protocore_arena_set *s) -{ - protocore_arena_mark m; - m.count = s->count; - for (size_t i = 0; i < s->count; i++) - { - m.top[i] = s->region[i].scratch_top; - } - return m; -} - -void protocore_arena_set_scratch_release(protocore_arena_set *s, const protocore_arena_mark *m) -{ - size_t n = m->count < s->count ? m->count : s->count; - for (size_t i = 0; i < n; i++) - { - protocore_arena_scratch_release(&s->region[i], m->top[i]); - } -} - -void protocore_arena_set_scratch_reset(protocore_arena_set *s) -{ - for (size_t i = 0; i < s->count; i++) - { - protocore_arena_scratch_reset(&s->region[i]); - } -} - -size_t protocore_arena_set_free_bytes(const protocore_arena_set *s) -{ - size_t t = 0; - for (size_t i = 0; i < s->count; i++) - { - t += protocore_arena_free_bytes(&s->region[i]); - } - return t; -} - -size_t protocore_arena_set_persist_used(const protocore_arena_set *s) -{ - size_t t = 0; - for (size_t i = 0; i < s->count; i++) - { - t += protocore_arena_persist_used(&s->region[i]); - } - return t; -} - -size_t protocore_arena_set_scratch_used(const protocore_arena_set *s) -{ - size_t t = 0; - for (size_t i = 0; i < s->count; i++) - { - t += protocore_arena_scratch_used(&s->region[i]); - } - return t; -} diff --git a/src/mmgr/arena/arena.h b/src/mmgr/arena/arena.h deleted file mode 100644 index c278800f3..000000000 --- a/src/mmgr/arena/arena.h +++ /dev/null @@ -1,303 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file arena.h - * @brief Unified double-ended server arena. - * - * One contiguous region is shared by two allocators that grow toward each other, with - * the free space floating in the middle: - * - * [ persistent --grows up--> | free | <--grows down-- scratch ] - * low addr (floating boundary) high addr - * - * - **Persistent** (bottom): a first-fit free-list. Long-lived objects that are freed - * individually, in arbitrary order (e.g. per-connection state). Grows up into the - * middle only as far as the scratch end allows; a freed top block shrinks it back. - * - **Scratch** (top): a bump allocator reclaimed in bulk. Transient per-dispatch - * buffers. `protocore_arena_scratch_reset()` empties it in O(1); `mark`/`release` give nested savepoints. - * - * Whichever side needs more room grows into the shared middle - that is the win over two - * fixed pools. Both ends fail closed (return NULL) rather than crossing the boundary. - * - * All state lives in ::protocore_arena (no globals), so it is unit-testable and can back several - * arenas (a DRAM base and a PSRAM extension - see ::protocore_arena_set). No heap; no stdlib. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_ARENA_H -#define PROTOCORE_ARENA_H - -#include "protocore_config.h" // PROTOCORE_WORKER_COUNT - how many slots the pools are cut into - -PROTOCORE_BEGIN_DECLS - -// --------------------------------------------------------------------------- -// Slot identity - which arena is mine -// --------------------------------------------------------------------------- -// -// The pools are cut one slot per worker so a borrow never crosses workers, which means the -// allocator has to be able to answer "which slot is the caller" before it can hand anything back. -// That answer lives here, with the thing it indexes, rather than in the scheduler: mmgr arbitrates -// the memory, so it owns the identity the arbitration keys on. Starting and waking those workers is -// a separate concern and stays in the session layer. - -/** @brief Number of server worker tasks (PROTOCORE_WORKER_COUNT). */ -int protocore_worker_count(void); - -/** - * @brief Worker id [0, count) of the calling task; 0 by default / single-worker. - * - * With PROTOCORE_WORKER_COUNT == 1 (the default) there is exactly one worker, so the answer is 0 by - * construction and this is an inline constant - no lookup, no call. That matters because every pool - * borrow asks: the multi-worker path reads a `_Thread_local`, which on FreeRTOS resolves through the - * task's TLS block rather than a register, and it was being paid on operations that are otherwise a - * single struct-field read. - */ -#if PROTOCORE_WORKER_COUNT == 1 -PROTOCORE_INLINE int protocore_worker_self(void) -{ - return 0; -} -#else -int protocore_worker_self(void); -#endif - -/** @brief Bind the calling task/thread to worker id @p id (worker entry / tests). */ -void protocore_worker_set_self(int id); - -/** @brief Baseline alignment (bytes) applied to every allocation and to headers. */ -#define PROTOCORE_ARENA_ALIGN 8u - -/** @brief Round @p n up to PROTOCORE_ARENA_ALIGN. */ -PROTOCORE_INLINE size_t protocore_arena_align_up(size_t n) -{ - return (n + (PROTOCORE_ARENA_ALIGN - 1)) & ~(size_t)(PROTOCORE_ARENA_ALIGN - 1); -} - -/** @brief Strongest alignment a scratch borrow may request; the region base is aligned to it. */ -#define PROTOCORE_ARENA_MAX_ALIGN 16u - -/** - * @brief Double-ended arena over one region `[base, base+size)`. - * - * `persist_end` and `scratch_top` are byte offsets from `base`; the free middle is - * `[persist_end, scratch_top)`. The persistent pool owns `[0, persist_end)` (a chain of - * first-fit blocks); scratch owns `[scratch_top, size)` (bump). Initialize with - * protocore_arena_init(); do not touch the fields directly. - */ -typedef struct -{ - uint8_t *base; ///< Region start. - size_t size; ///< Region length in bytes. - size_t persist_end; ///< Persistent pool occupies [0, persist_end). - size_t scratch_top; ///< Scratch occupies [scratch_top, size). - size_t persist_used; ///< Bytes currently handed out by the persistent pool (payload). - size_t persist_hw; ///< High-water of persist_end (for sizing). - size_t scratch_hw; ///< High-water of scratch use (size - min scratch_top). -} protocore_arena; - -/** - * @brief Initialize @p a over the region `[base, base+size)`. - * - * @p base should be PROTOCORE_ARENA_ALIGN-aligned; @p size must be at least a few blocks. - */ -void protocore_arena_init(protocore_arena *a, void *base, size_t size); - -// --- persistent end (first-fit, individual free, grows up) ------------------ - -/** - * @brief Allocate @p n zero-initialized bytes of long-lived storage. - * - * First-fits an existing free block; otherwise carves a new block from the free middle - * (growing the persistent end up) if it will not cross the scratch end. - * @return aligned, zeroed pointer, or NULL if the arena cannot satisfy it. - */ -void *protocore_arena_persist_alloc(protocore_arena *a, size_t n); - -/** - * @brief Free a pointer previously returned by protocore_arena_persist_alloc(). - * - * Coalesces with adjacent free blocks; if the freed block sits at the top of the - * persistent region it returns that space to the free middle (shrinks the boundary). - * Passing NULL is a no-op. - */ -void protocore_arena_persist_free(protocore_arena *a, void *p); - -// --- scratch end (bump, bulk reset, grows down) ----------------------------- -// -// Inline: a borrow is a few loads, a mask and a store, so a call would cost more than the work. -// PROTOCORE_INLINE, not bare inline - a bare C inline needs a second out-of-line definition to link. - -/** - * @brief Bump-allocate @p n bytes of transient storage, aligned to @p align. - * - * @param align power-of-two alignment for the returned pointer; clamped to - * `[PROTOCORE_ARENA_ALIGN, PROTOCORE_ARENA_MAX_ALIGN]`. - * @return aligned pointer (NOT zeroed), or NULL if it would cross the persistent end. - */ -PROTOCORE_INLINE void *protocore_arena_scratch_alloc_aligned(protocore_arena *a, size_t n, size_t align) -{ - if (align < PROTOCORE_ARENA_ALIGN) - { - align = PROTOCORE_ARENA_ALIGN; - } - if (align > PROTOCORE_ARENA_MAX_ALIGN) - { - align = PROTOCORE_ARENA_MAX_ALIGN; // the base only guarantees this much - } - n = protocore_arena_align_up(n ? n : PROTOCORE_ARENA_ALIGN); - if (a->scratch_top < n) - { - return NULL; - } - // The base is PROTOCORE_ARENA_MAX_ALIGN-aligned, so aligning the offset down aligns the pointer. - size_t nt = (a->scratch_top - n) & ~(size_t)(align - 1); - // The "nt > a->scratch_top" half is unreachable: the guard above already established - // n <= a->scratch_top, so the subtraction cannot underflow, and masking off low bits can - // only ever decrease the value further - nt <= a->scratch_top always holds. - if (nt < a->persist_end || nt > a->scratch_top) - { - return NULL; // would cross the persistent end (or underflow) - } - a->scratch_top = nt; - size_t used = a->size - a->scratch_top; - if (used > a->scratch_hw) - { - a->scratch_hw = used; - } - return a->base + a->scratch_top; -} - -/** @brief Bump-allocate @p n transient bytes at the baseline alignment (PROTOCORE_ARENA_ALIGN). */ -void *protocore_arena_scratch_alloc(protocore_arena *a, size_t n); - -/** @brief Capture the current scratch position (a savepoint for protocore_arena_scratch_release()). */ -PROTOCORE_INLINE size_t protocore_arena_scratch_mark(const protocore_arena *a) -{ - return a->scratch_top; -} - -/** @brief Free every scratch allocation made since @p mark (a value from protocore_arena_scratch_mark()). */ -PROTOCORE_INLINE void protocore_arena_scratch_release(protocore_arena *a, size_t mark) -{ - // A mark is an earlier (higher) scratch_top; releasing frees everything below it. - if (mark >= a->scratch_top && mark <= a->size) - { - a->scratch_top = mark; - } -} - -/** @brief Free ALL scratch allocations in O(1). */ -PROTOCORE_INLINE void protocore_arena_scratch_reset(protocore_arena *a) -{ - a->scratch_top = a->size; -} - -// --- ownership (the access control) ----------------------------------------- - -/** - * @brief True if @p p points inside this pool's region. - * - * Ownership is an address-range property, not bookkeeping. The pools occupy disjoint regions, so a - * pointer belongs to exactly one of them and the owner is recoverable from the address alone. That - * is what stops a secret-pool pointer from being accepted where a plaintext one is expected, and - * what makes a write that ran off the end land outside the range rather than in a neighbour. - * - * Two compares, because this arena's base and size are only known at run time. protocore_plaintext_owns() - * / protocore_secure_owns() answer the same question against a compile-time bound in one subtract. - */ -PROTOCORE_INLINE proto_bool protocore_arena_owns(const protocore_arena *a, const void *p) -{ - const uint8_t *q = (const uint8_t *)p; - return a->base != NULL && q >= a->base && q < a->base + a->size; -} - -// --- observability ---------------------------------------------------------- - -/** @brief Free bytes in the middle (max a single new allocation could take, minus a header). */ -size_t protocore_arena_free_bytes(const protocore_arena *a); - -/** @brief Persistent payload bytes currently allocated. */ -size_t protocore_arena_persist_used(const protocore_arena *a); - -/** @brief Scratch bytes currently allocated. */ -PROTOCORE_INLINE size_t protocore_arena_scratch_used(const protocore_arena *a) -{ - return a->size - a->scratch_top; -} - -// =========================================================================== -// Multi-region extension: a DRAM base + an optional PSRAM extension. -// =========================================================================== -// -// A ::protocore_arena_set chains a few ::protocore_arena regions in preference order (add DRAM -// first, PSRAM second). Allocations try each region in turn and take the first -// that fits, so hot state stays in fast internal RAM and only the overflow -// spills into external RAM. Frees are routed to the owning region by address. -// This is how "arena extension" works: enable PSRAM by adding a second region; -// leave it out and the set is just the single DRAM arena. - -/** @brief Max regions in a ::protocore_arena_set (DRAM base + PSRAM extension). */ -#ifndef PROTOCORE_ARENA_MAX_REGIONS -#define PROTOCORE_ARENA_MAX_REGIONS 2u -#endif - -/** @brief A set of ::protocore_arena regions searched in insertion (preference) order. */ -typedef struct -{ - protocore_arena region[PROTOCORE_ARENA_MAX_REGIONS]; - size_t count; ///< Regions in use. -} protocore_arena_set; - -/** @brief A scratch savepoint across every region of a ::protocore_arena_set. */ -typedef struct -{ - size_t top[PROTOCORE_ARENA_MAX_REGIONS]; - size_t count; -} protocore_arena_mark; - -/** @brief Initialize an empty set (no regions yet). */ -void protocore_arena_set_init(protocore_arena_set *s); - -/** - * @brief Add a region `[base, base+size)`; regions are searched in the order added. - * @return true if added, false if the set is full or the region is too small. - */ -proto_bool protocore_arena_set_add(protocore_arena_set *s, void *base, size_t size); - -/** @brief Persistent alloc from the first region that fits (see protocore_arena_persist_alloc()). */ -void *protocore_arena_set_persist_alloc(protocore_arena_set *s, size_t n); - -/** @brief Free a persistent pointer, routed to its owning region by address. */ -void protocore_arena_set_persist_free(protocore_arena_set *s, void *p); - -/** @brief Aligned scratch alloc from the first region that fits (see protocore_arena_scratch_alloc_aligned()). */ -void *protocore_arena_set_scratch_alloc_aligned(protocore_arena_set *s, size_t n, size_t align); - -/** @brief Scratch alloc from the first region that fits (see protocore_arena_scratch_alloc()). */ -void *protocore_arena_set_scratch_alloc(protocore_arena_set *s, size_t n); - -/** @brief Capture the scratch position of every region. */ -protocore_arena_mark protocore_arena_set_scratch_mark(const protocore_arena_set *s); - -/** @brief Restore every region's scratch position to @p m (frees scratch made since). */ -void protocore_arena_set_scratch_release(protocore_arena_set *s, const protocore_arena_mark *m); - -/** @brief Reset scratch in every region. */ -void protocore_arena_set_scratch_reset(protocore_arena_set *s); - -/** @brief Total free middle bytes summed over all regions. */ -size_t protocore_arena_set_free_bytes(const protocore_arena_set *s); - -/** @brief Persistent payload bytes allocated, summed over all regions. */ -size_t protocore_arena_set_persist_used(const protocore_arena_set *s); - -/** @brief Scratch bytes allocated, summed over all regions. */ -size_t protocore_arena_set_scratch_used(const protocore_arena_set *s); - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_ARENA_H diff --git a/src/mmgr/bitio/CMakeLists.txt b/src/mmgr/bitio/CMakeLists.txt deleted file mode 100644 index d0c2ae29e..000000000 --- a/src/mmgr/bitio/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/bitio - SOURCES bitio.c -) diff --git a/src/mmgr/bitio/bitio.c b/src/mmgr/bitio/bitio.c deleted file mode 100644 index ea444634e..000000000 --- a/src/mmgr/bitio/bitio.c +++ /dev/null @@ -1,58 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file bitio.c - * @brief The LSB-first bit writer - see bitio.h. - * - * Bits enter a @c uint32_t accumulator above the bits already buffered, so the first bit written sits - * lowest. Whole bytes leave the low end of the accumulator into the caller's buffer, one per step, - * until fewer than eight bits remain. A byte with @c cnt already at @c cap latches @c overflow and - * empties the accumulator, and a latched writer returns from every later call. - * - * The one symbol this module exports is @ref bitw. - */ - -#include "mmgr/bitio/bitio.h" - -void protocore_bitw_put(protocore_bit_writer *w, uint32_t bits, int n) -{ - if (w->overflow) - { - return; // latched: nbits is no longer a shift distance this can use - } - // Only the low n bits enter the accumulator; anything above them is dropped rather than ORed - // into the bits that follow. - uint32_t low = (n >= 32) ? bits : (bits & ((1u << n) - 1u)); - w->acc |= low << w->nbits; - w->nbits += n; - while (w->nbits >= 8) - { - if (w->cnt >= w->cap) - { - w->overflow = PROTO_TRUE; - w->nbits = 0; - w->acc = 0; - return; - } - w->out[w->cnt] = (uint8_t)(w->acc & 0xFF); - w->cnt++; - w->acc >>= 8; - w->nbits -= 8; - } -} - -void protocore_bitw_align(protocore_bit_writer *w) -{ - if (w->nbits > 0) - { - if (w->cnt >= w->cap) - { - w->overflow = PROTO_TRUE; - return; - } - w->out[w->cnt++] = (uint8_t)(w->acc & 0xFF); - w->acc = 0; - w->nbits = 0; - } -} diff --git a/src/mmgr/bitio/bitio.h b/src/mmgr/bitio/bitio.h deleted file mode 100644 index 5b3519e69..000000000 --- a/src/mmgr/bitio/bitio.h +++ /dev/null @@ -1,81 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file bitio.h - * @brief LSB-first bit writer over a caller-owned byte buffer - one source of truth. - * - * Packs bits LSB-first into a @c uint32_t accumulator, spills whole bytes to the output, and latches - * @c overflow when the buffer is full. The DEFLATE encoder - * (network_drivers/presentation/codec/deflate) and the SSH zlib@openssh.com stream compressor - * (ssh/transport/ssh_zlib) both write their bitstreams through it. - * - * Distinct from bytes.h's @c protocore_bw_* helpers, which are a BYTE-oriented (big-endian) codec cursor. - * This is a BIT writer, for the DEFLATE bitstream. - * - * The module exports one symbol, @ref bitw. The walks live in bitio.c. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_BITIO_H -#define PROTOCORE_BITIO_H - -#include "protocore_config.h" // the entry point: protocore_types.h for the widths - -PROTOCORE_BEGIN_DECLS - -/** @brief LSB-first bit writer over the caller's output buffer; @c overflow latches once @c cap is exceeded. */ -typedef struct -{ - uint8_t *out; - size_t cap; - size_t cnt; ///< bytes written so far - uint32_t acc; ///< bit accumulator (LSB-first) - int nbits; ///< bits currently buffered (< 8 between calls) - proto_bool overflow; -} protocore_bit_writer; - -/** - * @brief The bit-writer module. Bits enter an accumulator at the low end and leave it a byte at a time. - * - * @var BitwNs::put - * Append the low @c n bits of @c bits to @c w, LSB-first, and spill every byte the accumulator - * completes to @c out. A spill with @c cnt already at @c cap sets @c overflow, clears the - * accumulator, and every later call returns at once. - * - * @var BitwNs::align - * Write the partial byte @c w still holds, its high bits zero, then clear the accumulator. Nothing is - * written when @c nbits is zero. A write with @c cnt already at @c cap sets @c overflow instead. - * - * No storage member: the buffer, the cursor and the accumulator all live in the caller's - * ::protocore_bit_writer, and this module holds nothing of its own. - */ -typedef struct -{ - void (*put)(protocore_bit_writer *w, uint32_t bits, int n); - void (*align)(protocore_bit_writer *w); -} BitwNs; - -// The bit walks, in bitio.c. Named here because the table below has to name them, and prefixed -// because that puts them in the linker's namespace. -void protocore_bitw_put(protocore_bit_writer *w, uint32_t bits, int n); -void protocore_bitw_align(protocore_bit_writer *w); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away and the call to the walk in bitio.c is direct, leaving the table referenced by - * nothing for the linker to drop. - * - * `unused` because this header reaches files that take none of it. - */ -// Designated, so a member's position in the struct does not decide what it binds to. -static const BitwNs bitw __attribute__((unused)) = {.put = protocore_bitw_put, .align = protocore_bitw_align}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_BITIO_H diff --git a/src/mmgr/bytes/CMakeLists.txt b/src/mmgr/bytes/CMakeLists.txt deleted file mode 100644 index 30f905841..000000000 --- a/src/mmgr/bytes/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/bytes - SOURCES bytes.c - DEPS - mmgr/endian - mmgr/protomem - mmgr/protostr - mmgr/span -) diff --git a/src/mmgr/bytes/bytes.c b/src/mmgr/bytes/bytes.c deleted file mode 100644 index b31b0b3fd..000000000 --- a/src/mmgr/bytes/bytes.c +++ /dev/null @@ -1,122 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file bytes.c - * @brief The byte verbs - see bytes.h. - * - * Every append tests the room that remains before it stores, latches the region's overflow flag when - * the store does not fit, and advances the cursor either way, so the cursor states the capacity the - * payload needs. - * - * Every bound is a subtraction against the space that remains, taken after the offset is established - * to be within the length, so the subtraction cannot wrap. - * - * The surface this file stands behind is @ref bytes. - */ - -#include "mmgr/bytes/bytes.h" - -// --- append into a protocore_span --- - -void protocore_bw_put(protocore_span *w, uint8_t b) -{ - if (w->pos < w->cap) - { - w->buf[w->pos] = b; - } - else - { - w->overflow = PROTO_TRUE; - } - w->pos++; // keep counting so protocore_span_len() reports the size the payload needs -} - -void protocore_bw_put_be(protocore_span *w, uint64_t val, int32_t nbytes) -{ - for (int32_t s = (nbytes - 1) * 8; s >= 0; s -= 8) - { - protocore_bw_put(w, (uint8_t)(val >> s)); - } -} - -void protocore_bw_bytes(protocore_span *w, const void *src, size_t n) -{ - if (w->buf != NULL && w->pos <= w->cap && w->cap - w->pos >= n) - { - mem.cpy(w->buf + w->pos, src, n); - } - else if (n > 0) - { - w->overflow = PROTO_TRUE; - } - w->pos += n; // keep counting so protocore_span_len() reports the size the payload needs -} - -// --- take out of a protocore_cspan --- - -proto_bool protocore_br_take_be(protocore_cspan *r, size_t nbytes, uint64_t *out) -{ - if (r->pos > r->len || r->len - r->pos < nbytes) - { - r->err = PROTO_TRUE; - return PROTO_FALSE; - } - uint64_t v = 0; - for (size_t i = 0; i < nbytes; i++) - { - v = (v << 8) | r->buf[r->pos + i]; - } - *out = v; - r->pos += nbytes; - return PROTO_TRUE; -} - -// --- offset-passing reads over a caller-owned buffer (no region object needed) --- - -proto_bool protocore_rd_u32(const uint8_t *p, size_t len, size_t *off, uint32_t *out) -{ - if (*off > len || len - *off < 4) - { - return PROTO_FALSE; - } - *out = protocore_rd32be(p + *off); - *off += 4; - return PROTO_TRUE; -} - -proto_bool protocore_rd_str(const uint8_t *p, size_t len, size_t *off, const uint8_t **out, uint32_t *slen) -{ - size_t start = *off; - uint32_t n = 0; - if (!protocore_rd_u32(p, len, off, &n)) - { - return PROTO_FALSE; - } - if (n > len - *off) // protocore_rd_u32 succeeding established *off <= len, so this cannot wrap - { - *off = start; - return PROTO_FALSE; - } - *out = p + *off; - *slen = n; - *off += n; - return PROTO_TRUE; -} - -proto_bool protocore_mpint_to_fixed(const uint8_t *m, uint32_t mlen, uint8_t *out, size_t outlen) -{ - uint32_t off = 0; - while (off < mlen && m[off] == 0) - { - off++; - } - uint32_t vlen = mlen - off; - if (vlen > outlen) - { - return PROTO_FALSE; - } - mem.set(out, 0, outlen); - mem.cpy(out + (outlen - vlen), m + off, vlen); - return PROTO_TRUE; -} diff --git a/src/mmgr/bytes/bytes.h b/src/mmgr/bytes/bytes.h deleted file mode 100644 index 38b275a39..000000000 --- a/src/mmgr/bytes/bytes.h +++ /dev/null @@ -1,113 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file bytes.h - * @brief The byte verbs - append into a protocore_span, take out of a protocore_cspan. - * - * A bounded byte region is one thing with two accessors. span.h is the region: where the storage came - * from, how big it is, how much has been produced, and whether anything overran. This file is what you - * do to it. - * - * A write past the capacity stores nothing, latches the sticky overflow flag, and still advances - * `pos`, so `pos` reports the capacity the payload needs. Widths go out and come back big-endian - * (network order). - * - * These take protocore_span / protocore_cspan directly rather than being written per codec, so one - * concrete pair serves every codec and the field names are fixed rather than restated. - * - * The surface is @ref bytes. The walks are in bytes.c. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_BYTES_H -#define PROTOCORE_BYTES_H - -#include "mmgr/endian/endian.h" // protocore_rd32be - the fixed-width serializers the reads step with -#include "mmgr/protomem/protomem.h" // mem.set / mem.cpy - the byte movers -#include "mmgr/protostr/protostr.h" // str.len - the bounded run length -#include "mmgr/span/span.h" // protocore_span / protocore_cspan - the region these verbs act on - -PROTOCORE_BEGIN_DECLS - -/** - * @brief The byte-verb module: append into a write region, take out of a read region, and walk a - * caller-owned payload by offset. - * - * @var BytesNs::put - * Append one byte to @c w. Past @c cap nothing is stored and the overflow flag latches; @c pos counts - * the byte either way. - * - * @var BytesNs::put_be - * Append the low @c nbytes of @c val most significant byte first, one @ref BytesNs::put per byte. - * - * @var BytesNs::raw - * Append @c n bytes from @c src. Stores when @c w has storage and @c n fits the room that remains, - * otherwise latches the overflow flag; @c pos advances by @c n either way. - * - * @var BytesNs::take_be - * Read @c nbytes big-endian at @c r's cursor and advance past them. A read reaching past the end sets - * the sticky err, leaves the cursor and @c out untouched, and returns false. - * - * Reads at the cursor and nowhere else: no framing byte is consumed here. A codec that leads with a - * tag - CBOR's head byte, MessagePack's format byte - advances past it itself. - * - * @var BytesNs::rd_u32 - * Read a big-endian u32 at @c *off and advance it by 4. False when fewer than four bytes of @c len - * remain, with @c *off left where it started. - * - * @var BytesNs::rd_str - * Read a u32-length-prefixed blob: @c out points into @c p and @c slen is its length. Nothing is - * copied, so the result must not outlive @c p. A length reaching past the end leaves @c *off where it - * started and returns false. SSH names this shape a "string" (RFC 4251 sec 5). - * - * Every bound here subtracts against the space that remains, after establishing @c *off is within - * @c len so the subtraction cannot wrap. size_t is 32 bits on some targets and the length prefix is a - * full u32, so the sum form wraps on a peer-chosen length. - * - * @var BytesNs::mpint_fixed - * Strip an mpint's leading zero bytes and right-align the rest into @c out[@c outlen], zeroing the - * lanes ahead of it. False when the magnitude is wider than @c outlen. - * - * No storage member: every verb works on the caller's region or pointers and holds nothing of its own. - */ -typedef struct -{ - void (*put)(protocore_span *w, uint8_t b); - void (*put_be)(protocore_span *w, uint64_t val, int32_t nbytes); - void (*raw)(protocore_span *w, const void *src, size_t n); - proto_bool (*take_be)(protocore_cspan *r, size_t nbytes, uint64_t *out); - proto_bool (*rd_u32)(const uint8_t *p, size_t len, size_t *off, uint32_t *out); - proto_bool (*rd_str)(const uint8_t *p, size_t len, size_t *off, const uint8_t **out, uint32_t *slen); - proto_bool (*mpint_fixed)(const uint8_t *m, uint32_t mlen, uint8_t *out, size_t outlen); -} BytesNs; - -// The verbs, in bytes.c. Named here because the table below has to name them, and prefixed because -// that puts them in the linker's namespace. -void protocore_bw_put(protocore_span *w, uint8_t b); -void protocore_bw_put_be(protocore_span *w, uint64_t val, int32_t nbytes); -void protocore_bw_bytes(protocore_span *w, const void *src, size_t n); -proto_bool protocore_br_take_be(protocore_cspan *r, size_t nbytes, uint64_t *out); -proto_bool protocore_rd_u32(const uint8_t *p, size_t len, size_t *off, uint32_t *out); -proto_bool protocore_rd_str(const uint8_t *p, size_t len, size_t *off, const uint8_t **out, uint32_t *slen); -proto_bool protocore_mpint_to_fixed(const uint8_t *m, uint32_t mlen, uint8_t *out, size_t outlen); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away and the call to the verb in bytes.c is direct, leaving the table referenced by - * nothing for the linker to drop. - * - * `unused` because a header this wide is included by files that take none of it. - */ -static const BytesNs bytes - __attribute__((unused)) = {protocore_bw_put, protocore_bw_put_be, protocore_bw_bytes, protocore_br_take_be, - protocore_rd_u32, protocore_rd_str, protocore_mpint_to_fixed}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_BYTES_H diff --git a/src/mmgr/dma/CMakeLists.txt b/src/mmgr/dma/CMakeLists.txt deleted file mode 100644 index c6323fb71..000000000 --- a/src/mmgr/dma/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/dma - GATE PROTOCORE_ENABLE_DMA - SOURCES dma.c -) diff --git a/src/mmgr/dma/dma.c b/src/mmgr/dma/dma.c deleted file mode 100644 index a75bc54b8..000000000 --- a/src/mmgr/dma/dma.c +++ /dev/null @@ -1,75 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file dma.c - * @brief DMA peripheral ingest / egress - implementation. - * - * The front end validates and dispatches to the weak protocore_dma_hw_* hooks a driver overrides. - * The host build overrides them too (test/core_setup/hal/host/protocore_dma_host.h), so the arm that runs on - * silicon is the arm the tests drive. - */ - -#include "protocore_config.h" // the entry point: the enable gate below, and the widths - -#if PROTOCORE_ENABLE_DMA - -#include "mmgr/dma/dma.h" - -PROTOCORE_BEGIN_DECLS - -// The driver stamps a completion, so the clock is its dependency rather than this front end's. -__attribute__((weak)) proto_bool protocore_dma_hw_open(const protocore_dma_config *cfg) -{ - (void)cfg; - return PROTO_FALSE; -} -__attribute__((weak)) proto_bool protocore_dma_hw_tx_submit(uint8_t ch, const uint8_t *buf, uint16_t len) -{ - (void)ch; - (void)buf; - (void)len; - return PROTO_FALSE; -} -__attribute__((weak)) void protocore_dma_hw_close(uint8_t ch) -{ - (void)ch; -} -__attribute__((weak)) void protocore_dma_hw_poll(void) -{ -} - -proto_bool protocore_dma_open(const protocore_dma_config *cfg) -{ - if (!cfg || !cfg->on_complete || cfg->channel >= PROTOCORE_DMA_CHANNELS) - { - return PROTO_FALSE; - } - return protocore_dma_hw_open(cfg); -} - -proto_bool protocore_dma_tx_submit(uint8_t ch, const uint8_t *buf, uint16_t len) -{ - if (ch >= PROTOCORE_DMA_CHANNELS || !buf || len == 0 || len > PROTOCORE_DMA_BUF_SIZE) - { - return PROTO_FALSE; - } - return protocore_dma_hw_tx_submit(ch, buf, len); -} - -void protocore_dma_close(uint8_t ch) -{ - if (ch < PROTOCORE_DMA_CHANNELS) - { - protocore_dma_hw_close(ch); - } -} - -void protocore_dma_poll(void) -{ - protocore_dma_hw_poll(); -} - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_ENABLE_DMA diff --git a/src/mmgr/dma/dma.h b/src/mmgr/dma/dma.h deleted file mode 100644 index bbea996ac..000000000 --- a/src/mmgr/dma/dma.h +++ /dev/null @@ -1,135 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file dma.h - * @brief DMA peripheral ingest / egress (PROTOCORE_ENABLE_DMA) - the v5 high-throughput - * hardware-ingest path. - * - * A DMA channel moves bytes between a peripheral (UART / I2C / SPI) and a static - * buffer while the CPU is free, then a DMA-complete event carries the result up. - * Two directions: - * - * - RX (ingress): peripheral -> DMA -> buffer. On completion the channel emits a - * @ref protocore_dma_event whose `data`/`len` point at the just-filled buffer. RX is - * **double-buffered (ping-pong)**: the completed buffer is handed to the callback - * while the engine fills the other, so there is a full transfer of headroom to - * consume it before it is reused. - * - TX (egress): buffer -> DMA -> peripheral. The caller submits bytes; on - * completion the channel emits a TX event (data == nullptr) so the producer knows - * the buffer is free to refill. - * - * The completion callback runs in ISR context on real silicon, so keep it tiny - the - * intended pattern is to post the event into the preempting work queue - * (services/system/preempt_queue) with protocore_pq_post_from_isr(), letting a high-priority task - * do the real work off the interrupt. protocore_dma stays decoupled from the queue: it just - * hands you the event. - * - * - * Zero-heap: PROTOCORE_DMA_CHANNELS channels, each with 2x PROTOCORE_DMA_BUF_SIZE RX + one TX - * buffer + the simulator's ingress/egress staging, all static and compile-time sized. - * Fail-closed: a submit onto a busy channel or a feed past the staging capacity returns - * false rather than blocking or overrunning. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_DMA_H -#define PROTOCORE_DMA_H - -#include "protocore_config.h" // the entry point: protocore_types.h for the widths - -#if PROTOCORE_ENABLE_DMA - -PROTOCORE_BEGIN_DECLS - -/** @brief Peripheral a channel is bound to (informational; selects the real backend). */ -typedef enum PROTO_ENUM_PACKED -{ - PROTOCORE_DMA_UART = 0, - PROTOCORE_DMA_I2C = 1, - PROTOCORE_DMA_SPI = 2, -} protocore_dma_periph; - -/** @brief Transfer direction carried on a completion event. */ -typedef enum PROTO_ENUM_PACKED -{ - PROTOCORE_DMA_RX = 0, ///< ingress: peripheral -> buffer - PROTOCORE_DMA_TX = 1, ///< egress: buffer -> peripheral -} protocore_dma_dir; - -/** - * @brief A DMA-complete event handed to the channel callback. - * - * For RX, @ref data / @ref len point at the completed ping-pong buffer - valid only - * until that buffer is reused (a transfer or two later). Consume it inside the callback, - * or, if you hand the work to another task (e.g. post it to the preempting queue), copy - * the @ref len bytes into the posted item: a deferred consumer can lag past the buffer's - * reuse under load, so post the bytes, not this pointer. For TX, @ref data is nullptr and - * @ref len is the number of bytes drained. - */ -typedef struct -{ - const uint8_t *data; ///< RX: received bytes (into a ping-pong buffer); TX: nullptr - uint32_t t_ms; ///< protocore_millis() at completion (0 on host builds) - uint32_t t_us; ///< protocore_micros() at completion (0 on host builds) - a high-rate - ///< peripheral (SPI slave DMA off a fast external DAQ/scope) can - ///< complete several transfers inside one t_ms tick; use t_us to - ///< measure inter-transfer jitter / trigger latency at that rate. - uint16_t len; ///< bytes transferred - uint16_t seq; ///< per-channel completion sequence (wraps) - uint8_t channel; ///< channel id [0, PROTOCORE_DMA_CHANNELS) - protocore_dma_periph periph; ///< protocore_dma_periph - protocore_dma_dir dir; ///< protocore_dma_dir - uint8_t _pad; -} protocore_dma_event; - -/** - * @brief Called once per completed transfer (RX and TX). ISR context on real silicon, - * so keep it tiny (the canonical body posts @p ev to the preempting queue). - * @param ev the completion event (owned by the caller; copy what you need). - * @param ctx the opaque pointer from @ref protocore_dma_config. - */ -typedef void (*protocore_dma_cb)(const protocore_dma_event *ev, void *ctx); - -/** @brief Channel configuration passed to protocore_dma_open(). */ -typedef struct -{ - uint8_t channel; ///< channel id [0, PROTOCORE_DMA_CHANNELS). - protocore_dma_periph periph; ///< protocore_dma_periph the channel drives. - proto_bool loopback; ///< simulator: this channel's TX egress feeds its own RX ingress. - protocore_dma_cb on_complete; ///< completion callback (required). - void *ctx; ///< opaque, forwarded to @ref on_complete. -} protocore_dma_config; - -/** - * @brief Configure a channel and arm its RX transfer. - * @return true if opened; false on a bad channel id / null callback / already open. - */ -proto_bool protocore_dma_open(const protocore_dma_config *cfg); - -/** - * @brief Submit bytes for egress DMA on channel @p ch (copies up to PROTOCORE_DMA_BUF_SIZE). - * - * Fail-closed: returns false if a TX is still in flight on the channel (wait for its - * TX-complete event), if the channel is closed, or on a null / oversize buffer. - * @return true if the transfer was accepted. - */ -proto_bool protocore_dma_tx_submit(uint8_t ch, const uint8_t *buf, uint16_t len); - -/** @brief Close a channel and drop any in-flight transfer / staged simulator bytes. */ -void protocore_dma_close(uint8_t ch); - -/** - * @brief Advance the simulator engine: drain egress, run loopback, complete RX/TX and - * fire the callbacks. No-op on the real silicon backend (ISRs drive completion). - * This is how the host and the on-device self-test step the pipeline. - */ -void protocore_dma_poll(void); - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_ENABLE_DMA - -#endif // PROTOCORE_DMA_H diff --git a/src/mmgr/endian/CMakeLists.txt b/src/mmgr/endian/CMakeLists.txt deleted file mode 100644 index be5ccd1e2..000000000 --- a/src/mmgr/endian/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/endian - SOURCES endian.c -) diff --git a/src/mmgr/endian/endian.c b/src/mmgr/endian/endian.c deleted file mode 100644 index 661708395..000000000 --- a/src/mmgr/endian/endian.c +++ /dev/null @@ -1,109 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file endian.c - * @brief A fixed width moved between an integer and the bytes at a pointer - see endian.h. - * - * One byte per step, never a cast to a wider pointer: a store lands on a byte boundary, so a target - * that faults on an unaligned wide access is served, and the shift naming each byte fixes the order - * regardless of the machine's own. - * - * The one symbol this file exports is @ref endian. - */ - -#include "mmgr/endian/endian.h" - -// --- little-endian ------------------------------------------------------------------------------ - -size_t protocore_wr16le(uint8_t *p, uint16_t v) -{ - p[0] = (uint8_t)v; - p[1] = (uint8_t)(v >> 8); - return 2; -} - -size_t protocore_wr32le(uint8_t *p, uint32_t v) -{ - p[0] = (uint8_t)v; - p[1] = (uint8_t)(v >> 8); - p[2] = (uint8_t)(v >> 16); - p[3] = (uint8_t)(v >> 24); - return 4; -} - -size_t protocore_wr64le(uint8_t *p, uint64_t v) -{ - for (int i = 0; i < 8; i++) - { - p[i] = (uint8_t)(v >> (8 * i)); - } - return 8; -} - -uint16_t protocore_rd16le(const uint8_t *p) -{ - return (uint16_t)((uint16_t)p[0] | ((uint16_t)p[1] << 8)); -} - -uint32_t protocore_rd32le(const uint8_t *p) -{ - return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); -} - -uint64_t protocore_rd64le(const uint8_t *p) -{ - uint64_t v = 0; - for (int i = 0; i < 8; i++) - { - v |= (uint64_t)p[i] << (8 * i); - } - return v; -} - -// --- big-endian (network order) ----------------------------------------------------------------- - -size_t protocore_wr16be(uint8_t *p, uint16_t v) -{ - p[0] = (uint8_t)(v >> 8); - p[1] = (uint8_t)v; - return 2; -} - -size_t protocore_wr32be(uint8_t *p, uint32_t v) -{ - p[0] = (uint8_t)(v >> 24); - p[1] = (uint8_t)(v >> 16); - p[2] = (uint8_t)(v >> 8); - p[3] = (uint8_t)v; - return 4; -} - -size_t protocore_wr64be(uint8_t *p, uint64_t v) -{ - for (int i = 0; i < 8; i++) - { - p[i] = (uint8_t)(v >> (8 * (7 - i))); - } - return 8; -} - -uint16_t protocore_rd16be(const uint8_t *p) -{ - return (uint16_t)(((uint16_t)p[0] << 8) | (uint16_t)p[1]); -} - -uint32_t protocore_rd32be(const uint8_t *p) -{ - return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3]; -} - -uint64_t protocore_rd64be(const uint8_t *p) -{ - uint64_t v = 0; - for (int i = 0; i < 8; i++) - { - v = (v << 8) | p[i]; - } - return v; -} diff --git a/src/mmgr/endian/endian.h b/src/mmgr/endian/endian.h deleted file mode 100644 index baca3003e..000000000 --- a/src/mmgr/endian/endian.h +++ /dev/null @@ -1,128 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file endian.h - * @brief A fixed width moved between an integer and the bytes at a pointer. - * - * A width is all this file knows, so the bound is not its to check. mmgr/span.h holds - * the bound and hands out a pointer to bytes it has already proven; a width is read or written there. - * - * Writers return their width (2/4/8) so a caller can advance by it. - * - * Byte at a time, never a cast to a wider pointer: correct where loads must be aligned, and correct - * on either byte order. - * - * The module exports one symbol, @ref endian. The moves themselves are in endian.c. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_ENDIAN_H -#define PROTOCORE_ENDIAN_H - -#include "protocore_config.h" // the entry point: protocore_types.h for the widths - -PROTOCORE_BEGIN_DECLS - -/** - * @brief The fixed-width serializer module. Each entry steps one byte at a time over 2, 4 or 8 bytes. - * - * @var EndianNs::wr16le - * Write @c v at @c p low byte first, @c p[0] taking bits 0..7. Returns 2. - * - * @var EndianNs::wr32le - * Write @c v at @c p low byte first, each later byte shifted down another 8 bits. Returns 4. - * - * @var EndianNs::wr64le - * Write @c v at @c p low byte first, eight steps of the same shift. Returns 8. - * - * @var EndianNs::rd16le - * Read a u16 at @c p taken low byte first: @c p[0] is bits 0..7, @c p[1] shifted up 8. - * - * @var EndianNs::rd32le - * Read a u32 at @c p taken low byte first, each later byte shifted up another 8 bits. - * - * @var EndianNs::rd64le - * Read a u64 at @c p taken low byte first, eight bytes ORed in at their own shift. - * - * @var EndianNs::wr16be - * Write @c v at @c p high byte first, @c p[0] taking bits 8..15. Returns 2. - * - * @var EndianNs::wr32be - * Write @c v at @c p high byte first, each later byte shifted down another 8 bits. Returns 4. - * - * @var EndianNs::wr64be - * Write @c v at @c p high byte first, eight steps down from bits 56..63. Returns 8. - * - * @var EndianNs::rd16be - * Read a u16 at @c p taken high byte first: @c p[0] shifted up 8, @c p[1] is bits 0..7. - * - * @var EndianNs::rd32be - * Read a u32 at @c p taken high byte first, @c p[0] shifted up 24. - * - * @var EndianNs::rd64be - * Read a u64 at @c p taken high byte first, the accumulator shifted up 8 per byte. - * - * No storage member: every entry moves bytes between the caller's integer and the caller's pointer - * and holds nothing of its own. - */ -typedef struct -{ - size_t (*wr16le)(uint8_t *p, uint16_t v); - size_t (*wr32le)(uint8_t *p, uint32_t v); - size_t (*wr64le)(uint8_t *p, uint64_t v); - uint16_t (*rd16le)(const uint8_t *p); - uint32_t (*rd32le)(const uint8_t *p); - uint64_t (*rd64le)(const uint8_t *p); - size_t (*wr16be)(uint8_t *p, uint16_t v); - size_t (*wr32be)(uint8_t *p, uint32_t v); - size_t (*wr64be)(uint8_t *p, uint64_t v); - uint16_t (*rd16be)(const uint8_t *p); - uint32_t (*rd32be)(const uint8_t *p); - uint64_t (*rd64be)(const uint8_t *p); -} EndianNs; - -// The width moves, in endian.c. Named here because the table below has to name them, and prefixed -// because that puts them in the linker's namespace. -size_t protocore_wr16le(uint8_t *p, uint16_t v); -size_t protocore_wr32le(uint8_t *p, uint32_t v); -size_t protocore_wr64le(uint8_t *p, uint64_t v); -uint16_t protocore_rd16le(const uint8_t *p); -uint32_t protocore_rd32le(const uint8_t *p); -uint64_t protocore_rd64le(const uint8_t *p); -size_t protocore_wr16be(uint8_t *p, uint16_t v); -size_t protocore_wr32be(uint8_t *p, uint32_t v); -size_t protocore_wr64be(uint8_t *p, uint64_t v); -uint16_t protocore_rd16be(const uint8_t *p); -uint32_t protocore_rd32be(const uint8_t *p); -uint64_t protocore_rd64be(const uint8_t *p); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away and the call to the move in endian.c is direct, leaving the table referenced by - * nothing for the linker to drop. - * - * `unused` because this header reaches files that take none of it. - */ -// Designated, so a member's position in the struct does not decide what it binds to. -static const EndianNs endian __attribute__((unused)) = {.wr16le = protocore_wr16le, - .wr32le = protocore_wr32le, - .wr64le = protocore_wr64le, - .rd16le = protocore_rd16le, - .rd32le = protocore_rd32le, - .rd64le = protocore_rd64le, - .wr16be = protocore_wr16be, - .wr32be = protocore_wr32be, - .wr64be = protocore_wr64be, - .rd16be = protocore_rd16be, - .rd32be = protocore_rd32be, - .rd64be = protocore_rd64be}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_ENDIAN_H diff --git a/src/mmgr/float_bits/CMakeLists.txt b/src/mmgr/float_bits/CMakeLists.txt deleted file mode 100644 index 4c157d86f..000000000 --- a/src/mmgr/float_bits/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/float_bits - SOURCES float_bits.c - PRIVATE_DEPS - mmgr/rawmemcpy -) diff --git a/src/mmgr/float_bits/float_bits.c b/src/mmgr/float_bits/float_bits.c deleted file mode 100644 index 84dc11f1b..000000000 --- a/src/mmgr/float_bits/float_bits.c +++ /dev/null @@ -1,46 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file float_bits.c - * @brief The binary64 field reads - see float_bits.h. - * - * Every read takes the eight bytes at the double's address as one integer and cuts the wanted field - * out of it with a mask and a shift. The merge runs the same arithmetic backwards, and from_bits - * moves the bytes into a double. - * - * The one symbol this file exports is @ref dbl. - */ - -#include "mmgr/float_bits/float_bits.h" -#include "mmgr/rawmemcpy/rawmemcpy.h" // proto_raw_u64 / proto_raw_read - the bit read and the byte move - -proto_u64 proto_dbl_sign(double v) -{ - return (proto_raw_u64(&v) & PROTO_DBL_SIGN_MASK) >> PROTO_DBL_SIGN_SHIFT; -} - -proto_u64 proto_dbl_exp(double v) -{ - return (proto_raw_u64(&v) & PROTO_DBL_EXP_MASK) >> PROTO_DBL_MANT_BITS; -} - -proto_u64 proto_dbl_mant(double v) -{ - return proto_raw_u64(&v) & PROTO_DBL_MANT_MASK; -} - -// Each field is masked to its own width before it is shifted, so a bit above a field stays out of -// the one above it. -proto_u64 proto_dbl_merge(proto_u64 sign, proto_u64 exp, proto_u64 mant) -{ - return ((sign & PROTO_DBL_SIGN_ONE) << PROTO_DBL_SIGN_SHIFT) | ((exp & PROTO_DBL_EXP_ALL) << PROTO_DBL_MANT_BITS) | - (mant & PROTO_DBL_MANT_MASK); -} - -double proto_dbl_from_bits(proto_u64 bits) -{ - double v = 0.0; - proto_raw_read(&v, &bits, sizeof(v)); - return v; -} diff --git a/src/mmgr/float_bits/float_bits.h b/src/mmgr/float_bits/float_bits.h deleted file mode 100644 index 36a701d3f..000000000 --- a/src/mmgr/float_bits/float_bits.h +++ /dev/null @@ -1,89 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file float_bits.h - * @brief A double read as the three fields it is: sign, exponent, mantissa. - * - * 63 62 52 51 0 - * +--+-----------+----------------------------------------------------+ - * | s| exponent | mantissa | - * +--+-----------+----------------------------------------------------+ - * - * The module exports one symbol, @ref dbl. The field reads live in float_bits.c. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_FLOAT_BITS_H -#define PROTOCORE_FLOAT_BITS_H - -#include "protocore_config.h" // proto_u64 - the integer one double's bits fill - -PROTOCORE_BEGIN_DECLS - -#define PROTO_DBL_SIGN_MASK 0x8000000000000000ull ///< bit 63 -#define PROTO_DBL_EXP_MASK 0x7FF0000000000000ull ///< bits 62..52 -#define PROTO_DBL_MANT_MASK 0x000FFFFFFFFFFFFFull ///< bits 51..0 -#define PROTO_DBL_SIGN_SHIFT 63u -#define PROTO_DBL_MANT_BITS 52u -#define PROTO_DBL_SIGN_ONE 0x1ull ///< the sign field, shifted down -#define PROTO_DBL_EXP_ALL 0x7FFull ///< the exponent field, shifted down: all ones is an inf or a NaN -#define PROTO_DBL_BIAS 1023 ///< subtracted from the exponent field to get the power of two - -/** - * @brief The binary64 field module. Each read is one mask and one shift over the bits at the - * double's own address; each write is the mirror. - * - * @var DblNs::sign - * The sign bit of @c v as 0 or 1. - * - * @var DblNs::exp - * The exponent field of @c v, still biased. ::PROTO_DBL_BIAS comes off it for the power of two. - * - * @var DblNs::mant - * The mantissa field of @c v, without the implicit leading bit a normal value carries. - * - * @var DblNs::merge - * The three fields, each masked to its own width and shifted into place, ORed: the bits of the - * double they describe. Bits above a field's width are dropped rather than carried into the next. - * - * @var DblNs::from_bits - * The double those bits are. - * - * No storage member: every entry point works on the caller's value and holds nothing of its own. - */ -typedef struct -{ - proto_u64 (*sign)(double v); - proto_u64 (*exp)(double v); - proto_u64 (*mant)(double v); - proto_u64 (*merge)(proto_u64 sign, proto_u64 exp, proto_u64 mant); - double (*from_bits)(proto_u64 bits); -} DblNs; - -// The field reads, in float_bits.c. Named here because the table below has to name them, and -// prefixed because that puts them in the linker's namespace. -proto_u64 proto_dbl_sign(double v); -proto_u64 proto_dbl_exp(double v); -proto_u64 proto_dbl_mant(double v); -proto_u64 proto_dbl_merge(proto_u64 sign, proto_u64 exp, proto_u64 mant); -double proto_dbl_from_bits(proto_u64 bits); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away and the call to the field read in float_bits.c is direct, leaving the table - * referenced by nothing for the linker to drop. - * - * `unused` because this header is included by files that take none of it. - */ -static const DblNs dbl - __attribute__((unused)) = {proto_dbl_sign, proto_dbl_exp, proto_dbl_mant, proto_dbl_merge, proto_dbl_from_bits}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_FLOAT_BITS_H diff --git a/src/mmgr/membuild/CMakeLists.txt b/src/mmgr/membuild/CMakeLists.txt deleted file mode 100644 index d849ca23b..000000000 --- a/src/mmgr/membuild/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/membuild - SOURCES membuild.c - PRIVATE_DEPS - mmgr/float_bits - mmgr/protostr - mmgr/rawmemcpy - shared/hex -) diff --git a/src/mmgr/membuild/membuild.c b/src/mmgr/membuild/membuild.c deleted file mode 100644 index 58809ccd7..000000000 --- a/src/mmgr/membuild/membuild.c +++ /dev/null @@ -1,659 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file membuild.c - * @brief The bounded no-heap builder - see membuild.h. - * - * Each append tests @c ok, measures the field it is about to write, checks the one bound against - * @c cap, then writes in place. A number is filled back-to-front where it lands, so nothing here - * needs a scratch array. The float renderings take the value apart as the sign, exponent and - * mantissa it is and scale an `n * 2^s` pair by whole decades, so the digits come off integers. - * - * The names @ref Sb aliases are defined here. Everything else in this file has internal linkage. - */ - -#include "mmgr/membuild/membuild.h" -#include "mmgr/float_bits/float_bits.h" // proto_dbl_sign / proto_dbl_exp / proto_dbl_mant - the field reads -#include "mmgr/protostr/protostr.h" // str.len - a word per test, bounded by a known width -#include "mmgr/rawmemcpy/rawmemcpy.h" // proto_raw_read - the span move protocore_sb_put_n is built on -#include "shared/hex/hex.h" // PROTOCORE_HEX: the shared digit tables - -/// @brief Working width of the `n * 2^s` pair below: four bits clear of the top so a decade fits. -#define PROTOCORE_G_WORK_BITS 58u - -void protocore_sb_put_n(protocore_sb *b, const char *s, size_t sl) -{ - if (!b->ok) - { - return; - } - if (b->len + sl >= b->cap) - { - b->ok = PROTO_FALSE; - return; - } - // The destination is a position inside the caller's buffer, so the exact mover: the bytes past - // the append still belong to whoever owns the rest of it. - proto_raw_read(b->p + b->len, s, sl); - b->len += sl; -} - -void protocore_sb_put(protocore_sb *b, const char *s) -{ - if (!b->ok) - { - return; - } - protocore_sb_put_n(b, s, str.len(s, b->cap)); -} - -void protocore_sb_put_clip(protocore_sb *b, const char *s) -{ - if (!b->ok || !s || b->len + 1 >= b->cap) - { - return; - } - size_t room = b->cap - b->len - 1; - size_t sl = str.len(s, room); - // The destination is a position inside the caller's buffer, so the exact mover: the bytes past - // the append still belong to whoever owns the rest of it. - proto_raw_read(b->p + b->len, s, sl); - b->len += sl; -} - -void protocore_sb_u64_clip(protocore_sb *b, uint64_t v, uint8_t columns) -{ - if (!b->ok) - { - return; - } - uint64_t probe = v; - size_t digits = 1; - while (probe >= 10) - { - probe /= 10; - digits++; - } - size_t width = (digits < columns) ? columns : digits; - if (b->len + width >= b->cap) - { - return; - } - for (size_t i = width - digits; i-- > 0;) - { - b->p[b->len + i] = ' '; - } - for (size_t i = width; i-- > width - digits;) - { - b->p[b->len + i] = (char)('0' + (unsigned)(v % 10)); - v /= 10; - } - b->len += width; -} - -void protocore_sb_xml(protocore_sb *b, const char *s) -{ - if (!b->ok || !s) - { - return; - } - for (; *s; s++) - { - const char *rep = NULL; - switch (*s) - { - case '&': - rep = "&"; - break; - case '<': - rep = "<"; - break; - case '>': - rep = ">"; - break; - case '"': - rep = """; - break; - default: - break; - } - if (rep) - { - protocore_sb_put(b, rep); - } - else - { - if (b->len + 1 >= b->cap) - { - b->ok = PROTO_FALSE; - return; - } - b->p[b->len] = *s; - b->len++; - } - } -} - -void protocore_sb_ch(protocore_sb *b, char c) -{ - if (!b->ok) - { - return; - } - if (b->len + 1 >= b->cap) - { - b->ok = PROTO_FALSE; - return; - } - b->p[b->len++] = c; -} - -void protocore_sb_uint(protocore_sb *b, uint64_t v, unsigned base, unsigned min_digits) -{ - if (!b->ok) - { - return; - } - // A power-of-two base is a bit field, not an arithmetic one: one hex digit IS four bits and - // one octal digit IS three, so extracting them is a shift and a mask. Only base 10 has to - // divide. Naming the width says which it is; the constants are the digit width, not a - // hand-tuned bit pattern. - const unsigned bits_per_digit = (base == 16) ? 4u : (base == 8) ? 3u : 0u; - const proto_bool power_of_two = bits_per_digit != 0; - const uint64_t digit_mask = power_of_two ? ((1ull << bits_per_digit) - 1u) : 0u; - - // Decimal on a value that fits 32 bits uses 32-bit arithmetic: these cores are 32-bit, so a - // uint64_t `/= 10` is a software divide call per digit. Hex and octal shift, so neither cares. - const proto_bool narrow = !power_of_two && v <= 0xFFFFFFFFu; - - uint64_t probe = v; - unsigned digits = 1; - if (power_of_two) - { - while ((probe >>= bits_per_digit) != 0) - { - digits++; - } - } - else if (narrow) - { - uint32_t p32 = (uint32_t)v; - while (p32 >= 10u) - { - p32 /= 10u; - digits++; - } - } - else - { - while (probe >= 10) - { - probe /= 10; - digits++; - } - } - if (digits < min_digits) - { - digits = min_digits; - } - if (b->len + digits >= b->cap) - { - b->ok = PROTO_FALSE; - return; - } - if (power_of_two) - { - for (unsigned i = digits; i-- > 0;) - { - b->p[b->len + i] = PROTOCORE_HEX.lower[v & digit_mask]; - v >>= bits_per_digit; - } - } - else if (narrow) - { - uint32_t v32 = (uint32_t)v; - for (unsigned i = digits; i-- > 0;) - { - b->p[b->len + i] = (char)('0' + (unsigned)(v32 % 10u)); - v32 /= 10u; - } - } - else - { - for (unsigned i = digits; i-- > 0;) - { - b->p[b->len + i] = (char)('0' + (unsigned)(v % 10)); - v /= 10; - } - } - b->len += digits; -} - -void protocore_sb_u32w(protocore_sb *b, uint32_t v, unsigned min_digits) -{ - protocore_sb_uint(b, v, 10, min_digits); -} - -void protocore_sb_hex(protocore_sb *b, uint64_t v, unsigned min_digits) -{ - protocore_sb_uint(b, v, 16, min_digits); -} - -void protocore_sb_u32(protocore_sb *b, uint32_t v) -{ - protocore_sb_uint(b, v, 10, 1); -} - -void protocore_sb_u64(protocore_sb *b, uint64_t v) -{ - protocore_sb_uint(b, v, 10, 1); -} - -void protocore_sb_i64(protocore_sb *b, int64_t v) -{ - // Negating INT64_MIN overflows, so the magnitude is taken through unsigned arithmetic - // rather than by negating the signed value. - uint64_t mag = (v < 0) ? (uint64_t)(-(v + 1)) + 1u : (uint64_t)v; - if (v < 0) - { - protocore_sb_ch(b, '-'); - } - protocore_sb_uint(b, mag, 10, 1); -} - -proto_bool protocore_signbit(double v) -{ - return proto_dbl_sign(v) != 0u; -} - -proto_bool protocore_isinf(double v) -{ - return proto_dbl_exp(v) == 0x7FFu && proto_dbl_mant(v) == 0u; -} - -proto_bool protocore_isnan(double v) -{ - return proto_dbl_exp(v) == 0x7FFu && proto_dbl_mant(v) != 0u; -} - -// Emit @p digits decimal digits of @p mant, with a '.' after the first @p point_after. Peels digits -// by division so no scratch array is needed. @p point_after of 0 or of @p digits emits no point. -static void sb_digits(protocore_sb *b, uint64_t mant, unsigned digits, unsigned point_after) -{ - uint64_t div = 1; - for (unsigned i = 1; i < digits; i++) - { - div *= 10; - } - for (unsigned i = 0; i < digits; i++) - { - if (i == point_after && i != 0) - { - protocore_sb_ch(b, '.'); - } - protocore_sb_ch(b, (char)('0' + (unsigned)((mant / div) % 10))); - div /= 10; - } -} - -// Renormalize `n * 2^s` so @p n sits in the top half of the working width. -static void g_renorm(proto_u64 *n, proto_i32 *s) -{ - if (*n == 0u) - { - return; - } - while (*n >= (1ull << PROTOCORE_G_WORK_BITS)) - { - *n >>= 1; - *s += 1; - } - while (*n < (1ull << (PROTOCORE_G_WORK_BITS - 1u))) - { - *n <<= 1; - *s -= 1; - } -} - -// Multiply the pair by ten. -static void g_mul10(proto_u64 *n, proto_i32 *s) -{ - *n *= 10u; - g_renorm(n, s); -} - -// Divide the pair by ten, shifting up first so the divide keeps the low bits. -static void g_div10(proto_u64 *n, proto_i32 *s) -{ - *n <<= 4; - *s -= 4; - *n /= 10u; - g_renorm(n, s); -} - -// The integer part of `n * 2^s`, rounded half to even on the bits below the point. The tie is the -// case where those bits are one followed by zeros, and it goes toward the even digit. -static proto_u64 g_round(proto_u64 n, proto_i32 s) -{ - if (s >= 0) - { - return n << (unsigned)s; - } - unsigned sh = (unsigned)(-s); - if (sh >= 64u) - { - return 0u; - } - proto_u64 r = n >> sh; - proto_u64 rem = n - (r << sh); - proto_u64 half = 1ull << (sh - 1u); - if (rem > half || (rem == half && (r & 1u) != 0u)) - { - r++; - } - return r; -} - -void protocore_sb_g(protocore_sb *b, double v, unsigned sig) -{ - if (!b->ok) - { - return; - } - if (sig == 0) - { - sig = 1; - } - if (protocore_isnan(v)) - { - protocore_sb_put(b, "nan"); - return; - } - // `v < 0` is false for -0.0, but printf emits "-0" for it. The sign is a single bit of the - // encoding, so it is read with a mask rather than recovered by dividing into it. - if (protocore_signbit(v)) - { - protocore_sb_ch(b, '-'); - v = -v; - } - if (protocore_isinf(v)) - { - protocore_sb_put(b, "inf"); - return; - } - proto_u64 be = proto_dbl_exp(v); - proto_u64 n = proto_dbl_mant(v); - if (be == 0u && n == 0u) - { - protocore_sb_ch(b, '0'); - return; - } - - // The value IS n * 2^s. A normal carries an implicit 1 above the stored mantissa; a subnormal - // stores no leading 1 and denotes an exponent field of 1. - proto_i32 s = 1 - PROTO_DBL_BIAS - (proto_i32)PROTO_DBL_MANT_BITS; - if (be != 0u) - { - n |= 1ull << PROTO_DBL_MANT_BITS; - s = (proto_i32)be - PROTO_DBL_BIAS - (proto_i32)PROTO_DBL_MANT_BITS; - } - g_renorm(&n, &s); - - proto_u64 limit = 1u; - for (unsigned i = 0; i < sig; i++) - { - limit *= 10u; - } - - // The binary exponent gives the decimal one to within a step, log10(2) being 78913/2^18. The - // renormalize left the value in [2^(WORK-1+s), 2^(WORK+s)), and the settle below closes the step. - int e = (int)(((int64_t)((int)PROTOCORE_G_WORK_BITS - 1 + s) * 78913) >> 18); - - // Whole decades onto the pair, so the scale is a multiply or a divide by ten and never a power - // of ten that leaves the range. - int p = (int)sig - 1 - e; - while (p > 0) - { - g_mul10(&n, &s); - p--; - } - while (p < 0) - { - g_div10(&n, &s); - p++; - } - - // A decade out either way is one more step on the pair, then the digits are taken again from - // the unrounded value rather than rounded a second time. - proto_u64 mant = g_round(n, s); - for (unsigned guard = 0; guard < 4u; guard++) - { - if (mant >= limit) // the round carried into a new decade (9.9995 -> 10.000) - { - g_div10(&n, &s); - e++; - } - else if (sig > 1u && mant < limit / 10u) - { - g_mul10(&n, &s); - e--; - } - else - { - break; - } - mant = g_round(n, s); - } - - unsigned digits = sig; - while (digits > 1 && mant % 10 == 0) // %g strips trailing zeros - { - mant /= 10; - digits--; - } - - if (e < -4 || e >= (int)sig) // scientific, matching %g's threshold - { - sb_digits(b, mant, digits, 1); - protocore_sb_ch(b, 'e'); - protocore_sb_ch(b, e < 0 ? '-' : '+'); - unsigned mag = (unsigned)(e < 0 ? -e : e); - protocore_sb_u32w(b, mag, 2); // %g always emits at least two exponent digits - return; - } - if (e >= (int)digits - 1) // integral: all significant digits, then padding zeros - { - sb_digits(b, mant, digits, 0); - for (int i = 0; i < e - (int)digits + 1; i++) - { - protocore_sb_ch(b, '0'); - } - return; - } - if (e >= 0) - { - sb_digits(b, mant, digits, (unsigned)e + 1); - return; - } - protocore_sb_put(b, "0."); - for (int i = 0; i < -e - 1; i++) - { - protocore_sb_ch(b, '0'); - } - sb_digits(b, mant, digits, 0); -} - -void protocore_sb_fixed(protocore_sb *b, double v, unsigned decimals) -{ - if (!b->ok) - { - return; - } - if (protocore_isnan(v)) - { - protocore_sb_put(b, "nan"); - return; - } - // Same negative-zero rule as protocore_sb_g, read from the sign bit. - if (protocore_signbit(v)) - { - protocore_sb_ch(b, '-'); - v = -v; - } - if (protocore_isinf(v)) - { - protocore_sb_put(b, "inf"); - return; - } - // Beyond the 64-bit range the integer part cannot go through uint64 at all - the cast wraps. - // An exact %f expansion of such a magnitude needs big-integer arithmetic (~309 digits), so it - // falls back to the significant-digit form rather than rendering a wrapped value. "At or above - // 2^64" is the exponent field alone: 64 unbiased is 1023 + 64 biased. - if (proto_dbl_exp(v) >= (PROTO_DBL_BIAS + 64)) - { - protocore_sb_g(b, v, 10); // 10 is the precision protocore_sb_g is exact to - return; - } - if (decimals > 18u) // 10^19 leaves the 64-bit range the carry check below is done in - { - decimals = 18u; - } - proto_u64 scale = 1u; - for (unsigned i = 0; i < decimals; i++) - { - scale *= 10u; - } - - // The value IS mant * 2^exp2, so the digits come off those integers. A normal carries an - // implicit 1 above the stored mantissa; a subnormal stores no leading 1 and denotes an - // exponent field of 1. - proto_u64 mant = proto_dbl_mant(v); - proto_u64 be = proto_dbl_exp(v); - proto_i32 exp2 = 1 - PROTO_DBL_BIAS - (proto_i32)PROTO_DBL_MANT_BITS; - if (be != 0u) - { - mant |= 1ull << PROTO_DBL_MANT_BITS; - exp2 = (proto_i32)be - PROTO_DBL_BIAS - (proto_i32)PROTO_DBL_MANT_BITS; - } - - proto_u64 ip = 0u; - proto_u64 frac = 0u; - if (exp2 >= 0) - { - ip = mant << (unsigned)exp2; // an integer already: nothing below the point to round - } - else - { - unsigned shift = (unsigned)(-exp2); - proto_u64 num = mant; - if (shift < 64u) - { - ip = mant >> shift; - num = mant - (ip << shift); - } - // Each digit costs one multiply and one shift, so the numerator must stay clear of the top - // four bits. Below 2^-60 of the value there is no digit left to decide. - if (shift > 60u) - { - num >>= (shift - 60u); - shift = 60u; - } - const proto_u64 den = 1ull << shift; - for (unsigned i = 0; i < decimals; i++) - { - num *= 10u; - proto_u64 digit = num >> shift; - num -= digit << shift; - frac = frac * 10u + digit; - } - // What is left is the remainder over the same denominator, so the tie is num*2 == den, and - // printf breaks it toward the even digit. - proto_u64 twice = num * 2u; - if (twice > den || (twice == den && (frac & 1u) != 0u)) - { - frac++; - } - } - if (frac >= scale) // the fraction rounded up into the integer part - { - ip++; - frac = 0u; - } - protocore_sb_u64(b, ip); - if (decimals) - { - protocore_sb_ch(b, '.'); - protocore_sb_uint(b, frac, 10, decimals); - } -} - -// RFC 8259 sec 7 gives a two-character escape to five of the control characters; the letter each -// one takes, indexed by the code point, and 0 where the grammar names none. -static const char JSON_CTRL_ESC[32] = {0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -void protocore_sb_json(protocore_sb *b, const char *s) -{ - static const char HEX[] = "0123456789abcdef"; - - if (!b->ok) - { - return; // the loop below stores through b->p directly, so the latch is tested here - } - protocore_sb_put(b, "\""); - // RFC 8259 sec 7: a quotation mark, a reverse solidus and the control characters U+0000 through - // U+001F MUST be escaped. The five with a named two-character form take it; the rest take - // \u00XX, the six-character form sec 7 gives for a Basic Multilingual Plane code point. - for (const char *p = s ? s : ""; *p; p++) - { - const unsigned char c = (unsigned char)*p; - const char two = (c == '"' || c == '\\') ? (char)c : (c < 0x20u ? JSON_CTRL_ESC[c] : 0); - if (two) - { - if (b->len + 2 >= b->cap) - { - b->ok = PROTO_FALSE; - return; - } - b->p[b->len++] = '\\'; - b->p[b->len++] = two; - } - else if (c < 0x20u) - { - if (b->len + 6 >= b->cap) - { - b->ok = PROTO_FALSE; - return; - } - b->p[b->len++] = '\\'; - b->p[b->len++] = 'u'; - b->p[b->len++] = '0'; - b->p[b->len++] = '0'; - b->p[b->len++] = HEX[(c >> 4) & 0xFu]; - b->p[b->len++] = HEX[c & 0xFu]; - } - else if (b->len + 1 < b->cap) - { - b->p[b->len++] = (char)c; - } - else - { - b->ok = PROTO_FALSE; - } - } - protocore_sb_put(b, "\""); -} - -size_t protocore_sb_finish(protocore_sb *b) -{ - // cap == 0 owns no bytes at all, so even the terminator is out of bounds. Every appender - // refuses to write into a zero-capacity buffer without latching `ok`, which left this the one - // path that would still have written p[0]. - if (!b->ok || b->cap == 0) - { - return 0; - } - b->p[b->len] = '\0'; - return b->len; -} diff --git a/src/mmgr/membuild/membuild.h b/src/mmgr/membuild/membuild.h deleted file mode 100644 index 298bb140d..000000000 --- a/src/mmgr/membuild/membuild.h +++ /dev/null @@ -1,209 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file membuild.h - * @brief Bounded no-heap builder that writes into memory the caller already owns. - * - * Under mmgr because building into a buffer is a memory operation: the builder never allocates, it - * is handed a region and fills it. It bump-appends into a caller-owned `char[]` and latches @c ok to - * false the first time something would not fit, so every later append is a no-op and the caller - * tests one flag at the end rather than a return value per call. - * - * The module exports one symbol, @ref Sb. The appends it names are in membuild.c, and everything - * else in that file has internal linkage. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_MEMBUILD_H -#define PROTOCORE_MEMBUILD_H - -#include "protocore_config.h" - -PROTOCORE_BEGIN_DECLS - -/** - * @brief Append a string literal, taking the length from the array type. - * - * `sizeof(s) - 1` is the extent the array type already states, folded at compile time. A macro - * because only the array type carries that extent: passing a literal to a function decays it to a - * pointer and loses the length. - * - * @warning @p s must be a string literal or a `char[]`. A `const char *` compiles here and yields the - * pointer size, so it appends 3 or 7 bytes. ::SbNs::put takes a runtime string. - */ -#define protocore_sb_lit(b, s) protocore_sb_put_n((b), (s), sizeof(s) - 1) - -/** @brief Bump-append target; @c ok latches false once an append would overflow @c cap. */ -typedef struct -{ - char *p; - size_t cap; - size_t len; - proto_bool ok; -} protocore_sb; - -/** - * @brief The builder module. Every append measures its field, tests the one bound, then writes. - * - * @var SbNs::put_n - * Append @c sl bytes of @c s. The primitive the others are built on: it takes the length rather than - * scanning for a NUL. Appending a literal goes through ::protocore_sb_lit, which deduces the length. - * - * @var SbNs::put - * Append the NUL-terminated @c s, measured within @c cap. Leaves the buffer untouched and clears - * @c ok when the whole string would not fit. - * - * @var SbNs::put_clip - * Append as much of @c s as fits and stop, WITHOUT latching @c ok. A NULL @c s appends nothing. - * - * Display text only - an `ls -l` line, a log message. A protocol field takes ::SbNs::put: a clipped - * header or frame has no terminator and desynchronizes the peer, which the latch is what stops. - * - * @var SbNs::u64_clip - * Append @c v as decimal, right-aligned in at least @c columns with leading spaces, if the whole - * field fits - else append nothing, without latching @c ok. @c columns of 0 asks for the natural - * width. All-or-nothing where ::SbNs::put_clip is byte-wise, since half a number reads as a - * different number. Space padding, not the zero padding ::SbNs::uint writes. - * - * @var SbNs::xml - * Append @c s XML-escaped (& < > "); a NULL @c s appends nothing. - * - * @var SbNs::ch - * Append one character. - * - * @var SbNs::uint - * Append @c v in @c base (10 or 16), left-padded with '0' to at least @c min_digits. The one engine - * behind the decimal and hex appenders: measure the field, bounds-check once, then fill it - * back-to-front in place, so neither needs a scratch array. A power-of-two base takes each digit - * with a shift and a mask; base 10 divides, in 32-bit arithmetic when the value fits 32 bits. - * @c min_digits is what carries a printf width like %08lx or %02d. - * - * @var SbNs::u32w - * Append @c v as decimal, zero-padded to at least @c min_digits (printf "%0Nu"). - * - * @var SbNs::hex - * Append @c v as lowercase hex, zero-padded to at least @c min_digits (printf "%0Nx"). - * - * @var SbNs::u32 - * Append @c v as decimal, no leading zeros ("0" for zero). - * - * @var SbNs::u64 - * Append @c v as decimal, 64-bit. - * - * @var SbNs::i64 - * Append @c v as signed decimal, 64-bit, with a leading '-' when negative. The magnitude is taken - * through unsigned arithmetic, so the most negative value does not overflow on the way. - * - * @var SbNs::sign_bit - * True when @c v carries the IEEE-754 sign bit, including for -0.0. A mask on the encoding, not a - * divide. - * - * @var SbNs::is_inf - * True when @c v is an infinity: all exponent bits set, zero significand. - * - * @var SbNs::is_nan - * True when @c v is a NaN: all exponent bits set, nonzero significand. - * - * @var SbNs::g - * Append @c v with @c sig significant digits, choosing fixed or scientific form - the printf - * "%.g" rendering, including trailing-zero removal. Byte-identical to printf for @c sig up to - * 10. Above that the scaling is done in double, which runs out of precision around 16 significant - * digits, so @c sig of 15 or more can differ from libc in the last digit. - * - * @var SbNs::fixed - * Append @c v with exactly @c decimals digits after the point (printf "%.f"), @c decimals - * clamped to 18. Byte-identical to printf for a magnitude below 2^64; at or above it the value falls - * back to ::SbNs::g, whose exact expansion needs no big-integer arithmetic. - * - * @var SbNs::json - * Append @c s as a JSON string literal: double-quoted, with `"` and `\` backslash-escaped. A NULL - * @c s appends `""`. Control characters pass through unescaped. - * - * @var SbNs::finish - * NUL-terminate and return the built length, or 0 when the build overflowed or @c cap is 0. - * - * No storage member: every call works on the caller's @ref protocore_sb and the module holds nothing - * of its own. - */ -typedef struct -{ - void (*put_n)(protocore_sb *b, const char *s, size_t sl); - void (*put)(protocore_sb *b, const char *s); - void (*put_clip)(protocore_sb *b, const char *s); - void (*u64_clip)(protocore_sb *b, uint64_t v, uint8_t columns); - void (*xml)(protocore_sb *b, const char *s); - void (*ch)(protocore_sb *b, char c); - void (*uint)(protocore_sb *b, uint64_t v, unsigned base, unsigned min_digits); - void (*u32w)(protocore_sb *b, uint32_t v, unsigned min_digits); - void (*hex)(protocore_sb *b, uint64_t v, unsigned min_digits); - void (*u32)(protocore_sb *b, uint32_t v); - void (*u64)(protocore_sb *b, uint64_t v); - void (*i64)(protocore_sb *b, int64_t v); - proto_bool (*sign_bit)(double v); - proto_bool (*is_inf)(double v); - proto_bool (*is_nan)(double v); - void (*g)(protocore_sb *b, double v, unsigned sig); - void (*fixed)(protocore_sb *b, double v, unsigned decimals); - void (*json)(protocore_sb *b, const char *s); - size_t (*finish)(protocore_sb *b); -} SbNs; - -// The appends, in membuild.c. Named here because the table below has to name them, and prefixed -// because that puts them in the linker's namespace. -void protocore_sb_put_n(protocore_sb *b, const char *s, size_t sl); -void protocore_sb_put(protocore_sb *b, const char *s); -void protocore_sb_put_clip(protocore_sb *b, const char *s); -void protocore_sb_u64_clip(protocore_sb *b, uint64_t v, uint8_t columns); -void protocore_sb_xml(protocore_sb *b, const char *s); -void protocore_sb_ch(protocore_sb *b, char c); -void protocore_sb_uint(protocore_sb *b, uint64_t v, unsigned base, unsigned min_digits); -void protocore_sb_u32w(protocore_sb *b, uint32_t v, unsigned min_digits); -void protocore_sb_hex(protocore_sb *b, uint64_t v, unsigned min_digits); -void protocore_sb_u32(protocore_sb *b, uint32_t v); -void protocore_sb_u64(protocore_sb *b, uint64_t v); -void protocore_sb_i64(protocore_sb *b, int64_t v); -proto_bool protocore_signbit(double v); -proto_bool protocore_isinf(double v); -proto_bool protocore_isnan(double v); -void protocore_sb_g(protocore_sb *b, double v, unsigned sig); -void protocore_sb_fixed(protocore_sb *b, double v, unsigned decimals); -void protocore_sb_json(protocore_sb *b, const char *s); -size_t protocore_sb_finish(protocore_sb *b); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away and the call to the append in membuild.c is direct, leaving the table referenced - * by nothing for the linker to drop. - * - * `unused` because a header this wide is included by files that take none of it. - */ -// Designated, so a member's position in the struct does not decide what it binds to. -static const SbNs Sb __attribute__((unused)) = {.put_n = protocore_sb_put_n, - .put = protocore_sb_put, - .put_clip = protocore_sb_put_clip, - .u64_clip = protocore_sb_u64_clip, - .xml = protocore_sb_xml, - .ch = protocore_sb_ch, - .uint = protocore_sb_uint, - .u32w = protocore_sb_u32w, - .hex = protocore_sb_hex, - .u32 = protocore_sb_u32, - .u64 = protocore_sb_u64, - .i64 = protocore_sb_i64, - .sign_bit = protocore_signbit, - .is_inf = protocore_isinf, - .is_nan = protocore_isnan, - .g = protocore_sb_g, - .fixed = protocore_sb_fixed, - .json = protocore_sb_json, - .finish = protocore_sb_finish}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_MEMBUILD_H diff --git a/src/mmgr/plaintext/CMakeLists.txt b/src/mmgr/plaintext/CMakeLists.txt deleted file mode 100644 index ac4adeafc..000000000 --- a/src/mmgr/plaintext/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/plaintext - SOURCES plaintext.c - DEPS - mmgr/span - PRIVATE_DEPS - mmgr/arena -) diff --git a/src/mmgr/plaintext/plaintext.c b/src/mmgr/plaintext/plaintext.c deleted file mode 100644 index 041dc57e8..000000000 --- a/src/mmgr/plaintext/plaintext.c +++ /dev/null @@ -1,257 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file plaintext.c - * @brief Plaintext pool accessor - implementation. - * - * This file is an access layer, not a second allocator. The pool mechanism is ::protocore_arena - * (mmgr/arena) and there is exactly one of it; this module owns one instance per worker slot over - * compile-time-sized storage and decides who may reach it. The secret pool is the same mechanism - * instantiated again behind its own accessor - identical resource, identical mechanics, different - * access and control. - * - * Each instance has exactly one accessor (its worker), so the lock-free guarantees in plaintext.h hold - * per slot. With PROTOCORE_WORKER_COUNT == 1 this is byte-for-byte the original single arena. - * - * The arenas, the storage behind them and the debug owner table sit in one instance, reached - * through ::protocore_plaintext_internal. Everything else here has internal linkage. - */ - -#include "mmgr/plaintext/plaintext.h" -#include "config/platform/platform.h" // protocore_platform_context_id() -#include "mmgr/arena/arena.h" -#include - -// The whole plaintext block in bytes: every slot's arena laid end to end. -#define PLAIN_BLOCK_BYTES ((uintptr_t)PROTOCORE_REG_POOL_SLOTS * (uintptr_t)PROTOCORE_PLAINTEXT_ARENA_SIZE) - -// The offset an ownership test reads while no slot has bound the storage. Past every bound below. -#define PLAIN_NO_OFFSET (~(uintptr_t)0) - -/** - * @brief The backing bytes, one arena's worth per slot. - * - * @var PlainStorage::mem the slots in address order, PROTOCORE_PLAINTEXT_ARENA_SIZE bytes each - */ -struct PlainStorage -{ - // The pool aligns allocation offsets, so the base must itself satisfy the strictest alignment a - // caller can request. As a struct member it would only inherit 8-byte alignment; force 32. - _Alignas(32) uint8_t mem[PROTOCORE_REG_POOL_SLOTS][PROTOCORE_PLAINTEXT_ARENA_SIZE]; -}; - -/** - * @brief The pool instances and the bytes they hand out - what PlainNs::internal points at. - * - * @var PlainInternal::store the backing bytes, written by the first borrow and NULL before it - * @var PlainInternal::pool one arena per slot; the offsets and the high-water mark live in each - * @var PlainInternal::owner the first context id seen on each slot, in debug builds - */ -struct PlainInternal -{ - struct PlainStorage *store; - protocore_arena pool[PROTOCORE_REG_POOL_SLOTS]; -#if PROTOCORE_DEBUG_CHECKS - // Off by default; see PROTOCORE_DEBUG_CHECKS. The identity comes from test/core_setup/ - the core does - // not name an RTOS. - uintptr_t owner[PROTOCORE_REG_POOL_SLOTS]; -#endif -}; - -// The backing storage, in its OWN owned instance so it is a distinct linker symbol. -// -// Nothing outside bind() below names this symbol, and bind() is reachable only from the allocation -// path. A firmware that never allocates plaintext scratch (a plain TLS/HTTP server - no SSH / -// WebSocket / OIDC) therefore has the allocator garbage-collected and, with it, this storage, -// reclaiming PROTOCORE_REG_POOL_SLOTS * PROTOCORE_PLAINTEXT_ARENA_SIZE bytes of DRAM. That is why -// protocore_plaintext_reset() - which runs every dispatch and so is always live - must NOT bind, and why -// the handle below carries a null store pointer that bind() fills in rather than an initialized one: -// --gc-sections is per-symbol, and one always-live reference would anchor the multi-KB storage into -// builds that never touch it. -static struct PlainStorage s_storage; - -// The one instance, BSS-zeroed: no slot is bound and no arena has a base until the first borrow. -struct PlainInternal protocore_plaintext_internal; - -// The handle every call below reaches its arenas and its storage through. -static inline struct PlainInternal *plain_self(void) -{ - return &protocore_plaintext_internal; -} - -// Byte offset of @p p within the whole plaintext block, or PLAIN_NO_OFFSET while the storage is -// unbound. The slot count is compile time, so the block is ONE region of known extent and the test -// needs no loop and no per-slot compare: a single unsigned subtract. A pointer below the base wraps -// to a huge value and so fails the same bound as one past the end, which is why NULL needs no -// special case. -// -// Deliberately NOT keyed on a power-of-two slot size. The board profiles tune this per die and most -// are not powers of two (s3 12288, c6 10240), so a masking form would either reject those builds or -// round them up and waste kilobytes on the smallest parts. Subtract-and-compare works for any size. -static inline uintptr_t plain_offset(const struct PlainInternal *ctx, const void *p) -{ - if (ctx->store == NULL) - { - return PLAIN_NO_OFFSET; - } - return (uintptr_t)p - (uintptr_t)ctx->store->mem; -} - -// Resolve the calling worker. The clamp guarantees a legal index, and only that: a caller that is -// not a server worker lands on the ghost instead of worker 0. Two such callers still share the -// ghost, which is what the tripwire below is for. -static inline int cur_worker(void) -{ - int w = protocore_worker_self(); - return (w >= 0 && w < PROTOCORE_REG_POOL_SLOTS) ? w : PROTOCORE_GHOST_WORKER_SLOT; -} - -// Debug tripwire: each pool instance must only ever be touched from one execution context (its -// worker). Record the first caller per slot and assert every later call matches. The structural -// single-accessor-per-slot invariant is what makes this lock-free; the assert just turns a future -// violation into an immediate failure instead of a silent cross-core race. -static inline void assert_single_owner(struct PlainInternal *ctx, int w) -{ -#if PROTOCORE_DEBUG_CHECKS - const uintptr_t cur = protocore_platform_context_id(); - if (ctx->owner[w] == 0) - { - ctx->owner[w] = cur; - } - else - { - assert(ctx->owner[w] == cur && "plaintext pool borrowed from a foreign task"); - } -#else - (void)ctx; - (void)w; -#endif -} - -// Bind slot @p w's pool to its storage on first use, and the handle with it. The ONLY reference to -// s_storage - see the note on it for why it must stay confined to the allocation path. -static inline protocore_arena *bind(struct PlainInternal *ctx, int w) -{ - protocore_arena *a = &ctx->pool[w]; - if (a->base == NULL) - { - ctx->store = &s_storage; - protocore_arena_init(a, ctx->store->mem[w], PROTOCORE_PLAINTEXT_ARENA_SIZE); - } - return a; -} - -// The pool for slot @p w WITHOUT binding it: for the observers and the reset, which must not anchor -// the storage. An unbound slot has never allocated, so it is empty by definition. -static inline protocore_arena *peek(struct PlainInternal *ctx, int w) -{ - protocore_arena *a = &ctx->pool[w]; - return (a->base != NULL) ? a : NULL; -} - -void *protocore_plaintext_alloc(size_t n, size_t align) -{ - struct PlainInternal *ctx = plain_self(); - int w = cur_worker(); - assert_single_owner(ctx, w); - // The false half is a caller-contract violation (align documented as a power of two) and aborts - // the process, so it cannot be exercised from an in-process host test without killing the whole - // test binary mid-run. - assert((align & (align - 1)) == 0 && "plaintext alignment must be a power of two"); - return protocore_arena_scratch_alloc_aligned(bind(ctx, w), n, align); -} - -protocore_span protocore_plaintext_span(size_t n, size_t align) -{ - // One argument sets both fields, so the capacity can never disagree with the allocation. On - // exhaustion protocore_span_from() normalizes to {NULL, 0} rather than a null with a live capacity, - // which is what makes an omitted protocore_span_ok() check drop bytes instead of dereference null. - return protocore_span_from((uint8_t *)protocore_plaintext_alloc(n, align), n); -} - -protocore_span protocore_plaintext_persist_span(size_t n) -{ - struct PlainInternal *ctx = plain_self(); - int w = cur_worker(); - assert_single_owner(ctx, w); - // The persistent end grows up from the base and the scratch end bumps down from the top, so the - // per-dispatch reset never reaches this and no release reclaims it. The arena hands these bytes - // back zeroed. The secure pool's half of this is protocore_secure_persist_span(). - return protocore_span_from((uint8_t *)protocore_arena_persist_alloc(bind(ctx, w), n), n); -} - -void protocore_plaintext_reset(void) -{ - struct PlainInternal *ctx = plain_self(); - int w = cur_worker(); - assert_single_owner(ctx, w); - protocore_arena *a = peek(ctx, w); // must not bind: this runs every dispatch and would anchor the storage - if (a != NULL) - { - protocore_arena_scratch_reset(a); - } -} - -size_t protocore_plaintext_mark(void) -{ - struct PlainInternal *ctx = plain_self(); - int w = cur_worker(); - assert_single_owner(ctx, w); - return protocore_arena_scratch_mark(bind(ctx, w)); -} - -void protocore_plaintext_release(size_t mark) -{ - struct PlainInternal *ctx = plain_self(); - int w = cur_worker(); - assert_single_owner(ctx, w); - protocore_arena_scratch_release(bind(ctx, w), mark); -} - -size_t protocore_plaintext_used(void) -{ - struct PlainInternal *ctx = plain_self(); - const protocore_arena *a = peek(ctx, cur_worker()); - return (a != NULL) ? protocore_arena_scratch_used(a) : 0; -} - -size_t protocore_plaintext_high_water(void) -{ - // Peak any single slot reached - the value to size PROTOCORE_PLAINTEXT_ARENA_SIZE by. This is the - // backward direction of the run-length constant: the pool reports what was actually needed. - struct PlainInternal *ctx = plain_self(); - size_t peak = 0; - for (int w = 0; w < PROTOCORE_REG_POOL_SLOTS; w++) - { - const protocore_arena *a = peek(ctx, w); - if (a != NULL && a->scratch_hw > peak) - { - peak = a->scratch_hw; - } - } - return peak; -} - -size_t protocore_plaintext_capacity(void) -{ - return PROTOCORE_PLAINTEXT_ARENA_SIZE; -} - -proto_bool protocore_plaintext_owns(const void *p) -{ - return plain_offset(plain_self(), p) < PLAIN_BLOCK_BYTES; -} - -int protocore_plaintext_slot_of(const void *p) -{ - const uintptr_t off = plain_offset(plain_self(), p); - if (off >= PLAIN_BLOCK_BYTES) - { - return -1; - } - // A divide by a compile-time constant, which the compiler emits as a multiply-and-shift. Not a - // hot path either way: this exists so a borrow handed back can be asserted to belong to the - // calling worker. - return (int)(off / PROTOCORE_PLAINTEXT_ARENA_SIZE); -} diff --git a/src/mmgr/plaintext/plaintext.h b/src/mmgr/plaintext/plaintext.h deleted file mode 100644 index 984654a21..000000000 --- a/src/mmgr/plaintext/plaintext.h +++ /dev/null @@ -1,248 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file plaintext.h - * @brief Plaintext pool accessor - transient borrows whose bytes are not secret. - * - * Fixed BSS arenas that codec / protocol handlers borrow transient working - * memory from, instead of each feature carrying its own dedicated scratch - * buffer. Many such buffers are mutually exclusive in time - a connection is - * doing HTTP *or* WebSocket *or* SSH at any instant, and a worker runs one - * event to completion before the next - so overlapping them in one arena cuts - * peak RAM without weakening the zero-heap / deterministic guarantee (fixed - * size, no runtime growth). - * - * There is one arena per slot (::PROTOCORE_REG_POOL_SLOTS): one per server worker, plus - * the ghost, which is the library's own. protocore_plaintext_alloc() resolves the - * caller's slot with protocore_worker_self(), so a borrow never crosses workers. - * - * **Model - region reset per dispatch.** protocore_plaintext_alloc() bump-allocates from the - * caller's arena; protocore_plaintext_reset() empties that one arena in O(1). - * dispatch_event() calls protocore_plaintext_reset() before handing an event to its - * protocol handler, so a borrow is valid only until the handler returns. There - * is no per-allocation free - the whole arena is reclaimed at once. - * - * **Race-safety.** Each arena has exactly one accessor - the worker that owns - * its slot - so allocation is a plain bump with no lock. Work reaches a worker - * through its queue, so a context that is not a worker never borrows: the - * network stack's callbacks run on its own thread and only fill the rx ring + - * enqueue events, and an ISR posts a fixed-size item to a preempt-queue lane - * whose task does the work. In debug builds an owner assertion - * (protocore_platform_context_id()) records the first context to touch each arena - * and fails loud if a second one does, turning a future mistake into an - * immediate visible failure instead of a silent cross-core race. - * - * **Exhaustion-safety.** Borrows live only within one dispatch and are - * auto-reclaimed by the reset, so a forgotten free cannot accumulate (no - * creeping exhaustion). An over-budget protocore_plaintext_alloc() returns NULL; every - * caller must take a defined fail-closed path (drop the optional optimization, - * close the connection, answer 503) and must never dereference a null borrow. - * - * **No implicit zeroing.** protocore_plaintext_alloc() returns uninitialized memory and the - * reset does not wipe. This pool is for plaintext: anything whose bytes are key - * material belongs in the secure pool (mmgr/secure.h), which is the same - * mechanism with one added control - reclaiming wipes, before the bytes become - * available again. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_PLAINTEXT_H -#define PROTOCORE_PLAINTEXT_H - -#include "mmgr/span/span.h" - -#include "protocore_config.h" - -PROTOCORE_BEGIN_DECLS - -/** - * @brief Slots in the plaintext pool. - * - * Sized off the ghost rather than the worker count so the invariant is the definition: the pool - * must reach the highest slot any caller can resolve to, and that is the ghost. - * - * The secure pool states its own count (::PROTOCORE_SEC_POOL_SLOTS). They are equal today and neither is - * derived from the other - one pool growing a slot is not a reason for the other to. - */ -#define PROTOCORE_REG_POOL_SLOTS (PROTOCORE_GHOST_WORKER_SLOT + 1) - -/** @brief The per-slot arenas and the bytes they hand out, laid out only in plaintext.c. */ -struct PlainInternal; - -/** - * @brief The plaintext pool. - * - * @var PlainNs::alloc borrow @c n bytes aligned to @c align, or NULL if it does not fit - * @var PlainNs::span the same borrow as a span, so the length travels with the pointer - * @var PlainNs::persist a span that outlives the dispatch, for state that spans polls - * @var PlainNs::reset empty the calling worker's arena - * @var PlainNs::mark capture the arena offset, to release back to - * @var PlainNs::release reclaim everything borrowed since a mark, LIFO - * @var PlainNs::used bytes currently handed out - * @var PlainNs::high_water the largest @c used any slot has reached, for sizing the arena - * @var PlainNs::capacity one arena's total extent - * @var PlainNs::owns whether a pointer lies inside the pool - * @var PlainNs::slot_of which slot holds a pointer, or -1 - * @var PlainNs::internal the per-slot arenas and the storage behind them - * - * The extent and the layout of that storage are plaintext.c's alone: the handle is an incomplete - * type here, so a caller can carry it and nothing else. Every call resolves the slot from the - * calling worker, so no caller passes one in. - */ -typedef struct -{ - void *(*alloc)(size_t n, size_t align); - protocore_span (*span)(size_t n, size_t align); - protocore_span (*persist)(size_t n); - void (*reset)(void); - size_t (*mark)(void); - void (*release)(size_t mark); - size_t (*used)(void); - size_t (*high_water)(void); - size_t (*capacity)(void); - proto_bool (*owns)(const void *p); - int (*slot_of)(const void *p); - - struct PlainInternal *internal; -} PlainNs; - -/** @brief The one pool instance every call below reaches its arenas through. */ -extern struct PlainInternal protocore_plaintext_internal; - -/** - * @brief Borrow @p n bytes of plaintext, aligned to @p align. - * - * The returned pointer is valid only until the next protocore_plaintext_reset() (i.e. only - * within the current session dispatch). Returns NULL if the request does not - * fit the remaining arena - callers MUST handle null and fail closed. - * - * @param n bytes requested (0 yields a valid non-null pointer when space - * remains). - * @param align required alignment in bytes, a power of two, clamped to - * `[PROTOCORE_ARENA_ALIGN, PROTOCORE_ARENA_MAX_ALIGN]` by the arena - * underneath (0 selects the platform default). - * @return pointer to @p n writable bytes, or NULL if it does not fit. - */ -void *protocore_plaintext_alloc(size_t n, size_t align); - -/** - * @brief Borrow @p n bytes as a span whose capacity is bound to the allocation. - * - * The preferred form. protocore_plaintext_alloc() hands back a bare pointer, which leaves the caller to carry - * the length separately and keep the two in agreement by hand at every call - the same severed - * binding that makes `sizeof()` on a converted array read 4 bytes instead of the extent. Here one - * argument sets both fields, so the run length is stated once and cannot drift. - * - * Fails closed: an over-budget request yields `{NULL, 0}`, so a caller that omits the - * protocore_span_ok() check writes nothing rather than dereferencing null. Callers should still check and - * take their defined fail-closed path. - * - * @param n bytes requested. - * @param align required alignment in bytes, a power of two (0 selects the platform default). - * @return a span over @p n writable bytes, or an empty span if it does not fit. - */ -protocore_span protocore_plaintext_span(size_t n, size_t align); - -/** - * @brief Borrow @p n bytes that outlive the dispatch, as a span. - * - * The transient borrows above die at the next protocore_plaintext_reset(), which runs before every event. - * State that spans dispatches - a receive ring holding a partial message between polls, a packet - * held for retransmit until it is acknowledged - comes from here instead: the persistent end grows - * up from the arena base while the scratch end bumps down from the top, so the reset never reaches - * it. The bytes come back zeroed. - * - * This is the plaintext half of ::protocore_secure_persist_span. Bytes that are key material belong in the - * secure pool, whose reclaim wipes; these are not wiped. - * - * @param n bytes requested. - * @return a span over @p n writable bytes, or an empty span if it does not fit. - */ -protocore_span protocore_plaintext_persist_span(size_t n); - -/** - * @brief Reclaim the whole arena (empties it). - * - * Called by Session.tick() before each event dispatch. Invalidates every pointer - * previously returned by protocore_plaintext_alloc(). - */ -void protocore_plaintext_reset(void); - -/** - * @brief Capture the current arena offset (a savepoint for protocore_plaintext_release()). - * @return an opaque mark to pass to protocore_plaintext_release(). - */ -size_t protocore_plaintext_mark(void); - -/** - * @brief Reclaim everything allocated since @p mark (LIFO). - * - * Restores the arena to a previous protocore_plaintext_mark(), freeing every protocore_plaintext_alloc() - * made in between. Marks must be released in reverse order (nested scopes). - * - * @param mark a value previously returned by protocore_plaintext_mark() (must be <= the - * current offset). - */ -void protocore_plaintext_release(size_t mark); - -/** @brief Bytes currently handed out (0 immediately after a reset). */ -size_t protocore_plaintext_used(void); - -/** @brief Largest protocore_plaintext_used() value seen since boot (for sizing the arena). */ -size_t protocore_plaintext_high_water(void); - -/** @brief Total arena capacity in bytes (PROTOCORE_PLAINTEXT_ARENA_SIZE). */ -size_t protocore_plaintext_capacity(void); - -/** - * @brief True if @p p points inside the plaintext pool. - * - * Ownership is an address-range property, not bookkeeping. The slot count and slot size are both - * compile-time, so the whole pool is ONE region of known extent and the test is a single unsigned - * subtract and compare - no loop, no per-slot comparison, no per-allocation metadata. A pointer - * below the base wraps to a huge offset and fails the same bound as one past the end, so a buffer - * overrun cannot test as still-inside. Nothing is inside a pool no slot has taken a borrow from, - * so an untouched pool answers false. - * - * This is the plaintext half of the control strategy. The secure pool is a disjoint region and - * answers its own question, so a secure-pool pointer can never be accepted where a plaintext one - * is required, or the reverse. - */ -proto_bool protocore_plaintext_owns(const void *p); - -/** - * @brief Which plaintext slot owns @p p, or -1 if @p p is not in the plaintext pool. - * - * A divide by a compile-time constant, so a multiply-and-shift rather than real division. Use to - * assert that a borrow being handed back belongs to the calling worker: crossing slots is the one - * way the lock-free single-accessor invariant can be violated, and this makes it checkable. - */ -int protocore_plaintext_slot_of(const void *p); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here. - * - * `unused` because this header reaches files that take none of it. - */ -// Designated, so a member's position in the struct does not decide what it binds to. -static const PlainNs plain __attribute__((unused)) = {.alloc = protocore_plaintext_alloc, - .span = protocore_plaintext_span, - .persist = protocore_plaintext_persist_span, - .reset = protocore_plaintext_reset, - .mark = protocore_plaintext_mark, - .release = protocore_plaintext_release, - .used = protocore_plaintext_used, - .high_water = protocore_plaintext_high_water, - .capacity = protocore_plaintext_capacity, - .owns = protocore_plaintext_owns, - .slot_of = protocore_plaintext_slot_of, - .internal = &protocore_plaintext_internal}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_PLAINTEXT_H diff --git a/src/mmgr/protoframe/CMakeLists.txt b/src/mmgr/protoframe/CMakeLists.txt deleted file mode 100644 index 91e073705..000000000 --- a/src/mmgr/protoframe/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/protoframe - SOURCES protoframe.c - DEPS - mmgr/membuild - PRIVATE_DEPS - mmgr/protostr - shared/speed_opt -) diff --git a/src/mmgr/protoframe/protoframe.c b/src/mmgr/protoframe/protoframe.c deleted file mode 100644 index 653affd08..000000000 --- a/src/mmgr/protoframe/protoframe.c +++ /dev/null @@ -1,141 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file protoframe.c - * @brief The one frame engine. Walks a protocore_field spec, pulls one argument per valued field. - * - * Every conversion is a protocore_sb appender, so what lives here is the dispatch loop and the - * fail-closed contract, never formatting logic. - */ - -#include "mmgr/protoframe/protoframe.h" -#include "mmgr/protostr/protostr.h" // str: the bounded-run walks -#include "shared/speed_opt/speed_opt.h" - -#ifndef PROTOCORE_FRAME_SCAN_LITERALS -#define PROTOCORE_FRAME_SCAN_LITERALS 0 // 1 = find each literal length at runtime instead of reading it from the spec -#endif - -// A dispatch loop over a table, handling no secrets, so the size level the TU would otherwise -// inherit buys nothing here and costs the appenders their inlining. -PROTOCORE_OPTIMIZE_O2 - -// A null string field renders empty, so no caller has to coalesce one before passing it. -static const char *str_or_empty(const char *s) -{ - if (s == NULL) - { - return ""; - } - return s; -} - -size_t protocore_frame_build(char *out, size_t cap, const protocore_field *spec, const protocore_fval *v, size_t nv) -{ - if (!out || cap == 0 || !spec) - { - return 0; - } - protocore_sb b = {out, cap, 0, PROTO_TRUE}; - size_t k = 0; // next value; a valued field consumes one - for (const protocore_field *f = spec; f->kind != PROTOCORE_FK_END; f++) - { - if (f->kind == PROTOCORE_FK_LIT) - { -#if PROTOCORE_FRAME_SCAN_LITERALS - Sb.put(&b, f->lit); -#else - // the spec carries the length; scanning for the NUL would rediscover it every call - Sb.put_n(&b, f->lit, f->len); -#endif - continue; - } - // A valued field needs a value, and it needs the one the spec declared. Either failure is - // the caller and the spec disagreeing, which cannot produce the frame that was asked for. - if (k >= nv || !v || v[k].kind != f->kind) - { - out[0] = '\0'; - return 0; - } - const protocore_fval *a = &v[k]; - k++; - switch (f->kind) - { - case PROTOCORE_FK_STR: - Sb.put(&b, str_or_empty(a->as.s)); - break; - case PROTOCORE_FK_U32: - Sb.u32(&b, a->as.u32); - break; - case PROTOCORE_FK_U64: - Sb.u64(&b, a->as.u64); - break; - case PROTOCORE_FK_I64: - Sb.i64(&b, a->as.i64); - break; - case PROTOCORE_FK_DEC: - Sb.u32w(&b, a->as.u32, f->width); - break; - case PROTOCORE_FK_HEX: - Sb.hex(&b, a->as.u64, f->width ? f->width : 1); - break; - case PROTOCORE_FK_OCT: - Sb.uint(&b, a->as.u64, 8, f->width ? f->width : 1); - break; - case PROTOCORE_FK_G: - Sb.g(&b, a->as.d, f->width ? f->width : 6); - break; - case PROTOCORE_FK_FIX: - Sb.fixed(&b, a->as.d, f->width); - break; - case PROTOCORE_FK_CH: - Sb.ch(&b, a->as.c); - break; - case PROTOCORE_FK_JSON: - Sb.json(&b, str_or_empty(a->as.s)); - break; - case PROTOCORE_FK_XML: - Sb.xml(&b, str_or_empty(a->as.s)); - break; - default: - // An unknown opcode means the spec and this engine disagree; refuse rather than - // emit a frame that is missing a field and looks well-formed. - out[0] = '\0'; - return 0; - } - } - if (k != nv) - { - out[0] = '\0'; // more values than the spec declares fields - return 0; - } - size_t n = Sb.finish(&b); - if (n == 0) - { - // Did not fit (or was empty). Leave a valid, empty C string either way: callers that - // ignore the return must never read stale bytes or an unterminated buffer. - out[0] = '\0'; - } - return n; -} - -size_t protocore_frame_append(char *out, size_t cap, const protocore_field *spec, const protocore_fval *v, size_t nv) -{ - if (!out || cap == 0 || !spec) - { - return 0; - } - size_t used = str.len(out, cap); - if (used >= cap) - { - return 0; - } - size_t n = protocore_frame_build(out + used, cap - used, spec, v, nv); - if (n == 0) - { - out[used] = '\0'; // rewind: the frame is added whole or not at all - return 0; - } - return used + n; -} diff --git a/src/mmgr/protoframe/protoframe.h b/src/mmgr/protoframe/protoframe.h deleted file mode 100644 index 5504996cb..000000000 --- a/src/mmgr/protoframe/protoframe.h +++ /dev/null @@ -1,245 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file protoframe.h - * @brief Declarative frame builder: a frame is a static table of typed fields, built by one engine. - * - * A frame's shape is data, not code: a `static const protocore_field[]` in rodata, walked by one engine. - * The spec is pre-decoded, so the engine reads an opcode and a width out of a struct and jumps - - * nothing is parsed at runtime, and no float formatter is linked unless a frame declares a float - * field. Adding a frame adds a table, not logic. - * - * **Contract.** - * - Returns the number of bytes written (excluding the NUL) on success. - * - Returns 0 if the frame does not fit, and writes `out[0] = '\0'`. There is no truncation: - * a partial frame is a protocol violation, and a caller that ignores the return still finds a - * valid empty C string rather than half a header or stale bytes from a previous build. - * - `out` is always NUL-terminated on both paths, so a caller may always read it as a string. - * - A NULL `PROTOCORE_FK_STR` argument renders as empty, never as a crash or "(null)". - * - * - * **Arguments** are one ::protocore_fval per field that declares one (PROTOCORE_FK_LIT and PROTOCORE_FK_END declare - * none), in spec order, passed as an array with its count. Each value carries the ::protocore_fk it was - * written as, so the engine compares it against the spec's and refuses a frame whose values do not - * match - the arity and the type are both checked at the call instead of trusting the caller. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_PROTOFRAME_H -#define PROTOCORE_PROTOFRAME_H - -#include "mmgr/membuild/membuild.h" - -/** - * @brief Field kinds. The value is an opcode, so the enum is the name for a byte, not a type gate. - * - * The width is carried by protocore_field::kind (a uint8_t), not by the enum: C has no fixed underlying - * type, and the storage is what the wire sees. - */ -typedef enum -{ - PROTOCORE_FK_END = 0, ///< terminator; takes no argument - PROTOCORE_FK_LIT, ///< literal text from `lit`; takes no argument - PROTOCORE_FK_STR, ///< const char * (NULL renders as empty) - PROTOCORE_FK_U32, ///< uint32_t, plain decimal - PROTOCORE_FK_U64, ///< uint64_t, plain decimal - PROTOCORE_FK_I64, ///< int64_t, signed decimal - PROTOCORE_FK_DEC, ///< uint32_t, decimal zero-padded to `width` - PROTOCORE_FK_HEX, ///< uint64_t, lowercase hex zero-padded to `width` - PROTOCORE_FK_OCT, ///< uint64_t, octal zero-padded to `width` - PROTOCORE_FK_G, ///< double, printf %.g (width 0 means 6) - PROTOCORE_FK_FIX, ///< double, printf %.f - PROTOCORE_FK_CH, ///< char - PROTOCORE_FK_JSON, ///< const char *, emitted as a quoted JSON string literal - PROTOCORE_FK_XML, ///< const char *, XML-escaped -} protocore_fk; - -/** - * @brief One field of a frame. Frames are `static const protocore_field[]`, so they live in rodata. - * - * @c len carries a literal's length, written out in the spec and verified by - * ci_tooling/check/check_frame_specs.py. The length is fixed when the spec is written, so the - * engine reads it rather than scanning each literal for its NUL on every call. - */ -typedef struct protocore_field -{ - uint8_t kind; ///< a protocore_fk - uint8_t width; ///< min digits (DEC/HEX/OCT), significant digits (G), decimals (FIX) - uint16_t len; ///< PROTOCORE_FK_LIT: byte length of @c lit; gated by check_frame_specs.py - const char *lit; ///< PROTOCORE_FK_LIT only -} protocore_field; - -// Spec constructors, one per valued field carrying neither a width nor a literal. Field order is -// {kind, width, len, lit}; a field that does carry one is written as a plain aggregate, because a -// macro taking it as a parameter would be function-like (AUTOSAR A16-0-1). -// -// static const protocore_field RESP[] = { -// {PROTOCORE_FK_LIT, 0, 9, "HTTP/1.1 "}, // 9 == the literal's length -// PROTOCORE_U32, -// {PROTOCORE_FK_HEX, 8, 0, NULL}, // 8 == zero-pad width -// PROTOCORE_END, -// }; -// -// check_frame_specs.py fails the build when a len disagrees with its literal; --fix rewrites it. -#define PROTOCORE_STR {PROTOCORE_FK_STR, 0, 0, NULL} -#define PROTOCORE_U32 {PROTOCORE_FK_U32, 0, 0, NULL} -#define PROTOCORE_U64 {PROTOCORE_FK_U64, 0, 0, NULL} -#define PROTOCORE_I64 {PROTOCORE_FK_I64, 0, 0, NULL} -#define PROTOCORE_CH {PROTOCORE_FK_CH, 0, 0, NULL} -#define PROTOCORE_JSON {PROTOCORE_FK_JSON, 0, 0, NULL} -#define PROTOCORE_XML {PROTOCORE_FK_XML, 0, 0, NULL} -#define PROTOCORE_END {PROTOCORE_FK_END, 0, 0, NULL} - -/** - * @brief One argument to a frame: the ::protocore_fk it was written as, and the value under that tag. - * - * The tag is the discriminant the engine dispatches on, and it is compared against the spec's own - * kind before the value is read, so a caller that passes a string where the spec wants a number is - * refused rather than reinterpreted. - */ -typedef struct protocore_fval -{ - uint8_t kind; ///< a protocore_fk; must equal the spec field's kind - union { - const char *s; ///< PROTOCORE_FK_STR, PROTOCORE_FK_JSON, PROTOCORE_FK_XML - uint32_t u32; ///< PROTOCORE_FK_U32, PROTOCORE_FK_DEC - uint64_t u64; ///< PROTOCORE_FK_U64, PROTOCORE_FK_HEX, PROTOCORE_FK_OCT - int64_t i64; ///< PROTOCORE_FK_I64 - double d; ///< PROTOCORE_FK_G, PROTOCORE_FK_FIX - char c; ///< PROTOCORE_FK_CH - } as; -} protocore_fval; - -// Value constructors, one per valued kind. Written as a compound literal at the call, so the -// argument list stays a list and no named array appears at function scope. -#define PROTOCORE_VSTR(x) \ - { \ - PROTOCORE_FK_STR, \ - { \ - .s = (x) \ - } \ - } -#define PROTOCORE_VU32(x) \ - { \ - PROTOCORE_FK_U32, \ - { \ - .u32 = (x) \ - } \ - } -#define PROTOCORE_VU64(x) \ - { \ - PROTOCORE_FK_U64, \ - { \ - .u64 = (x) \ - } \ - } -#define PROTOCORE_VI64(x) \ - { \ - PROTOCORE_FK_I64, \ - { \ - .i64 = (x) \ - } \ - } -#define PROTOCORE_VDEC(x) \ - { \ - PROTOCORE_FK_DEC, \ - { \ - .u32 = (x) \ - } \ - } -#define PROTOCORE_VHEX(x) \ - { \ - PROTOCORE_FK_HEX, \ - { \ - .u64 = (x) \ - } \ - } -#define PROTOCORE_VOCT(x) \ - { \ - PROTOCORE_FK_OCT, \ - { \ - .u64 = (x) \ - } \ - } -#define PROTOCORE_VG(x) \ - { \ - PROTOCORE_FK_G, \ - { \ - .d = (x) \ - } \ - } -#define PROTOCORE_VFIX(x) \ - { \ - PROTOCORE_FK_FIX, \ - { \ - .d = (x) \ - } \ - } -#define PROTOCORE_VCH(x) \ - { \ - PROTOCORE_FK_CH, \ - { \ - .c = (x) \ - } \ - } -#define PROTOCORE_VJSON(x) \ - { \ - PROTOCORE_FK_JSON, \ - { \ - .s = (x) \ - } \ - } -#define PROTOCORE_VXML(x) \ - { \ - PROTOCORE_FK_XML, \ - { \ - .s = (x) \ - } \ - } - -/** - * @brief Build @p spec into @p out (capacity @p cap) from @p nv values in spec order. - * @return bytes written, or 0 if the frame did not fit or the values did not match the spec (in - * which case @p out is set empty). - */ -size_t protocore_frame_build(char *out, size_t cap, const protocore_field *spec, const protocore_fval *v, size_t nv); - -/** - * @brief Append @p spec to the NUL-terminated contents already in @p out. - * - * The append idiom this library uses for header and cookie accumulation: on overflow the buffer is - * rewound to its previous length, so a frame is added whole or not at all and a half-written line - * never reaches the wire. - * - * @return the new total length, or 0 if the frame did not fit (previous contents preserved). - */ -size_t protocore_frame_append(char *out, size_t cap, const protocore_field *spec, const protocore_fval *v, size_t nv); - -/** - * @brief The two builds a caller reaches. - * - * @var FrameNs::build write a frame into an empty buffer - * @var FrameNs::append add a frame to what the buffer already holds - */ -typedef struct -{ - size_t (*build)(char *out, size_t cap, const protocore_field *spec, const protocore_fval *v, size_t nv); - size_t (*append)(char *out, size_t cap, const protocore_field *spec, const protocore_fval *v, size_t nv); -} FrameNs; - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away and the call to the build in protoframe.c is direct, leaving the table referenced - * by nothing for the linker to drop. - * - * `unused` because a header this wide is included by files that take none of it. - */ -static const FrameNs frame __attribute__((unused)) = {protocore_frame_build, protocore_frame_append}; - -#endif // PROTOCORE_PROTOFRAME_H diff --git a/src/mmgr/protomem/CMakeLists.txt b/src/mmgr/protomem/CMakeLists.txt deleted file mode 100644 index 3f2e6b91f..000000000 --- a/src/mmgr/protomem/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/protomem - SOURCES protomem.c - DEPS - mmgr/rawmemcpy - PRIVATE_DEPS - mmgr/swar -) diff --git a/src/mmgr/protomem/protomem.c b/src/mmgr/protomem/protomem.c deleted file mode 100644 index 6b6be1bde..000000000 --- a/src/mmgr/protomem/protomem.c +++ /dev/null @@ -1,227 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file protomem.c - * @brief The byte-span operations - see protomem.h. - * - * Every access is one register-width load or store. A span that does not end on a boundary is not - * walked a byte at a time: the partial word is merged and stored whole, the lane mask choosing the - * span's bytes from the source and the destination's own word for the lanes past it. A source that - * is not co-aligned with the destination is funnelled, the way the raw mover above it does it. - * - * The one symbol this file exports is @ref mem. - */ - -#include "mmgr/protomem/protomem.h" -#include "mmgr/swar/swar.h" // the lane math the ordering walk reads its answer out of - -#define PROTOCORE_MEM_MASK ((uintptr_t)(PROTO_RAW_WORD - 1u)) - -// The low @p nbytes lanes of a word, as bits. A count at or past the width is the whole word, which -// is the case a shift by the full width would leave undefined. -static proto_mv_word lo_lanes(size_t nbytes) -{ - if (nbytes >= PROTO_RAW_WORD) - { - return (proto_mv_word) ~(proto_mv_word)0; - } - return (proto_mv_word)(((proto_mv_word)1 << (nbytes * 8u)) - (proto_mv_word)1); -} - -// Bits covering byte lanes [from, to) of a word in ADDRESS order. Address order is where byte order -// enters: the lowest-addressed lane sits in the low bits on a little-endian load and the high bits on -// a big-endian one, so the two ends are named from opposite sides. -static proto_mv_word span_lanes(size_t from, size_t to) -{ -#if PROTOCORE_HW_BIG_ENDIAN - return (proto_mv_word)(~lo_lanes(PROTO_RAW_WORD - to) & lo_lanes(PROTO_RAW_WORD - from)); -#else - return (proto_mv_word)(lo_lanes(to) & ~lo_lanes(from)); -#endif -} - -// The word of source bytes beginning at @p p, assembled from the aligned words that hold it. @p avail -// is what the span still has past @p p, so the second load is taken only when the wanted bytes reach -// into the next word and never past the span's own allocation. -static proto_mv_word src_word(const unsigned char *p, size_t avail) -{ - const size_t off = (size_t)((uintptr_t)p & PROTOCORE_MEM_MASK); - const unsigned char *sa = p - off; - const proto_mv_word w0 = raw.mv_load(sa); - - if (off == 0u) - { - return w0; - } - - const unsigned lo = (unsigned)(off * 8u); - const unsigned hi = (unsigned)(PROTO_MV_BITS - lo); - proto_mv_word w1 = 0; - if (avail > PROTO_RAW_WORD - off) - { - w1 = raw.mv_load(sa + PROTO_RAW_WORD); - } -#if PROTOCORE_HW_BIG_ENDIAN - return (proto_mv_word)((w0 << lo) | (w1 >> hi)); -#else - return (proto_mv_word)((w0 >> lo) | (w1 << hi)); -#endif -} - -void protocore_mem_cpy(void *dst, const void *src, size_t n) -{ - unsigned char *d = (unsigned char *)dst; - const unsigned char *s = (const unsigned char *)src; - size_t i = 0; - - while (i + PROTO_RAW_WORD <= n) - { - raw.mv_put(d + i, src_word(s + i, n - i)); - i += PROTO_RAW_WORD; - } - if (i < n) - { - const proto_mv_word keep = span_lanes(0u, n - i); - raw.mv_put(d + i, (proto_mv_word)((src_word(s + i, n - i) & keep) | (raw.mv_load(d + i) & ~keep))); - } -} - -void protocore_mem_move(void *dst, const void *src, size_t n) -{ - unsigned char *d = (unsigned char *)dst; - const unsigned char *s = (const unsigned char *)src; - - if (d == s || n == 0u) - { - return; - } - if (d < s || d >= s + n) - { - protocore_mem_cpy(dst, src, n); - return; - } - - // Destination ahead of the source and inside it: walk down so a word is read before the store - // that would overwrite it. The trailing partial goes first, for the same reason. - size_t i = n & ~(size_t)PROTOCORE_MEM_MASK; - if (i < n) - { - const proto_mv_word keep = span_lanes(0u, n - i); - raw.mv_put(d + i, (proto_mv_word)((src_word(s + i, n - i) & keep) | (raw.mv_load(d + i) & ~keep))); - } - while (i >= PROTO_RAW_WORD) - { - i -= PROTO_RAW_WORD; - raw.mv_put(d + i, src_word(s + i, n - i)); - } -} - -/** - * @brief Order @p n bytes at @p a against @p b, as unsigned. - * - * A word per step: XOR zeroes every lane that matches, so a nonzero syndrome means the two part - * inside this word and the lane math names which byte. That byte is the whole answer, because the - * ordering of two spans is decided where they first disagree and nothing after it is read. - * - * The tail runs the same rule a byte at a time. A partial word cannot be loaded whole without - * reading past what the caller offered: @p n is a promise about both operands, not a hint. - */ -int protocore_mem_cmp(const void *a, const void *b, size_t n) -{ - const char *x = (const char *)a; - const char *y = (const char *)b; - size_t i = 0; - - while (i + PROTOCORE_SWAR_BYTES <= n) - { - protocore_swar_word d = swar.load(x + i) ^ swar.load(y + i); - if (d != 0) - { - // The guard bit stands on every lane that differs, and the lowest one is where they part. - i += swar.zero_lane(PROTOCORE_SWAR_HIGH & ~swar.has_zero(d)); - return (int)(unsigned char)x[i] - (int)(unsigned char)y[i]; - } - i += PROTOCORE_SWAR_BYTES; - } - while (i < n) - { - if (x[i] != y[i]) - { - return (int)(unsigned char)x[i] - (int)(unsigned char)y[i]; - } - ++i; - } - return 0; -} - -/** - * @brief The first byte equal to @p c in @p n bytes at @p p, or NULL. - * - * A word per step: ::SwarNs::eq marks every lane holding @p c, and the lane math names the lowest - * one. @p n is the whole bound - there is no terminator test, because a span has no terminator, and - * the caller has already stated how far the bytes go. - * - * That is what separates this from ::StrNs::find, which stops at a NUL because it searches a string. - * A buffer that deliberately carries NULs - a decoded credential, a wire frame - needs this one. - */ -const void *protocore_mem_chr(const void *p, size_t n, uint8_t c) -{ - const char *s = (const char *)p; - size_t i = 0; - - while (i < n && ((uintptr_t)(s + i) & (PROTOCORE_SWAR_BYTES - 1u)) != 0u) - { - if ((uint8_t)s[i] == c) - { - return s + i; - } - ++i; - } - while (i + PROTOCORE_SWAR_BYTES <= n) - { - protocore_swar_word m = swar.eq(swar.load_al(s + i), c, PROTO_FALSE); - if (m != 0) - { - return s + i + swar.zero_lane(m); - } - i += PROTOCORE_SWAR_BYTES; - } - // The final partial word, a byte at a time: a whole load would read past what @p n offers. - while (i < n) - { - if ((uint8_t)s[i] == c) - { - return s + i; - } - ++i; - } - return NULL; -} - -void protocore_mem_set(void *dst, unsigned char v, size_t n) -{ - unsigned char *d = (unsigned char *)dst; - size_t i = 0; - - // The splat comes from the identity swar.h derives its lane masks with: the all-ones word over - // 0xFF leaves bit 0 of every lane, so multiplying by the byte puts it in every lane at once. - const proto_mv_word ones = (proto_mv_word)((proto_mv_word) ~(proto_mv_word)0 / 0xFFu); - const proto_mv_word w = (proto_mv_word)(ones * (proto_mv_word)v); - - while (i + PROTO_RAW_WORD <= n) - { - raw.mv_put(d + i, w); - i += PROTO_RAW_WORD; - } - if (i < n) - { - const proto_mv_word keep = span_lanes(0u, n - i); - raw.mv_put(d + i, (proto_mv_word)((w & keep) | (raw.mv_load(d + i) & ~keep))); - } -} - -void protocore_mem_zero(void *dst, size_t n) -{ - protocore_mem_set(dst, 0u, n); -} diff --git a/src/mmgr/protomem/protomem.h b/src/mmgr/protomem/protomem.h deleted file mode 100644 index a76de0c0f..000000000 --- a/src/mmgr/protomem/protomem.h +++ /dev/null @@ -1,101 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file protomem.h - * @brief The byte-span operations: copy, move, compare, fill. - * - * In mmgr because they move what mmgr hands out. Every allocation leaves the arena rounded up to - * PROTOCORE_ARENA_ALIGN and starting on it, so a span's trailing lanes belong to that same allocation. - * - * The module exports one symbol, @ref mem. Everything in protomem.c has internal linkage. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_PROTOMEM_H -#define PROTOCORE_PROTOMEM_H - -#include "mmgr/rawmemcpy/rawmemcpy.h" // the loads and stores every walk below steps with - -#include "protocore_config.h" - -PROTOCORE_BEGIN_DECLS - -/** - * @brief The byte-span module. Every access is one register-width load or store. - * - * @var MemNs::cpy - * Copy @c n bytes from @c src to @c dst, which must not overlap. A source that is not co-aligned with - * the destination is funnelled: two shifts and an OR assemble the wanted word from the two aligned - * words holding it. - * - * A partial word at the end is one merged store rather than a byte walk: the lane mask takes the - * span's bytes from the source and the destination's own word supplies the rest, so the store is a - * whole word and nothing past @c n changes. @c dst is any span, whole borrow or offset into one. - * - * @var MemNs::move - * Copy @c n bytes from @c src to @c dst, correct when the two overlap. Every direction but one reads - * each byte before the copy reaches it and goes through @ref MemNs::cpy; a destination ahead of the - * source inside it walks down, still a word per step. - * - * @var MemNs::cmp - * Order @c n bytes at @c a against @c b: negative, zero or positive on the first byte that differs, - * compared as unsigned. Both operands must hold @c n readable bytes; nothing stops at a terminator, - * so this is a span comparison and not a string one. - * - * **Not constant time.** It stops at the first difference, so how long it runs says how many leading - * bytes matched. A secret comparison uses protocore_ct_eq (crypto/ct_eq.h) instead. - * - * @var MemNs::chr - * The first byte equal to @c c in @c n bytes at @c p, or NULL. @c n is the whole bound: a span has - * no terminator, so nothing stops early. - * - * That is the difference from StrNs::find, which searches a STRING and stops at its NUL. Reach for - * this one whenever the buffer legitimately carries NULs and its extent is already known - a decoded - * credential, a wire frame - and for find when the run really does end at a terminator. - * - * @var MemNs::set - * Write @c v into @c n bytes at @c dst. - * - * @var MemNs::zero - * Write zero into @c n bytes at @c dst. - * - * No storage member: every operation works on the caller's pointers and holds nothing of its own. - */ -typedef struct -{ - void (*cpy)(void *dst, const void *src, size_t n); - void (*move)(void *dst, const void *src, size_t n); - int (*cmp)(const void *a, const void *b, size_t n); - const void *(*chr)(const void *p, size_t n, uint8_t c); - void (*set)(void *dst, unsigned char v, size_t n); - void (*zero)(void *dst, size_t n); -} MemNs; - -// The span walks, in protomem.c. Named here because the table below has to name them, and prefixed -// because that puts them in the linker's namespace. -void protocore_mem_cpy(void *dst, const void *src, size_t n); -void protocore_mem_move(void *dst, const void *src, size_t n); -int protocore_mem_cmp(const void *a, const void *b, size_t n); -const void *protocore_mem_chr(const void *p, size_t n, uint8_t c); -void protocore_mem_set(void *dst, unsigned char v, size_t n); -void protocore_mem_zero(void *dst, size_t n); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away and the call to the walk in protomem.c is direct, leaving the table referenced by - * nothing for the linker to drop. - * - * `unused` because a header this wide is included by files that take none of it. - */ -static const MemNs mem __attribute__((unused)) = {protocore_mem_cpy, protocore_mem_move, protocore_mem_cmp, - protocore_mem_chr, protocore_mem_set, protocore_mem_zero}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_PROTOMEM_H diff --git a/src/mmgr/protostr/CMakeLists.txt b/src/mmgr/protostr/CMakeLists.txt deleted file mode 100644 index 6ef421d05..000000000 --- a/src/mmgr/protostr/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/protostr - SOURCES protostr.c - DEPS - mmgr/swar -) diff --git a/src/mmgr/protostr/protostr.c b/src/mmgr/protostr/protostr.c deleted file mode 100644 index 9e72613b9..000000000 --- a/src/mmgr/protostr/protostr.c +++ /dev/null @@ -1,1336 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file protostr.c - * @brief The bounded-run operations and their one owner. See protostr.h. - * - * Built on mmgr/swar.h, which is the access layer: it loads a word, tests its lanes and - * names the lane that fired, and nothing in it walks a buffer or takes a capacity. Everything here - * does both. - * - * That split is what keeps swar.h's byte-order claim true. Address order decides which end a lane - * count starts from, and in the access layer that question is asked once, in ::protocore_swar_zero_lane. - * Every other byte-order arm belongs to a walk across a word pair, which is a property of stepping - * through a buffer rather than of reading one word, and lives here. - * - * Exact and case-folding are separate walks, not one walk carrying a flag: the syndrome, the byte - * test and the lane identify are different operations in each. The public entry picks between them - * once; below that point there is nothing to select and no flag to test. - * - * The one symbol this file exports is @ref str. - */ - -#include "mmgr/protostr/protostr.h" -#include "mmgr/swar/swar.h" // the access layer every operation below is built on - -static inline size_t len(const char *s, size_t nul_cap) -{ - // Walk to the boundary a byte at a time. A masked aligned load of the partial first word does - // the same job, but it is a load, a shift, a NOT, an OR, a zero test and a lane extract against - // at most PROTOCORE_SWAR_BYTES-1 byte compares that often do not run at all. - // - // Alignment is what makes the word loop safe to read past the terminator: an aligned load lies - // wholly inside one machine word, so it only touches bytes the string's own page already covers. - size_t i = 0; - while (i < nul_cap && ((uintptr_t)(s + i) & (PROTOCORE_SWAR_BYTES - 1u)) != 0u) - { - if (s[i] == '\0') - { - return i; - } - ++i; - } - while (i + PROTOCORE_SWAR_BYTES <= nul_cap) - { - protocore_swar_word m = swar.has_zero(swar.load_al(s + i)); - if (m != 0) - { - return i + swar.zero_lane(m); // the mask states the lane; no rescan - } - i += PROTOCORE_SWAR_BYTES; - } - // The final partial word, walked a byte at a time so the search cannot end past the bound. A - // whole aligned load here would never fault, since an aligned word cannot straddle a page, but it - // reads bytes the caller did not offer: `nul_cap` is the extent of the object, not a hint about - // where the answer is, and a needle passed by value is exactly as long as it says. - while (i < nul_cap && s[i] != '\0') - { - ++i; - } - return i; -} - -/** - * @brief One byte against one byte, folding ASCII case. - * - * The scalar edge of ::protocore_swar_eq_ci, for the positions a whole word cannot cover. Folding bit 5 is - * only valid when the folded value names a letter, which is the test the range check makes; without - * it `'0'` (0x30) and DLE (0x10) fold together. The exact walk has no counterpart to this: there the - * test is `==`. - */ -PROTOCORE_INLINE int byte_same_ci(uint8_t a, uint8_t b) -{ - if (a == b) - { - return 1; - } - uint8_t la = (uint8_t)(a | 0x20u); - uint8_t lb = (uint8_t)(b | 0x20u); - if (la != lb) - { - return 0; - } - if (la < 'a') - { - return 0; - } - if (la > 'z') - { - return 0; - } - return 1; -} - -static inline size_t diff_cs(const char *a, const char *b, size_t read_cap) -{ - size_t i = 0; - while (i + PROTOCORE_SWAR_BYTES <= read_cap) - { - protocore_swar_word d = swar.load(a + i) ^ swar.load(b + i); - if (d != 0) - { - // Guard bit set on every lane that differs, so the same lane reader that serves the NUL - // scan states the position. `~has_zero` because has_zero marks the lanes that MATCH. - return i + swar.zero_lane(PROTOCORE_SWAR_HIGH & ~swar.has_zero(d)); - } - i += PROTOCORE_SWAR_BYTES; - } - while (i < read_cap && a[i] == b[i]) - { - ++i; - } - return i; -} - -static inline size_t diff_ci(const char *a, const char *b, size_t read_cap) -{ - size_t i = 0; - while (i + PROTOCORE_SWAR_BYTES <= read_cap) - { - protocore_swar_word d = swar.xor_(swar.load(a + i), swar.load(b + i), PROTO_TRUE); - if (d != 0) - { - return i + swar.zero_lane(PROTOCORE_SWAR_HIGH & ~swar.has_zero(d)); - } - i += PROTOCORE_SWAR_BYTES; - } - // The tail runs the same lane math on a one-lane word, so the 0x20 rule is spelled once: the - // empty lanes are 0x00 on both sides and cancel, leaving only the byte in lane 0 to answer. - while (i < read_cap && swar.xor_((protocore_swar_word)(unsigned char)a[i], (protocore_swar_word)(unsigned char)b[i], - PROTO_TRUE) == 0) - { - ++i; - } - return i; -} - -/** - * @brief One word of the agreement test, given the two words already loaded. - * - * One rule for two load shapes, so both loops decide alike. Whichever lane fires lower settles it, - * so nothing past this word is read: an end strictly below the difference means they agreed the - * whole way, and the other side ends there too, because agreeing at the terminator means both hold - * one. Neither mask firing is reported as one lane past the end, so the comparison reads the same - * whether the word ran out of string, ran out of agreement, or neither. - * - * A walk built on this steps a whole word per decision, which is what a byte loop does not. - */ -PROTOCORE_INLINE int step_word_cs(protocore_swar_word wa, protocore_swar_word wb, int end_wins) -{ - protocore_swar_word x = wa ^ wb; - protocore_swar_word z = swar.has_zero(wa); - if ((x | z) == 0) - { - return PROTOCORE_SWAR_GO; - } - size_t dl = PROTOCORE_SWAR_BYTES; - if (x != 0) - { - dl = swar.zero_lane(PROTOCORE_SWAR_HIGH & ~swar.has_zero(x)); - } - size_t el = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - el = swar.zero_lane(z); - } - if (end_wins) - { - if (el <= dl) - { - return PROTOCORE_SWAR_YES; - } - return PROTOCORE_SWAR_NO; - } - if (el < dl) - { - return PROTOCORE_SWAR_YES; - } - return PROTOCORE_SWAR_NO; -} - -/** @brief ::step_word_cs over the case-folded syndrome. Same decision, a different comparison. */ -PROTOCORE_INLINE int step_word_ci(protocore_swar_word wa, protocore_swar_word wb, int end_wins) -{ - protocore_swar_word x = swar.xor_(wa, wb, PROTO_TRUE); - protocore_swar_word z = swar.has_zero(wa); - if ((x | z) == 0) - { - return PROTOCORE_SWAR_GO; - } - size_t dl = PROTOCORE_SWAR_BYTES; - if (x != 0) - { - dl = swar.zero_lane(PROTOCORE_SWAR_HIGH & ~swar.has_zero(x)); - } - size_t el = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - el = swar.zero_lane(z); - } - if (end_wins) - { - if (el <= dl) - { - return PROTOCORE_SWAR_YES; - } - return PROTOCORE_SWAR_NO; - } - if (el < dl) - { - return PROTOCORE_SWAR_YES; - } - return PROTOCORE_SWAR_NO; -} - -/** @brief ::step_word_cs for one byte, serving the head and the tail. Same rule, one lane. */ -PROTOCORE_INLINE int step_byte_cs(unsigned char ca, unsigned char cb, int end_wins) -{ - if (ca == 0) - { - if (ca == cb) - { - return PROTOCORE_SWAR_YES; - } - if (end_wins != 0) - { - return PROTOCORE_SWAR_YES; - } - return PROTOCORE_SWAR_NO; - } - if (ca != cb) - { - return PROTOCORE_SWAR_NO; - } - return PROTOCORE_SWAR_GO; -} - -/** @brief ::step_byte_cs over the case-folded syndrome. */ -PROTOCORE_INLINE int step_byte_ci(unsigned char ca, unsigned char cb, int end_wins) -{ - protocore_swar_word d = swar.xor_((protocore_swar_word)ca, (protocore_swar_word)cb, PROTO_TRUE); - if (ca == 0) - { - if (d == 0) - { - return PROTOCORE_SWAR_YES; - } - if (end_wins != 0) - { - return PROTOCORE_SWAR_YES; - } - return PROTOCORE_SWAR_NO; - } - if (d != 0) - { - return PROTOCORE_SWAR_NO; - } - return PROTOCORE_SWAR_GO; -} - -/** - * @brief Do @p a and @p b agree up to where the deciding one ends? The core of the exact compares. - * - * One pass, which is the whole point of it being one function. Measuring @p a, then measuring @p b, - * then comparing them is three walks to answer what one walk decides, and it is worst on the case - * these serve most: a field name that is NOT the one being sought disagrees at byte 0, so the two - * measuring walks are spent in full to learn nothing. - * - * Per word there are two questions and both come out of the same load pair: where do they part - * (the syndrome), and where does the string end (the zero test). Whichever fires in a lower lane - * settles it, so nothing beyond that word is read: - * - * - end lane strictly below the difference lane -> they agreed the whole way, and the other side - * ends there too, because agreeing at the terminator means both hold one. - * - difference lane at or below the end lane -> they part before either ran out. - * - * @p end_wins is the one bit of behavior that separates the two shapes, and it is the `<` above. - * Equality needs the terminator strictly first: a difference AT the terminator means one string - * carries a byte the other does not, so it is longer and they are not equal. A prefix test wants - * the opposite reading of that same lane - the pattern ended, whatever the subject does next - so - * it passes when the lanes tie. - */ -static inline proto_bool agree_cs(const char *a, const char *b, size_t read_cap, int end_wins) -{ - // `a` is the side whose terminator ends the comparison, and the side that gets aligned - a - // register holds one pointer, so only one of the two can be walked to a boundary. At nearly - // every call site `b` is a literal the compiler answers with immediates, so `a` is the only - // real pointer in the loop. - // - // One loop, deciding in place: a separate prologue would hold the same byte compare twice. - size_t i = 0; - while (i < read_cap) - { - if (((uintptr_t)(a + i) & (PROTOCORE_SWAR_BYTES - 1u)) == 0u && i + PROTOCORE_SWAR_BYTES <= read_cap) - { - protocore_swar_word wa = swar.load_al(a + i); - protocore_swar_word wb = swar.load(b + i); - protocore_swar_word x = wa ^ wb; - protocore_swar_word z = swar.has_zero(wa); - if ((x | z) != 0) - { - // Which mask fires FIRST. That is not a question about positions, so nothing here - // computes one: a lane's guard bit IS its position, and `(v - 1) & ~v` leaves every - // bit BELOW the lowest set one - a value that grows with the position it describes. - // Comparing those two values compares the two positions. - // - // A mask that never fires falls out of the same expression rather than being tested - // for: v == 0 gives all ones, the largest value there is, which is exactly "fires - // after everything". So there is no case for "no terminator in this word", no case - // for "no difference", and no branch for either. - protocore_swar_word xm = PROTOCORE_SWAR_HIGH & ~swar.has_zero(x); // lanes that differ, guard bits - protocore_swar_word zl = (z - (protocore_swar_word)1) & ~z; - protocore_swar_word xl = (xm - (protocore_swar_word)1) & ~xm; -#if PROTOCORE_HW_BIG_ENDIAN - // Lowest address is the HIGHEST bit here, so first-to-fire is the LARGER value. - if (end_wins) - { - return zl >= xl; - } - return zl > xl; -#else - if (end_wins) - { - return zl <= xl; - } - return zl < xl; -#endif - } - i += PROTOCORE_SWAR_BYTES; - continue; - } - unsigned char ca = (unsigned char)a[i]; - unsigned char cb = (unsigned char)b[i]; - if (ca == 0) - { - return (ca == cb) || (end_wins != 0); - } - if (ca != cb) - { - return PROTO_FALSE; - } - ++i; - } - // The bound ran out with no terminator and no disagreement. Equality cannot be claimed for a - // string this never saw the end of; a prefix that filled the whole bound has matched. - return end_wins != 0; -} - -/** @brief ::agree_cs over the case-folded syndrome. Same decision, a different comparison. */ -static inline proto_bool agree_ci(const char *a, const char *b, size_t read_cap, int end_wins) -{ - size_t i = 0; - while (i < read_cap) - { - if (((uintptr_t)(a + i) & (PROTOCORE_SWAR_BYTES - 1u)) == 0u && i + PROTOCORE_SWAR_BYTES <= read_cap) - { - protocore_swar_word wa = swar.load_al(a + i); - protocore_swar_word wb = swar.load(b + i); - protocore_swar_word x = swar.xor_(wa, wb, PROTO_TRUE); - protocore_swar_word z = swar.has_zero(wa); - if ((x | z) != 0) - { - protocore_swar_word xm = PROTOCORE_SWAR_HIGH & ~swar.has_zero(x); - protocore_swar_word zl = (z - (protocore_swar_word)1) & ~z; - protocore_swar_word xl = (xm - (protocore_swar_word)1) & ~xm; -#if PROTOCORE_HW_BIG_ENDIAN - if (end_wins) - { - return zl >= xl; - } - return zl > xl; -#else - if (end_wins) - { - return zl <= xl; - } - return zl < xl; -#endif - } - i += PROTOCORE_SWAR_BYTES; - continue; - } - unsigned char ca = (unsigned char)a[i]; - unsigned char cb = (unsigned char)b[i]; - protocore_swar_word d = swar.xor_((protocore_swar_word)ca, (protocore_swar_word)cb, PROTO_TRUE); - if (ca == 0) - { - return (d == 0) || (end_wins != 0); - } - if (d != 0) - { - return PROTO_FALSE; - } - ++i; - } - return end_wins != 0; -} - -static inline proto_bool eq_cs(const char *a, const char *b, size_t read_cap) -{ - return agree_cs(a, b, read_cap, 0); -} -static inline proto_bool eq_ci(const char *a, const char *b, size_t read_cap) -{ - return agree_ci(a, b, read_cap, 0); -} -static inline proto_bool starts_cs(const char *s, const char *pre, size_t read_cap) -{ - return agree_cs(pre, s, read_cap, 1); // the pattern's terminator is what ends the compare -} -static inline proto_bool starts_ci(const char *s, const char *pre, size_t read_cap) -{ - return agree_ci(pre, s, read_cap, 1); -} - -/** - * @brief The lane a mask names, from whichever end @p rev asks for. - * - * A lane's guard bit IS its position, so naming one is a bit scan and the end it starts from is the - * only thing that separates a forward walk from a reverse one. That is the same swap the byte-order - * arms already make: address order decides which end of the word is the low address, so reading a - * mask backwards on a little-endian load is exactly what reading it forwards on a big-endian one - * does. @p rev selects the other arm. - */ -PROTOCORE_INLINE size_t lane_of(protocore_swar_word m, int rev) -{ -#if PROTOCORE_HW_BIG_ENDIAN - if (rev) - { - return (size_t)((PROTO_SWAR_BITS - 1u - (unsigned)PROTOCORE_SWAR_CTZ(m)) >> 3); - } -#else - if (rev) - { - return (size_t)((PROTOCORE_SWAR_CLZ_WIDTH - 1u - (unsigned)PROTOCORE_SWAR_CLZ(m)) >> 3); - } -#endif - return swar.zero_lane(m); -} - -/** @brief Drop the lane ::lane_of just named, so the next read gives the one after it. */ -PROTOCORE_INLINE protocore_swar_word drop_lane(protocore_swar_word m, int rev) -{ - // Clearing the lowest set bit is `m & (m-1)`; clearing the highest needs its position. Which of - // the two is "the lane just read" is what the byte order and @p rev together decide. -#if PROTOCORE_HW_BIG_ENDIAN - const int clear_low = (rev != 0); -#else - const int clear_low = (rev == 0); -#endif - if (clear_low) - { - return (protocore_swar_word)(m & (m - (protocore_swar_word)1)); - } - return (protocore_swar_word)(m & ~((protocore_swar_word)1 - << (PROTOCORE_SWAR_CLZ_WIDTH - 1u - (unsigned)PROTOCORE_SWAR_CLZ(m)))); -} - -/** - * @brief First occurrence of @p needle in @p hay within @p read_cap bytes, or NULL. Exact. - * - * **Not fixed-work.** Its cost depends on how many candidate lanes the haystack happens to hold, so - * the worst case is a property of the input rather than a number that can be stated before flashing. - * - * The haystack is walked once. One load answers both questions a step has: ::protocore_swar_eq marks every - * lane holding the needle's first byte, ::protocore_swar_has_zero marks the lane the haystack ends on, and - * a word with neither costs that single load before the search steps a whole word past it. Measuring - * the haystack first, to know where to stop, is a second full walk over the same bytes to learn what - * this load already reports. - * - * A candidate is then settled by one load and a masked difference: XOR the haystack word against the - * needle word and AND a mask covering only the needle's own bytes, so zero means the whole needle - * matched. That test cannot run off the end of the haystack, which is why no length is needed to - * bound it: a needle byte is never NUL (the needle stops at its own first one), so a lane where the - * haystack has terminated always differs and always fails the match. - * - * The mask is one shift. Every lane it has to cover is contiguous from the needle's first byte, so - * sliding a word of all-ones until only that run survives states the whole thing in a single - * operation, with nothing in rodata to load and nothing to index. The load width is the largest - * power of two the needle is known to cover, which is what keeps the read inside a needle shorter - * than a word; a longer needle has its head settled by the mask and its tail by the ordinary - * compare. - * - * The walk branches on the needle's length, because the cheapest shape is a function of it: one byte - * needs no funnel, no lookahead word and no extent mask; a pair is settled for every start position - * in a word at once; past that the anchor-plus-verify walk costs less than a mask chain whose length - * grows with the needle. - * - * @p read_cap is ::diff_cs's promise: that many bytes of @p hay are readable. Every wide read below - * is guarded against it, and a candidate too close to the bound for one falls back to bytes. - * - * An empty needle matches at the start, which is what a search for nothing means. - */ -static const char *find_cs(const char *hay, size_t read_cap, const char *needle, size_t needle_cap) -{ - // The load width is the largest power of two at or under `needle_cap`, which the caller states as - // the count of readable bytes, so the load is inside the object by that promise alone. - size_t w = 1u; - if (needle_cap >= PROTOCORE_SWAR_BYTES) - { - w = PROTOCORE_SWAR_BYTES; - } - else if (needle_cap >= 4u) - { - w = 4u; - } - else if (needle_cap >= 2u) - { - w = 2u; - } - - // The ingest is the first operation, and it answers the length as well as supplying the bytes: - // a zero lane at index j < w means needle[j] is the terminator, so nlen is j. The mask only - // decides the length when the terminator lies inside the loaded window; at j == w the needle may - // continue past it and the bound is read the long way. - // Called directly, not as raw.load: xtensa gcc will not inline an always_inline entry it - // reaches through the table, and fails the build. - const protocore_swar_word n_raw = (protocore_swar_word)proto_raw_load(needle, w); - const protocore_swar_word nz = swar.has_zero(n_raw); - // With no terminator in the window, what is left is [w, needle_cap). A single byte there can only - // be the terminator, so nlen is w. Anything longer is read the long way. - size_t j0 = PROTOCORE_SWAR_BYTES; - if (nz != 0) - { - j0 = swar.zero_lane(nz); - } - size_t nlen = j0; - if (j0 >= w) - { - if (needle_cap - w == 1u) - { - nlen = w; - } - else - { - nlen = len(needle, needle_cap); - } - } - if (nlen == 0) - { - return hay; - } - - // needle bytes the masked compare settles - size_t take = w; - if (nlen < w) - { - take = nlen; - } - - // Slide a word of all-ones down until only `take` bytes are left standing. Which end the run is - // anchored at is the one thing a load's byte order decides: the first byte of a w-byte load is - // the low byte of the value on a little-endian machine and the top byte of the w-byte field on a - // big-endian one, so the big-endian arm shifts the surviving run back up to meet it. - // Built at the carrier's own width, because a 64-bit shift by a runtime amount is a call into - // libgcc on every target narrower than 64, for a mask that never leaves one word. The complement - // is truncated back to the carrier BEFORE the shift: a carrier narrower than `int` promotes, and - // an all-ones `int` is -1, whose right shift is arithmetic and refills the bits just cleared. - const protocore_swar_word all = (protocore_swar_word) ~(protocore_swar_word)0; -#if PROTOCORE_HW_BIG_ENDIAN - const protocore_swar_word nm = - (protocore_swar_word)((all >> (PROTOCORE_SWAR_BYTES * 8u - take * 8u)) << ((w - take) * 8u)); -#else - const protocore_swar_word nm = (protocore_swar_word)(all >> (PROTOCORE_SWAR_BYTES * 8u - take * 8u)); -#endif - const protocore_swar_word nw = n_raw & nm; - - // One splatted byte. Folding the needle's last byte in too thins the candidates only where the - // first byte is dense, and pays an extra load per word everywhere else. - const uint8_t c_first = (uint8_t)needle[0]; - - // The walk's anchor. A funnel by `ka` can only reach lane j+ka out of the loaded pair while - // ka stays under one word, which is the clamp; within that the middle byte is taken. - size_t ka = PROTOCORE_SWAR_BYTES - 1u; - if ((nlen / 2u) < PROTOCORE_SWAR_BYTES) - { - ka = nlen / 2u; - } - const uint8_t c_anchor = (uint8_t)needle[ka]; - - size_t i = 0; - - // Head: positions before the first word boundary, one byte at a time. - while (i < read_cap && ((uintptr_t)(hay + i) & (PROTOCORE_SWAR_BYTES - 1u)) != 0u) - { - if (hay[i] == '\0') - { - return NULL; - } - if ((uint8_t)hay[i] == c_first) - { - size_t j = 0; - while (j < nlen && i + j < read_cap && hay[i + j] == needle[j]) - { - ++j; - } - if (j == nlen) - { - return hay + i; - } - } - ++i; - } - - // A start at lane j needs needle[k] at lane j+k, and eq(w, needle[k]) shifted down k lanes has - // lane j set exactly when that holds. ANDing those shifted masks over k leaves a lane set at - // every start the whole needle lands on, so one chain of small operations decides all - // PROTOCORE_SWAR_BYTES positions at once and there is no candidate to walk. - // - // One needle byte needs no funnel, no lookahead word and no extent mask: the match mask and the - // terminator mask are the same shape, so whichever names the lower lane settles the answer. - if (nlen == 1u) - { - while (i + PROTOCORE_SWAR_BYTES <= read_cap) - { - protocore_swar_word w0 = swar.load_al(hay + i); - protocore_swar_word z = swar.has_zero(w0); - protocore_swar_word m = swar.eq(w0, c_first, PROTO_FALSE); - if ((m | z) != 0) - { - // Both cannot name one lane: a needle byte of 0 would have made nlen 0 above. - size_t km = PROTOCORE_SWAR_BYTES; - if (m != 0) - { - km = swar.zero_lane(m); - } - size_t kz = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - kz = swar.zero_lane(z); - } - if (km < kz) - { - return hay + i + km; - } - return NULL; - } - i += PROTOCORE_SWAR_BYTES; - } - } - - // Two needle bytes, decided for every lane at once: a start at lane j needs needle[1] at lane - // j+1, and eq(w, needle[1]) shifted down one lane has lane j set exactly when that holds, so - // ANDing it into the first mask leaves a lane set at every start the pair lands on. - // - // Then mask for the extent out of the word already loaded: lanes at or past the terminator are - // not start positions. On a little-endian load lane order is bit order, so (z-1) & ~z is exactly - // the lanes below the first zero, and all-ones when there is none. - // - // Only at two. This chain costs nlen identifies and nlen-1 funnels per word whatever the input - // holds; the walk below pays per candidate lane instead, which is the cheaper of the two once the - // needle is longer than a pair. - while (nlen >= 2u && nlen <= 3u && nlen <= PROTOCORE_SWAR_BYTES && i + (2u * PROTOCORE_SWAR_BYTES) <= read_cap) - { - protocore_swar_word w0 = swar.load_al(hay + i); - protocore_swar_word w1 = swar.load_al(hay + i + PROTOCORE_SWAR_BYTES); - protocore_swar_word m = swar.eq(w0, c_first, PROTO_FALSE); - for (size_t k = 1u; k < nlen; ++k) - { -#if PROTOCORE_HW_BIG_ENDIAN - protocore_swar_word fk = (protocore_swar_word)((w0 << (8u * k)) | (w1 >> (PROTO_SWAR_BITS - 8u * k))); -#else - protocore_swar_word fk = (protocore_swar_word)((w0 >> (8u * k)) | (w1 << (PROTO_SWAR_BITS - 8u * k))); -#endif - m &= swar.eq(fk, (uint8_t)needle[k], PROTO_FALSE); - } - protocore_swar_word z = swar.has_zero(w0); -#if PROTOCORE_HW_BIG_ENDIAN - size_t zend = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - zend = swar.zero_lane(z); - } - if (zend != PROTOCORE_SWAR_BYTES) - { - m &= (protocore_swar_word)(all << (PROTO_SWAR_BITS - 8u * zend)); - } -#else - m &= (protocore_swar_word)((z - 1u) & ~z); -#endif - if (m != 0) - { - return hay + i + swar.zero_lane(m); - } - if (z != 0) - { - return NULL; - } - i += PROTOCORE_SWAR_BYTES; - } - - // Body: `i` only ever moves a whole word, so every load is aligned. Candidates inside a word are - // walked out of the mask rather than by stepping the pointer to each one, and a candidate is - // verified against a funnel of the two loaded words instead of a fresh unaligned read. - while ((nlen > 3u || nlen > PROTOCORE_SWAR_BYTES) && nlen >= 2u && i + (2u * PROTOCORE_SWAR_BYTES) <= read_cap) - { - protocore_swar_word w0 = swar.load_al(hay + i); - protocore_swar_word w1 = swar.load_al(hay + i + PROTOCORE_SWAR_BYTES); - protocore_swar_word z = swar.has_zero(w0); - // eq against the anchor's own funnel sets lane j when hay[i+j+ka] is needle[ka], which is - // the needle STARTING at j whatever ka is. So which byte anchors is free, and it decides how - // many candidates the verify below runs on. The first byte of a pattern is where a delimiter - // or a capital sits, and both are dense; the middle byte is the one carrying content. - protocore_swar_word wa = w0; - if (ka != 0u) - { -#if PROTOCORE_HW_BIG_ENDIAN - wa = (protocore_swar_word)((w0 << (8u * ka)) | (w1 >> (PROTO_SWAR_BITS - 8u * ka))); -#else - wa = (protocore_swar_word)((w0 >> (8u * ka)) | (w1 << (PROTO_SWAR_BITS - 8u * ka))); -#endif - } - protocore_swar_word m = swar.eq(wa, c_anchor, PROTO_FALSE); - size_t end = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - end = swar.zero_lane(z); - } - - while (m != 0) - { - size_t k = swar.zero_lane(m); - if (k >= end) - { - break; // this candidate is at or past the terminator - } - // The word whose lane 0 is hay[i+k], built from the pair already in registers. - protocore_swar_word wk = w0; - if (k != 0) - { -#if PROTOCORE_HW_BIG_ENDIAN - wk = (protocore_swar_word)((w0 << (8u * k)) | (w1 >> (PROTO_SWAR_BITS - 8u * k))); -#else - wk = (protocore_swar_word)((w0 >> (8u * k)) | (w1 << (PROTO_SWAR_BITS - 8u * k))); -#endif - } - protocore_swar_word syn = (protocore_swar_word)(wk ^ nw); - size_t rest = nlen - take; - if ((syn & nm) == 0 && (take == nlen || (i + k + nlen <= read_cap && - diff_cs(hay + i + k + take, needle + take, rest) == rest))) - { - return hay + i + k; - } - m = drop_lane(m, 0); // the next candidate in address order - } - - if (z != 0) - { - return NULL; - } - i += PROTOCORE_SWAR_BYTES; - } - - // The body stops with up to 2*PROTOCORE_SWAR_BYTES-1 bytes left, because it needs a lookahead word it - // can no longer reach. A whole aligned load is still in bounds while PROTOCORE_SWAR_BYTES of them - // remain, and `i` is on a boundary, so the start positions whose needle lies entirely inside - // that one word take the same shape the body used. Shifting the word down brings zeros in above - // it, and a needle byte is never zero, so the positions that would straddle into the next word - // fail here and are left to the byte loop. That is PROTOCORE_SWAR_BYTES - nlen + 1 positions settled by - // one load instead of by nlen byte compares each. - if (nlen <= PROTOCORE_SWAR_BYTES && i + PROTOCORE_SWAR_BYTES <= read_cap) - { - protocore_swar_word w0 = swar.load_al(hay + i); - protocore_swar_word z = swar.has_zero(w0); - protocore_swar_word m = swar.eq(w0, c_first, PROTO_FALSE); - for (size_t k = 1u; k < nlen; ++k) - { -#if PROTOCORE_HW_BIG_ENDIAN - protocore_swar_word fk = (protocore_swar_word)(w0 << (8u * k)); -#else - protocore_swar_word fk = (protocore_swar_word)(w0 >> (8u * k)); -#endif - m &= swar.eq(fk, (uint8_t)needle[k], PROTO_FALSE); - } -#if PROTOCORE_HW_BIG_ENDIAN - size_t zend = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - zend = swar.zero_lane(z); - } - if (zend != PROTOCORE_SWAR_BYTES) - { - m &= (protocore_swar_word)(all << (PROTO_SWAR_BITS - 8u * zend)); - } -#else - m &= (protocore_swar_word)((z - 1u) & ~z); -#endif - if (m != 0) - { - return hay + i + swar.zero_lane(m); - } - if (z != 0) - { - return NULL; - } - i += PROTOCORE_SWAR_BYTES - nlen + 1u; - } - - // What is left is shorter than a word, or straddles into one that is not there. - while (i < read_cap && hay[i] != '\0') - { - if ((uint8_t)hay[i] == c_first) - { - size_t j = 1u; - while (j < nlen && i + j < read_cap && hay[i + j] == needle[j]) - { - ++j; - } - if (j == nlen) - { - return hay + i; - } - } - ++i; - } - return NULL; -} - -/** - * @brief ::find_cs over the case-folded comparison. - * - * The same walk and the same length dispatch, built on the folding lane tests: ::protocore_swar_eq_ci for - * the candidate mask, ::protocore_swar_xor_ci for the syndrome, ::byte_same_ci for the edges. Folding is - * only sound on letters, which is why the byte test is a function here and an `==` in ::find_cs. - */ -static const char *find_ci(const char *hay, size_t read_cap, const char *needle, size_t needle_cap) -{ - size_t w = 1u; - if (needle_cap >= PROTOCORE_SWAR_BYTES) - { - w = PROTOCORE_SWAR_BYTES; - } - else if (needle_cap >= 4u) - { - w = 4u; - } - else if (needle_cap >= 2u) - { - w = 2u; - } - - // Called directly, not as raw.load: xtensa gcc will not inline an always_inline entry it - // reaches through the table, and fails the build. - const protocore_swar_word n_raw = (protocore_swar_word)proto_raw_load(needle, w); - const protocore_swar_word nz = swar.has_zero(n_raw); - size_t j0 = PROTOCORE_SWAR_BYTES; - if (nz != 0) - { - j0 = swar.zero_lane(nz); - } - size_t nlen = j0; - if (j0 >= w) - { - if (needle_cap - w == 1u) - { - nlen = w; - } - else - { - nlen = len(needle, needle_cap); - } - } - if (nlen == 0) - { - return hay; - } - - size_t take = w; - if (nlen < w) - { - take = nlen; - } - - const protocore_swar_word all = (protocore_swar_word) ~(protocore_swar_word)0; -#if PROTOCORE_HW_BIG_ENDIAN - const protocore_swar_word nm = - (protocore_swar_word)((all >> (PROTOCORE_SWAR_BYTES * 8u - take * 8u)) << ((w - take) * 8u)); -#else - const protocore_swar_word nm = (protocore_swar_word)(all >> (PROTOCORE_SWAR_BYTES * 8u - take * 8u)); -#endif - const protocore_swar_word nw = n_raw & nm; - - const uint8_t c_first = (uint8_t)needle[0]; - size_t ka = PROTOCORE_SWAR_BYTES - 1u; - if ((nlen / 2u) < PROTOCORE_SWAR_BYTES) - { - ka = nlen / 2u; - } - const uint8_t c_anchor = (uint8_t)needle[ka]; - - size_t i = 0; - - while (i < read_cap && ((uintptr_t)(hay + i) & (PROTOCORE_SWAR_BYTES - 1u)) != 0u) - { - if (hay[i] == '\0') - { - return NULL; - } - if (byte_same_ci((uint8_t)hay[i], c_first)) - { - size_t j = 0; - while (j < nlen && i + j < read_cap && byte_same_ci((uint8_t)hay[i + j], (uint8_t)needle[j])) - { - ++j; - } - if (j == nlen) - { - return hay + i; - } - } - ++i; - } - - if (nlen == 1u) - { - while (i + PROTOCORE_SWAR_BYTES <= read_cap) - { - protocore_swar_word w0 = swar.load_al(hay + i); - protocore_swar_word z = swar.has_zero(w0); - protocore_swar_word m = swar.eq(w0, c_first, PROTO_TRUE); - if ((m | z) != 0) - { - size_t km = PROTOCORE_SWAR_BYTES; - if (m != 0) - { - km = swar.zero_lane(m); - } - size_t kz = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - kz = swar.zero_lane(z); - } - if (km < kz) - { - return hay + i + km; - } - return NULL; - } - i += PROTOCORE_SWAR_BYTES; - } - } - - while (nlen >= 2u && nlen <= 3u && nlen <= PROTOCORE_SWAR_BYTES && i + (2u * PROTOCORE_SWAR_BYTES) <= read_cap) - { - protocore_swar_word w0 = swar.load_al(hay + i); - protocore_swar_word w1 = swar.load_al(hay + i + PROTOCORE_SWAR_BYTES); - protocore_swar_word m = swar.eq(w0, c_first, PROTO_TRUE); - for (size_t k = 1u; k < nlen; ++k) - { -#if PROTOCORE_HW_BIG_ENDIAN - protocore_swar_word fk = (protocore_swar_word)((w0 << (8u * k)) | (w1 >> (PROTO_SWAR_BITS - 8u * k))); -#else - protocore_swar_word fk = (protocore_swar_word)((w0 >> (8u * k)) | (w1 << (PROTO_SWAR_BITS - 8u * k))); -#endif - m &= swar.eq(fk, (uint8_t)needle[k], PROTO_TRUE); - } - protocore_swar_word z = swar.has_zero(w0); -#if PROTOCORE_HW_BIG_ENDIAN - size_t zend = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - zend = swar.zero_lane(z); - } - if (zend != PROTOCORE_SWAR_BYTES) - { - m &= (protocore_swar_word)(all << (PROTO_SWAR_BITS - 8u * zend)); - } -#else - m &= (protocore_swar_word)((z - 1u) & ~z); -#endif - if (m != 0) - { - return hay + i + swar.zero_lane(m); - } - if (z != 0) - { - return NULL; - } - i += PROTOCORE_SWAR_BYTES; - } - - while ((nlen > 3u || nlen > PROTOCORE_SWAR_BYTES) && nlen >= 2u && i + (2u * PROTOCORE_SWAR_BYTES) <= read_cap) - { - protocore_swar_word w0 = swar.load_al(hay + i); - protocore_swar_word w1 = swar.load_al(hay + i + PROTOCORE_SWAR_BYTES); - protocore_swar_word z = swar.has_zero(w0); - protocore_swar_word wa = w0; - if (ka != 0u) - { -#if PROTOCORE_HW_BIG_ENDIAN - wa = (protocore_swar_word)((w0 << (8u * ka)) | (w1 >> (PROTO_SWAR_BITS - 8u * ka))); -#else - wa = (protocore_swar_word)((w0 >> (8u * ka)) | (w1 << (PROTO_SWAR_BITS - 8u * ka))); -#endif - } - protocore_swar_word m = swar.eq(wa, c_anchor, PROTO_TRUE); - size_t end = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - end = swar.zero_lane(z); - } - - while (m != 0) - { - size_t k = swar.zero_lane(m); - if (k >= end) - { - break; - } - protocore_swar_word wk = w0; - if (k != 0) - { -#if PROTOCORE_HW_BIG_ENDIAN - wk = (protocore_swar_word)((w0 << (8u * k)) | (w1 >> (PROTO_SWAR_BITS - 8u * k))); -#else - wk = (protocore_swar_word)((w0 >> (8u * k)) | (w1 << (PROTO_SWAR_BITS - 8u * k))); -#endif - } - protocore_swar_word syn = swar.xor_(wk, nw, PROTO_TRUE); - size_t rest = nlen - take; - if ((syn & nm) == 0 && (take == nlen || (i + k + nlen <= read_cap && - diff_ci(hay + i + k + take, needle + take, rest) == rest))) - { - return hay + i + k; - } - m = drop_lane(m, 0); - } - - if (z != 0) - { - return NULL; - } - i += PROTOCORE_SWAR_BYTES; - } - - if (nlen <= PROTOCORE_SWAR_BYTES && i + PROTOCORE_SWAR_BYTES <= read_cap) - { - protocore_swar_word w0 = swar.load_al(hay + i); - protocore_swar_word z = swar.has_zero(w0); - protocore_swar_word m = swar.eq(w0, c_first, PROTO_TRUE); - for (size_t k = 1u; k < nlen; ++k) - { -#if PROTOCORE_HW_BIG_ENDIAN - protocore_swar_word fk = (protocore_swar_word)(w0 << (8u * k)); -#else - protocore_swar_word fk = (protocore_swar_word)(w0 >> (8u * k)); -#endif - m &= swar.eq(fk, (uint8_t)needle[k], PROTO_TRUE); - } -#if PROTOCORE_HW_BIG_ENDIAN - size_t zend = PROTOCORE_SWAR_BYTES; - if (z != 0) - { - zend = swar.zero_lane(z); - } - if (zend != PROTOCORE_SWAR_BYTES) - { - m &= (protocore_swar_word)(all << (PROTO_SWAR_BITS - 8u * zend)); - } -#else - m &= (protocore_swar_word)((z - 1u) & ~z); -#endif - if (m != 0) - { - return hay + i + swar.zero_lane(m); - } - if (z != 0) - { - return NULL; - } - i += PROTOCORE_SWAR_BYTES - nlen + 1u; - } - - while (i < read_cap && hay[i] != '\0') - { - if (byte_same_ci((uint8_t)hay[i], c_first)) - { - size_t j = 1u; - while (j < nlen && i + j < read_cap && byte_same_ci((uint8_t)hay[i + j], (uint8_t)needle[j])) - { - ++j; - } - if (j == nlen) - { - return hay + i; - } - } - ++i; - } - return NULL; -} - -static inline size_t copy(char *dst, const char *src, size_t dst_cap) -{ - if (dst_cap == 0) - { - return 0; - } - // The bound reaches the scan as a `nul_cap`, a willingness to look that far, so a shorter source - // is copied whole. - size_t n = len(src, dst_cap - 1); - raw.read(dst, src, n); - dst[n] = '\0'; - return n; -} - -// The dispatch. One branch, at the door, naming which of the two walks runs. Nothing below this -// point carries a flag or tests one. -static size_t diff(const char *a, const char *b, size_t read_cap, proto_bool ci) -{ - if (ci) - { - return diff_ci(a, b, read_cap); - } - return diff_cs(a, b, read_cap); -} - -static proto_bool eq(const char *a, const char *b, size_t read_cap, proto_bool ci) -{ - if (ci) - { - return eq_ci(a, b, read_cap); - } - return eq_cs(a, b, read_cap); -} - -static proto_bool starts(const char *s, const char *pre, size_t read_cap, proto_bool ci) -{ - if (ci) - { - return starts_ci(s, pre, read_cap); - } - return starts_cs(s, pre, read_cap); -} - -static const char *find(const char *hay, size_t read_cap, const char *needle, size_t needle_cap, proto_bool ci) -{ - if (ci) - { - return find_ci(hay, read_cap, needle, needle_cap); - } - return find_cs(hay, read_cap, needle, needle_cap); -} - -static proto_bool has(const char *hay, size_t read_cap, const char *needle, size_t needle_cap, proto_bool ci) -{ - if (ci) - { - return find_ci(hay, read_cap, needle, needle_cap) != NULL; - } - return find_cs(hay, read_cap, needle, needle_cap) != NULL; -} - -static int step_word(protocore_swar_word wa, protocore_swar_word wb, proto_bool ci, int end_wins) -{ - if (ci) - { - return step_word_ci(wa, wb, end_wins); - } - return step_word_cs(wa, wb, end_wins); -} - -static int step_byte(unsigned char ca, unsigned char cb, proto_bool ci, int end_wins) -{ - if (ci) - { - return step_byte_ci(ca, cb, end_wins); - } - return step_byte_cs(ca, cb, end_wins); -} - -static proto_bool ws(char c) -{ - return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'; -} - -static proto_bool digit(char c) -{ - return c >= '0' && c <= '9'; -} - -static long to_long(const char *s, const char **end) -{ - const char *p = s; - while (ws(*p)) - { - p++; - } - proto_bool neg = PROTO_FALSE; - if (*p == '+' || *p == '-') - { - neg = (*p++ == '-'); - } - const char *ds = p; - unsigned long v = 0; // accumulate unsigned: signed overflow on a huge digit run is undefined - while (digit(*p)) - { - v = v * 10UL + (unsigned long)(*p++ - '0'); - } - if (end) - { - *end = s; - if (p != ds) - { - *end = p; - } - } - if (neg) - { - return (long)(0UL - v); // two's-complement reinterpret, so no negation overflow - } - return (long)v; -} - -static unsigned long to_ulong(const char *s, const char **end) -{ - const char *p = s; - while (ws(*p)) - { - p++; - } - if (*p == '+') - { - p++; - } - const char *ds = p; - unsigned long v = 0; - while (digit(*p)) - { - v = v * 10UL + (unsigned long)(*p++ - '0'); - } - if (end) - { - *end = s; - if (p != ds) - { - *end = p; - } - } - return v; -} - -// The fractional part after a '.', advancing p and accumulating into val. -static void frac(const char **p, double *val, proto_bool *any) -{ - (*p)++; // consume '.' - double scale = 1.0; - while (digit(**p)) - { - scale *= 10.0; - *val += (double)(*(*p)++ - '0') / scale; - *any = PROTO_TRUE; - } -} - -// A trailing exponent (e[+/-]NNN) applied to val, advancing p past it. -static void expo(const char **p, double *val) -{ - (*p)++; // consume 'e'/'E' - proto_bool eneg = PROTO_FALSE; - if (**p == '+' || **p == '-') - { - eneg = (*(*p)++ == '-'); - } - int ex = 0; - while (digit(**p)) - { - if (ex < 400) // clamp: 10^400 overflows the double to inf, so more digits change nothing - { - ex = ex * 10 + (**p - '0'); - } - (*p)++; - } - double m = 1.0; - for (int k = 0; k < ex; k++) - { - m *= 10.0; - } - if (eneg) - { - *val = *val / m; - return; - } - *val = *val * m; -} - -static double to_double(const char *s, const char **end) -{ - const char *p = s; - while (ws(*p)) - { - p++; - } - proto_bool neg = PROTO_FALSE; - if (*p == '+' || *p == '-') - { - neg = (*p++ == '-'); - } - proto_bool any = PROTO_FALSE; - double val = 0.0; - while (digit(*p)) - { - val = val * 10.0 + (*p++ - '0'); - any = PROTO_TRUE; - } - if (*p == '.') - { - frac(&p, &val, &any); - } - if (any && (*p == 'e' || *p == 'E')) - { - expo(&p, &val); - } - if (end) - { - *end = s; - if (any) - { - *end = p; - } - } - if (neg) - { - return -val; - } - return val; -} - -// Through the double, because sub-meter values (a GGA latitude) need its precision to land right. -static float to_float(const char *s, const char **end) -{ - return (float)to_double(s, end); -} - -const StrNs str = {len, diff, eq, starts, find, has, copy, step_word, - step_byte, ws, digit, to_long, to_ulong, to_double, to_float}; diff --git a/src/mmgr/protostr/protostr.h b/src/mmgr/protostr/protostr.h deleted file mode 100644 index 21ff99269..000000000 --- a/src/mmgr/protostr/protostr.h +++ /dev/null @@ -1,142 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file protostr.h - * @brief Operations over a bounded run of bytes: where it ends, where two part company, whether one - * occurs inside another, and moving one into a bounded destination. - * - * In mmgr beside @ref mem because both walk what mmgr hands out. That file moves a span given its - * length; this one answers where the length is. - * - * Every entry point takes an explicit capacity. A bound is the caller's statement about the object, - * not a hint: `nul_cap` is how many bytes may be read looking for a terminator, `read_cap` is a - * promise that many bytes ARE readable, and `dst_cap` is what a write may fill. - * - * Every comparison takes @c ci, which folds bit 5 on ASCII letters so a compare ignores case. It is - * the switch inside the one body, not a second entry point. - * - * The module exports one symbol, @ref str. Everything in protostr.c has internal linkage. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_PROTOSTR_H -#define PROTOCORE_PROTOSTR_H - -#include "mmgr/swar/swar.h" // protocore_swar_word and PROTOCORE_SWAR_GO/YES/NO: the step members' currency - -#include "protocore_config.h" - -PROTOCORE_BEGIN_DECLS - -/** - * @brief The bounded-run module. Every walk steps one register-width load at a time. - * - * @var StrNs::len - * Index of the first NUL in @c s within @c nul_cap bytes, or @c nul_cap if there is none. The - * bounded strnlen this library wants, a word per test instead of a byte. - * - * **@c nul_cap is a willingness, not a promise.** It says how far this may keep looking, and nothing - * about how much of @c s exists: `str.len(payload, 0xFFFF)` over a five-byte literal is the intended - * use. That is the opposite of the @c read_cap every compare below takes. - * - * @var StrNs::diff - * Index of the first byte where @c a and @c b differ, or @c read_cap if they agree throughout. XOR - * zeroes every matching lane, so the lanes that differ are exactly the nonzero ones and the lane - * math names the first of them. - * - * **@c read_cap is a promise, not a willingness.** Both operands must hold that many readable bytes, - * because this never looks for a terminator and so has nothing else to stop it. Every compare below - * carries the same contract. - * - * @var StrNs::eq - * True when @c a and @c b are the same NUL-terminated string within @c read_cap bytes. A prefix - * never passes as the whole: the terminator has to arrive strictly before the first disagreement. - * - * @var StrNs::starts - * True when @c s begins with @c pre, both holding @c read_cap readable bytes. The same walk @ref - * StrNs::eq runs, reading the tie the other way: the pattern ended, whatever the subject does next. - * - * @var StrNs::find - * First occurrence of @c needle in @c hay within @c read_cap bytes, or NULL. The haystack is walked - * once: one load marks every lane holding the needle's anchor byte and the lane the haystack ends - * on, and a candidate is settled by a masked difference against the needle word. - * - * An empty needle matches at the start. A haystack NUL ends the search but does not truncate it: - * @c read_cap bounds the walk, and a needle byte is never NUL, so a terminated lane always fails - * the match rather than passing. - * - * @var StrNs::has - * Whether @c needle occurs in @c hay. The same scan @ref StrNs::find runs, asked for less. - * - * @var StrNs::copy - * Copy the NUL-terminated @c src into @c dst, which holds @c dst_cap bytes, and return the length - * written. Always terminates, and writes only the bytes it copies. A @c dst_cap of 0 writes nothing. - * The bound belongs to the DESTINATION: nothing is claimed about how long @c src is. - * - * @var StrNs::step_word - * One word of the agreement test, given the two words the caller already loaded: @ref PROTOCORE_SWAR_GO to - * keep stepping, @ref PROTOCORE_SWAR_YES or @ref PROTOCORE_SWAR_NO once this word settles it. Whichever lane fires - * lower decides, so nothing past this word is read. @c end_wins reads the tie as a match, which is - * what a prefix test wants and what an equality test does not. - * - * This is what a walk steps with instead of a byte at a time. - * - * @var StrNs::step_byte - * @ref StrNs::step_word for one byte, serving the head and the tail a whole word cannot cover. Same - * rule, one lane. - * - * @var StrNs::ws - * Whether @c c is one of the six ASCII whitespace characters. - * - * @var StrNs::digit - * Whether @c c is an ASCII decimal digit. - * - * @var StrNs::to_long - * Read a base-10 long from @c s. Skips leading whitespace, takes an optional sign, consumes digits, - * and points @c end past them - or back at @c s when no digit converted, which is how a caller tells - * "no number" from a parsed zero. @c end may be NULL. - * - * @var StrNs::to_ulong - * @ref StrNs::to_long without the sign: a leading `+` is consumed, a `-` is not. - * - * @var StrNs::to_double - * Read `integer[.frac][e[+/-]exp]` from @c s, with @ref StrNs::to_long's @c end contract. The - * exponent is clamped, because past ten to the four hundredth the double is already infinite. - * - * @var StrNs::to_float - * @ref StrNs::to_double narrowed. It parses at double precision first, which is what a sub-meter - * value like a GGA latitude needs to land on the right float. - * - * **None of these are constant time.** Each stops at the byte that settles it, so how long it runs - * states how many leading bytes matched. A secret comparison uses protocore_ct_eq (crypto/ct_eq.h). - * - * No storage member: every operation works on the caller's pointers and holds nothing of its own. - */ -typedef struct -{ - size_t (*len)(const char *s, size_t nul_cap); - size_t (*diff)(const char *a, const char *b, size_t read_cap, proto_bool ci); - proto_bool (*eq)(const char *a, const char *b, size_t read_cap, proto_bool ci); - proto_bool (*starts)(const char *s, const char *pre, size_t read_cap, proto_bool ci); - const char *(*find)(const char *hay, size_t read_cap, const char *needle, size_t needle_cap, proto_bool ci); - proto_bool (*has)(const char *hay, size_t read_cap, const char *needle, size_t needle_cap, proto_bool ci); - size_t (*copy)(char *dst, const char *src, size_t dst_cap); - int (*step_word)(protocore_swar_word wa, protocore_swar_word wb, proto_bool ci, int end_wins); - int (*step_byte)(unsigned char ca, unsigned char cb, proto_bool ci, int end_wins); - proto_bool (*ws)(char c); - proto_bool (*digit)(char c); - long (*to_long)(const char *s, const char **end); - unsigned long (*to_ulong)(const char *s, const char **end); - double (*to_double)(const char *s, const char **end); - float (*to_float)(const char *s, const char **end); -} StrNs; - -/** @brief The one symbol this module exports. */ -extern const StrNs str; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_PROTOSTR_H diff --git a/src/mmgr/psram_pool/CMakeLists.txt b/src/mmgr/psram_pool/CMakeLists.txt deleted file mode 100644 index d10463cb7..000000000 --- a/src/mmgr/psram_pool/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/psram_pool - GATE PROTOCORE_ENABLE_PSRAM_POOL - SOURCES psram_pool.c -) diff --git a/src/mmgr/psram_pool/psram_pool.c b/src/mmgr/psram_pool/psram_pool.c deleted file mode 100644 index 1efda0ada..000000000 --- a/src/mmgr/psram_pool/psram_pool.c +++ /dev/null @@ -1,95 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file psram_pool.c - * @brief Buffer placement policy + SPI DMA ping-pong index manager (see psram_pool.h). - */ - -#include "protocore_config.h" // the entry point: the enable gate below, and the widths - -#if PROTOCORE_ENABLE_PSRAM_POOL - -#include "mmgr/psram_pool/psram_pool.h" - -PROTOCORE_BEGIN_DECLS - -// Does `size` fit in DRAM while still leaving `reserve` free? Subtracts instead of summing, so no -// width of size_t can wrap the comparison. -static proto_bool dram_fits(size_t size, size_t free_dram, size_t reserve) -{ - return size <= free_dram && (free_dram - size) >= reserve; -} - -protocore_place protocore_psram_place(size_t size, proto_bool dma_required, size_t free_dram, size_t free_psram, - size_t psram_threshold, size_t dram_reserve) -{ - if (size == 0) - { - return PLACE_FAIL; - } - - proto_bool d_fits = dram_fits(size, free_dram, dram_reserve); - proto_bool p_fits = size <= free_psram; - - if (dma_required) // PSRAM is not DMA-capable: DRAM or bust. - { - return d_fits ? PLACE_DRAM : PLACE_FAIL; - } - - if (size >= psram_threshold) // large / cold: prefer PSRAM. - { - if (p_fits) - { - return PLACE_PSRAM; - } - if (d_fits) - { - return PLACE_DRAM; - } - return PLACE_FAIL; - } - - // small / hot: prefer DRAM. - if (d_fits) - { - return PLACE_DRAM; - } - if (p_fits) - { - return PLACE_PSRAM; - } - return PLACE_FAIL; -} - -void protocore_pingpong_init(PingPong *pp) -{ - if (pp) - { - pp->fill_idx = 0; - } -} - -uint8_t protocore_pingpong_fill_index(const PingPong *pp) -{ - return pp ? pp->fill_idx : 0; -} - -uint8_t protocore_pingpong_drain_index(const PingPong *pp) -{ - return pp ? (uint8_t)(pp->fill_idx ^ 1u) : 1; -} - -uint8_t protocore_pingpong_swap(PingPong *pp) -{ - if (!pp) - { - return 0; - } - pp->fill_idx ^= 1u; - return pp->fill_idx; -} - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_ENABLE_PSRAM_POOL diff --git a/src/mmgr/psram_pool/psram_pool.h b/src/mmgr/psram_pool/psram_pool.h deleted file mode 100644 index 1f7844620..000000000 --- a/src/mmgr/psram_pool/psram_pool.h +++ /dev/null @@ -1,77 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file psram_pool.h - * @brief Buffer placement policy (DRAM vs PSRAM) + SPI DMA ping-pong index manager - * (PROTOCORE_ENABLE_PSRAM_POOL). - * - * An ESP32 with PSRAM has two heaps: fast internal DRAM (scarce, DMA-capable) and large external PSRAM - * (roomy, but not DMA-capable for most peripherals and slower). Serving big web assets / net buffers well - * means putting the large, cold buffers in PSRAM and keeping the small, hot, DMA buffers in DRAM, while - * always leaving an internal-DRAM reserve so the stack does not starve. That placement choice is a pure - * policy; the actual `heap_caps_calloc(..., MALLOC_CAP_SPIRAM / MALLOC_CAP_DMA)` is the app's. - * - * This module is that policy (`protocore_psram_place`) plus the classic SPI DMA **ping-pong** double-buffer - * bookkeeping (`protocore_pingpong_*`): while DMA drains one buffer, the CPU fills the other, and a swap - * exchanges their roles. Pure, no heap, no stdlib, host-testable. - */ - -#ifndef PROTOCORE_PSRAM_POOL_H -#define PROTOCORE_PSRAM_POOL_H - -#include "protocore_config.h" // the entry point: protocore_types.h for the widths - -#if PROTOCORE_ENABLE_PSRAM_POOL - -PROTOCORE_BEGIN_DECLS - -/** @brief Placement verdict (the sole return of protocore_psram_place). */ -typedef enum PROTO_ENUM_PACKED -{ - PLACE_DRAM = 0, ///< allocate in internal DRAM. - PLACE_PSRAM = 1, ///< allocate in external PSRAM. - PLACE_FAIL = 2 ///< neither heap can satisfy the request. -} protocore_place; - -/** - * @brief Decide where a buffer should live. - * - * Rules: a zero-size request fails; a DMA-required buffer must go in DRAM (or fail); a buffer at or above - * @p psram_threshold prefers PSRAM (falling back to DRAM); a smaller buffer prefers DRAM (falling back to - * PSRAM). A DRAM placement must still leave @p dram_reserve bytes free in DRAM. - * - * @param size requested bytes. - * @param dma_required true if the buffer must be DMA-capable (DRAM only). - * @param free_dram currently free internal DRAM. - * @param free_psram currently free PSRAM (0 if no PSRAM). - * @param psram_threshold size at/above which PSRAM is preferred. - * @param dram_reserve internal DRAM to keep free after a DRAM placement. - * @return PLACE_DRAM / PLACE_PSRAM / PLACE_FAIL. - */ -protocore_place protocore_psram_place(size_t size, proto_bool dma_required, size_t free_dram, size_t free_psram, - size_t psram_threshold, size_t dram_reserve); - -/** @brief SPI DMA ping-pong double-buffer state. */ -typedef struct -{ - uint8_t fill_idx; ///< buffer the CPU is filling (DMA drains the other). -} PingPong; - -/** @brief Initialize: CPU fills buffer 0, DMA drains buffer 1. */ -void protocore_pingpong_init(PingPong *pp); - -/** @brief The buffer index the CPU should fill. */ -uint8_t protocore_pingpong_fill_index(const PingPong *pp); - -/** @brief The buffer index DMA should drain (the other one). */ -uint8_t protocore_pingpong_drain_index(const PingPong *pp); - -/** @brief Swap roles (a filled buffer is handed to DMA; the drained one is now filled). @return new fill index. */ -uint8_t protocore_pingpong_swap(PingPong *pp); - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_ENABLE_PSRAM_POOL - -#endif // PROTOCORE_PSRAM_POOL_H diff --git a/src/mmgr/rawmemcpy/CMakeLists.txt b/src/mmgr/rawmemcpy/CMakeLists.txt deleted file mode 100644 index 7c393b4d6..000000000 --- a/src/mmgr/rawmemcpy/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/rawmemcpy - SOURCES rawmemcpy.c -) diff --git a/src/mmgr/rawmemcpy/rawmemcpy.c b/src/mmgr/rawmemcpy/rawmemcpy.c deleted file mode 100644 index 2ae5e0c0c..000000000 --- a/src/mmgr/rawmemcpy/rawmemcpy.c +++ /dev/null @@ -1,83 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file rawmemcpy.c - * @brief The arbitrary-width span move - see rawmemcpy.h. - * - * The scalar rungs stay in the header, where each one folds to a single load or store at its call - * site. This file holds the one body with loops in it: the ladder that aligns the destination, steps - * PROTO_RAW_WORD bytes at a time, and funnels a source that does not share the destination's - * boundary. - * - * The one symbol this file defines is ::proto_raw_read. - */ - -#include "mmgr/rawmemcpy/rawmemcpy.h" - -void proto_raw_read(void *dst, const void *p, size_t sz) -{ - unsigned char *d = (unsigned char *)dst; - const unsigned char *u = (const unsigned char *)p; - const uintptr_t mask = (uintptr_t)(PROTO_RAW_WORD - 1u); - size_t i = 0; - - // Head: bytes until the DESTINATION is on a boundary. Fewer than one word, once. The - // destination is the side that gets aligned because every step below writes it, and a store - // that has to be assembled from bytes costs the same as a load that does. - while (i < sz && ((uintptr_t)(d + i) & mask) != 0u) - { - d[i] = u[i]; - i++; - } - - const size_t off = (size_t)((uintptr_t)(u + i) & mask); - if (off == 0u) - { - // Both on a boundary: the machine's own load and its own store, nothing in between. - while (sz - i >= PROTO_RAW_WORD) - { - proto_mv_put(d + i, proto_mv_load(u + i)); - i += PROTO_RAW_WORD; - } - } - else if (sz - i >= PROTO_RAW_WORD) - { - // Not co-aligned, and the answer is NOT to fall back to bytes. Read the source at its own - // boundary and funnel each adjacent PAIR of aligned words into the word the destination - // wants: one shifts down by the misalignment, the next shifts up by the rest, and the OR - // joins them. Both shifts move every lane at once, so the misalignment costs two shifts and - // an OR per word instead of a byte loop - and every access stays a real load and a real - // store, which on a part with no unaligned instruction is the whole difference. - // - // Address order decides which way each shift goes: on a little-endian load the lowest byte - // sits in the low bits, so the earlier word shifts DOWN; big-endian is the mirror. - // - // The priming load reads a whole word, so it is spent only once there is a whole word of - // work: with fewer bytes left than that the loop below never runs, and the load would reach - // past a source that short for a value nothing reads. The tail takes those bytes instead. - const unsigned char *sa = (u + i) - off; - const unsigned lo = (unsigned)(off * 8u); - const unsigned hi = (unsigned)(PROTO_MV_BITS - (off * 8u)); - proto_mv_word prev = proto_mv_load(sa); - while (sz - i >= PROTO_RAW_WORD) - { - sa += PROTO_RAW_WORD; - proto_mv_word cur = proto_mv_load(sa); -#if PROTOCORE_HW_BIG_ENDIAN - proto_mv_put(d + i, (proto_mv_word)((prev << lo) | (cur >> hi))); -#else - proto_mv_put(d + i, (proto_mv_word)((prev >> lo) | (cur << hi))); -#endif - prev = cur; - i += PROTO_RAW_WORD; - } - } - - // Tail: fewer than a word left. - while (i < sz) - { - d[i] = u[i]; - i++; - } -} diff --git a/src/mmgr/rawmemcpy/rawmemcpy.h b/src/mmgr/rawmemcpy/rawmemcpy.h deleted file mode 100644 index e3ce30e31..000000000 --- a/src/mmgr/rawmemcpy/rawmemcpy.h +++ /dev/null @@ -1,357 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file rawmemcpy.h - * @brief The raw load: bytes at a pointer read as a wider type, in the machine's own order. - * - * One owner for the operation every word-at-a-time reader needs - the lane math (swar.h), the - * span walks (protomem.c), the builder's float bit reads (membuild.h) - so the alignment rule is - * stated once and every reader inherits it. - * - * **The two attributes are the whole implementation.** A bare `*(const uint32_t *)p` says the wrong - * thing twice, and each attribute answers one of them: `aligned(1)` states that the address carries - * no alignment guarantee, and `may_alias` states that this type may alias any other. - * - * **Machine order, not wire order.** These reconstruct the value the way this machine stores it, - * which is what reading a representation means. A defined byte order on the wire is a different - * question and belongs to mmgr/endian.h. - * - * These are the primitives the span walks are built from. A caller that wants to move a span asks - * @ref mem for it. - * - * The module exports @ref raw. Each scalar rung is one load or store and stays here, where a call - * site folds it; the ladder @ref RawNs::read steps down has loops and lives in rawmemcpy.c. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_RAWMEMCPY_H -#define PROTOCORE_RAWMEMCPY_H - -#include "protocore_config.h" // PROTO_WORD_BITS: the register width the die declared - -PROTOCORE_BEGIN_DECLS - -/** - * @brief The attributes that make a raw access legal, named once. - * - * A struct read out of a byte stream needs exactly what a scalar does: it sits at whatever offset - * the stream put it, and it is being reached through a pointer of another type. Carrying this on - * the declaration is what stops the compiler assuming the struct's natural alignment and emitting - * wide member loads that fault - the same failure as the scalar case, only harder to see, because - * a struct's alignment is inherited from its widest member rather than written down. - * - * typedef struct PROTO_RAW { uint32_t id; uint16_t len; } wire_hdr; - */ -#define PROTO_RAW __attribute__((aligned(1), may_alias)) - -/** - * @brief Declare storage aligned to @p n bytes - the other half of the same platform question. - * - * ::PROTO_RAW says an address carries no guarantee; this states one. Both belong here because they - * are the same decision seen from either end, and a codebase that spells alignment two ways ends up - * with a pool that is aligned on one target and not on the next. @p n must be a power of two. - * - * static uint8_t PROTO_ALIGN(PROTOCORE_ARENA_MAX_ALIGN) arena_store[PROTOCORE_ARENA_SIZE]; - * - * This is the declaration, not the arithmetic: rounding a runtime offset up to a boundary is the - * arena's job (mmgr/arena.h), which is where that already lives. - */ -#define PROTO_ALIGN(n) __attribute__((aligned(n))) - -/** - * @brief The aliasing half of ::PROTO_RAW without the alignment disclaimer. - * - * Reading one object through a pointer of another type still needs `may_alias` or the optimizer may - * reorder or drop the access. What it does NOT need, once the caller has proven the address is - * aligned, is `aligned(1)` - and dropping that is the difference between one load instruction and a - * hand-built word. - */ -#define PROTO_ALIAS __attribute__((may_alias)) - -/** - * @brief The widest step a multi-byte move takes here: the register width the die declared. - * - * There are only three distinct operations in this file - load 2, load 4, load 8 - and every width - * above the top rung is that same load repeated, not a new one, because C has no wider scalar and - * asking for one only makes the compiler build it out of these anyway, with the halves parked in - * registers the caller cannot see. Anything past 64 bits is the caller's own walk over @ref - * RawNs::u32, in whatever limb order that caller's arithmetic already stores. - * - * Below the top rung a move shifts down: each rung is half the one above, so the tail costs at most - * one pass each. - * - * Taken from PROTO_WORD_BITS, which the die states in vendor/board_profiles/, rather than - * from UINTPTR_MAX. Reading the pointer width measures the BUILD MACHINE: the host toolchain is - * 64-bit, so that inference gave the host an 8-byte ladder while every target in the list steps 4, - * and a move is then a different shape in the test than in the thing being tested. - */ -#if PROTO_WORD_BITS >= 64 -#define PROTO_RAW_WORD 8 -#elif PROTO_WORD_BITS >= 32 -#define PROTO_RAW_WORD 4 -#else -#define PROTO_RAW_WORD 2 -#endif - -/// @brief The mover's rung in bits. -#define PROTO_MV_BITS (PROTO_RAW_WORD * 8u) - -/// @brief Unaligned, aliasing-permitted views of each scalar width. Declared once so the two -/// attributes that make the load legal cannot be omitted at a call site. -typedef uint16_t proto_raw_u16_t PROTO_RAW; -typedef uint32_t proto_raw_u32_t PROTO_RAW; -typedef uint64_t proto_raw_u64_t PROTO_RAW; - -/// @brief Aliasing-permitted views at NATURAL alignment. The caller guarantees the address. -typedef uint16_t proto_al_u16_t PROTO_ALIAS; -typedef uint32_t proto_al_u32_t PROTO_ALIAS; -typedef uint64_t proto_al_u64_t PROTO_ALIAS; - -/// @brief The mover's step, as a type. One rung; anything wider is this repeated. -#if PROTO_RAW_WORD >= 8 -typedef uint64_t proto_mv_word; -#elif PROTO_RAW_WORD >= 4 -typedef uint32_t proto_mv_word; -#else -typedef uint16_t proto_mv_word; -#endif - -/** - * @brief The raw access module: one scalar width read or written at a pointer, in machine order. - * - * @var RawNs::u16 - * Read the 2 bytes at @c p as a uint16_t in machine order, whatever the alignment. - * - * @var RawNs::u32 - * Read the 4 bytes at @c p as a uint32_t in machine order, whatever the alignment. - * - * @var RawNs::u64 - * Read the 8 bytes at @c p as a uint64_t in machine order, whatever the alignment. - * - * @var RawNs::load - * Read @c n bytes (1, 2, 4 or 8) at @c p as one integer in machine order. @c n outside {1,2,4,8} - * reads nothing and yields 0. - * - * For a caller whose width is a constant it does not spell out - the lane carrier in swar.h is set - * by PROTO_SWAR_BITS, so its load follows that knob rather than naming a width. The octet case needs - * no attribute: every address is aligned for one byte and a character type may alias anything, so it - * is the plain dereference the wider rungs are masked down to. - * - * **Costs a whole byte-assembly sequence on a machine with no unaligned load.** ::PROTO_RAW states - * that the address carries no alignment guarantee, which is right for a wire offset and wrong for a - * caller that already walked its pointer to a boundary - the compiler must then synthesize each word - * from bytes and shifts. A caller that has established alignment says so with ::RawNs::al_load. - * - * @var RawNs::put_u16 - * Write @c v as 2 bytes at @c p in machine order, whatever the alignment. - * - * @var RawNs::put_u32 - * Write @c v as 4 bytes at @c p in machine order, whatever the alignment. - * - * @var RawNs::put_u64 - * Write @c v as 8 bytes at @c p in machine order, whatever the alignment. - * - * @var RawNs::al_load - * ::RawNs::load for an address the caller has already aligned to @c n. - * - * The contract is the whole point: @c p MUST be @c n-byte aligned. In exchange the compiler emits - * the machine's own load instead of assembling the value from bytes, which on a die with no general - * unaligned load is the difference between roughly ten instructions per word and one. Passing an - * unaligned address here is undefined and on a strict-alignment part it faults. - * - * PROTOCORE_HW_UNALIGNED_LOAD says whether a die needs any of this. Where it is 1 the raw load is - * already a single instruction and a caller has no reason to walk to a boundary first. - * - * @var RawNs::al_put_u16 - * The store side of ::RawNs::al_load at 2 bytes. @c p must carry that alignment. - * - * @var RawNs::al_put_u32 - * The store side of ::RawNs::al_load at 4 bytes. @c p must carry that alignment. - * - * @var RawNs::al_put_u64 - * The store side of ::RawNs::al_load at 8 bytes. @c p must carry that alignment. - * - * @var RawNs::mv_load - * One aligned load at the mover's own rung, ::PROTO_RAW_WORD bytes at @c p. - * - * @var RawNs::mv_put - * The store side of ::RawNs::mv_load. - * - * @var RawNs::read - * Move @c sz bytes at @c p into @c dst, at any alignment - the arbitrary-width form. - * - * For a payload no scalar covers and no limb layout fits: a header struct overlaid on a byte stream, - * or a span landing in a ring. Declare an overlaid struct ::PROTO_RAW so its members are reachable - * once it lands, then move the whole thing here rather than member by member off a moving offset. - * - * It enters the ladder at ::PROTO_RAW_WORD and shifts down a rung at a time to the odd tail - the - * same widths the rest of this header is built from. Only the first loop runs more than once: each - * one below it starts with fewer bytes left than the loop above needed, so it iterates at most once. - * A rung wider than the bus is compiled out rather than left for the compiler to decompose. The - * source and destination must not overlap. - * - * No storage member: every rung works on the caller's pointers, the widths are compile-time, and the - * ladder carries its position in a local. - */ -typedef struct -{ - uint16_t (*u16)(const void *p); - uint32_t (*u32)(const void *p); - uint64_t (*u64)(const void *p); - uint64_t (*load)(const void *p, size_t n); - void (*put_u16)(void *p, uint16_t v); - void (*put_u32)(void *p, uint32_t v); - void (*put_u64)(void *p, uint64_t v); - uint64_t (*al_load)(const void *p, size_t n); - void (*al_put_u16)(void *p, uint16_t v); - void (*al_put_u32)(void *p, uint32_t v); - void (*al_put_u64)(void *p, uint64_t v); - proto_mv_word (*mv_load)(const unsigned char *p); - void (*mv_put)(unsigned char *p, proto_mv_word v); - void (*read)(void *dst, const void *p, size_t sz); -} RawNs; - -/** @brief Read the 2 bytes at @p p as a uint16_t in machine order, whatever the alignment. */ -PROTOCORE_INLINE uint16_t proto_raw_u16(const void *p) -{ - return *(const proto_raw_u16_t *)p; -} - -/** @brief Read the 4 bytes at @p p as a uint32_t in machine order, whatever the alignment. */ -PROTOCORE_INLINE uint32_t proto_raw_u32(const void *p) -{ - return *(const proto_raw_u32_t *)p; -} - -/** @brief Read the 8 bytes at @p p as a uint64_t in machine order, whatever the alignment. */ -PROTOCORE_INLINE uint64_t proto_raw_u64(const void *p) -{ - return *(const proto_raw_u64_t *)p; -} - -/** @brief Read @p n bytes (1, 2, 4 or 8) at @p p as one integer in machine order. See ::RawNs::load. */ -PROTOCORE_INLINE uint64_t proto_raw_load(const void *p, size_t n) -{ - switch (n) - { - case 1: - return *(const unsigned char *)p; - case 2: - return proto_raw_u16(p); - case 4: - return proto_raw_u32(p); - case 8: - return proto_raw_u64(p); - default: - return 0; - } -} - -/** @brief Write @p v as 2 bytes at @p p in machine order, whatever the alignment. */ -PROTOCORE_INLINE void proto_raw_put_u16(void *p, uint16_t v) -{ - *(proto_raw_u16_t *)p = v; -} - -/** @brief Write @p v as 4 bytes at @p p in machine order, whatever the alignment. */ -PROTOCORE_INLINE void proto_raw_put_u32(void *p, uint32_t v) -{ - *(proto_raw_u32_t *)p = v; -} - -/** @brief Write @p v as 8 bytes at @p p in machine order, whatever the alignment. */ -PROTOCORE_INLINE void proto_raw_put_u64(void *p, uint64_t v) -{ - *(proto_raw_u64_t *)p = v; -} - -/** @brief ::proto_raw_load for an address the caller has already aligned to @p n. See ::RawNs::al_load. */ -PROTOCORE_INLINE uint64_t proto_al_load(const void *p, size_t n) -{ - switch (n) - { - case 1: - return *(const unsigned char *)p; - case 2: - return *(const proto_al_u16_t *)p; - case 4: - return *(const proto_al_u32_t *)p; - case 8: - return *(const proto_al_u64_t *)p; - default: - return 0; - } -} - -/// @brief The store side of ::proto_al_load. @p p must be 2-byte aligned; the caller guarantees it. -PROTOCORE_INLINE void proto_al_put_u16(void *p, uint16_t v) -{ - *(proto_al_u16_t *)p = v; -} - -/// @brief The store side of ::proto_al_load. @p p must be 4-byte aligned; the caller guarantees it. -PROTOCORE_INLINE void proto_al_put_u32(void *p, uint32_t v) -{ - *(proto_al_u32_t *)p = v; -} - -/// @brief The store side of ::proto_al_load. @p p must be 8-byte aligned; the caller guarantees it. -PROTOCORE_INLINE void proto_al_put_u64(void *p, uint64_t v) -{ - *(proto_al_u64_t *)p = v; -} - -/// @brief Aligned load at the mover's own rung. -PROTOCORE_INLINE proto_mv_word proto_mv_load(const unsigned char *p) -{ - return (proto_mv_word)proto_al_load(p, PROTO_RAW_WORD); -} - -/// @brief Aligned store at the mover's own rung. -PROTOCORE_INLINE void proto_mv_put(unsigned char *p, proto_mv_word v) -{ -#if PROTO_RAW_WORD >= 8 - proto_al_put_u64(p, (uint64_t)v); -#elif PROTO_RAW_WORD >= 4 - proto_al_put_u32(p, (uint32_t)v); -#else - proto_al_put_u16(p, (uint16_t)v); -#endif -} - -// The span move, in rawmemcpy.c. Named here because the table below has to name it. The rungs above -// are one instruction each and fold at the call site; this one has loops and is compiled once. -void proto_raw_read(void *dst, const void *p, size_t sz); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away, a rung defined above inlines, and the table is left referenced by nothing for the - * linker to drop. - * - * `unused` because a header this wide is included by files that take none of it. - */ -// Designated, so a member's position in the struct does not decide what it binds to. -static const RawNs raw __attribute__((unused)) = {.u16 = proto_raw_u16, - .u32 = proto_raw_u32, - .u64 = proto_raw_u64, - .load = proto_raw_load, - .put_u16 = proto_raw_put_u16, - .put_u32 = proto_raw_put_u32, - .put_u64 = proto_raw_put_u64, - .al_load = proto_al_load, - .al_put_u16 = proto_al_put_u16, - .al_put_u32 = proto_al_put_u32, - .al_put_u64 = proto_al_put_u64, - .mv_load = proto_mv_load, - .mv_put = proto_mv_put, - .read = proto_raw_read}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_RAWMEMCPY_H diff --git a/src/mmgr/ring/CMakeLists.txt b/src/mmgr/ring/CMakeLists.txt deleted file mode 100644 index dc2eb4327..000000000 --- a/src/mmgr/ring/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/ring - HEADER_ONLY - DEPS - mmgr/rawmemcpy - mmgr/span -) diff --git a/src/mmgr/ring/ring.h b/src/mmgr/ring/ring.h deleted file mode 100644 index ea831ff0d..000000000 --- a/src/mmgr/ring/ring.h +++ /dev/null @@ -1,356 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later -#ifndef PROTOCORE_RING_H -#define PROTOCORE_RING_H - -#include "mmgr/rawmemcpy/rawmemcpy.h" // proto_raw_read: the producer span move -#include "mmgr/span/span.h" // protocore_cspan: the region a held slot keeps out -#include // _Atomic, atomic_load_explicit, atomic_store_explicit, memory_order_* - -/** - * @file ring.h - * @brief Shared single-producer / single-consumer byte-ring primitive. - * - * The one implementation of the receive-ring drain math, used by BOTH transports: - * the server (protocore_conn_* in tcp.h, over conn_pool slots) and the outbound - * client (protocore_client_* over its pool). The wrap and ordering invariants are stated - * here once, so a consumer in any layer drains identically. - * - * Ownership rule: exactly one producer advances `head`, exactly one consumer - * advances `tail`; both indices are `_Atomic` so a producer's buffer writes are visible - * before the consumer observes the advanced index (acquire/release), correct across - * the tcpip_thread <-> worker/caller boundary on either core. No locks, no RMW. - */ - -// --------------------------------------------------------------------------- -// Cross-thread field access -// --------------------------------------------------------------------------- -// -// A field shared across a producer/consumer thread boundary (a ring head/tail, a slot -// state) is declared `_Atomic` by its owner and reached only through these two, so the -// ordering is stated at every access rather than left to the default. Every read is an -// acquire load and every write a release store, which is what makes a producer's buffer -// writes visible before the consumer observes the advanced index. Single-producer / -// single-consumer, so only ordering is needed and never read-modify-write atomicity. -// -// Naming the pair here rather than per width is what lets a slot-state enum and a -// size_t index carry the identical rule; `atomic_load_explicit` is generic over both. -// -// `_Atomic` is native on every part in the target list: the emitted code is the plain -// load or store plus whatever that ISA needs to order it, and never a lock or a call into -// __atomic. Checked in the generated assembly - x86 emits nothing extra (its store order -// already gives acquire/release), Xtensa brackets the access with `memw`, RISC-V with -// `fence`, Cortex-M4 with `dmb`. So the cost is a counted instruction or two, not a wait, -// and bounded latency is preserved. -// -// Under ThreadSanitizer these expand to instrumented calls that branch on the -// memory-order argument. That order is a compile-time constant here, so only one arm is -// ever reachable in a correct SPSC program (see test_spsc_ring_no_race) and the lines - -/** @brief Acquire-load the atomic at @p p. */ -#define PROTO_ATOMIC_LOAD(p) atomic_load_explicit((p), memory_order_acquire) - -/** @brief Release-store @p v into the atomic at @p p. */ -#define PROTO_ATOMIC_STORE(p, v) atomic_store_explicit((p), (v), memory_order_release) - -// --------------------------------------------------------------------------- -// SPSC ring drain math (consumer side) -// --------------------------------------------------------------------------- -// The caller owns the storage (`buf` of `cap` bytes) and the indices; these advance -// `tail` only (the producer owns `head`). A read reads `tail` once and publishes it -// once at the end (one release store), not per byte. - -/** - * @brief A ring capacity is a power of two, so an index wraps with an AND. - * - * Every owner asserts this over its own capacity. Not every part in the target list has a hardware - * divide, and where it is missing the compiler emits a call into a software routine, which a - * per-byte wrap would take on every byte. - */ -#define PROTOCORE_RING_POW2(cap) (((cap) & ((cap) - 1)) == 0) - -/** @brief Wrap @p i into a ring of @p cap bytes. */ -#define PROTOCORE_RING_WRAP(i, cap) ((i) & ((cap) - 1)) - -/** @brief Bytes available to read (head - tail, wrapped). */ -static inline size_t protocore_ring_available(const _Atomic size_t *head, const _Atomic size_t *tail, size_t cap) -{ - return PROTOCORE_RING_WRAP(PROTO_ATOMIC_LOAD(head) - PROTO_ATOMIC_LOAD(tail), cap); -} - -/** @brief Pop one byte into @p out; false if empty. */ -static inline proto_bool protocore_ring_read_byte(const uint8_t *buf, size_t cap, const _Atomic size_t *head, - _Atomic size_t *tail, uint8_t *out) -{ - size_t t = PROTO_ATOMIC_LOAD(tail); - if (t == PROTO_ATOMIC_LOAD(head)) - { - return PROTO_FALSE; - } - *out = buf[t]; - PROTO_ATOMIC_STORE(tail, PROTOCORE_RING_WRAP(t + 1, cap)); - return PROTO_TRUE; -} - -/** @brief Pop up to @p maxn bytes into @p dst; returns the count read. */ -static inline size_t protocore_ring_read(const uint8_t *buf, size_t cap, const _Atomic size_t *head, - _Atomic size_t *tail, uint8_t *dst, size_t maxn) -{ - size_t h = PROTO_ATOMIC_LOAD(head); - size_t t = PROTO_ATOMIC_LOAD(tail); - size_t n = 0; - while (n < maxn && t != h) - { - dst[n] = buf[t]; - n++; - t = PROTOCORE_RING_WRAP(t + 1, cap); - } - PROTO_ATOMIC_STORE(tail, t); - return n; -} - -/** @brief Copy @p n bytes at @p off ahead of the tail into @p dst WITHOUT consuming. */ -static inline void protocore_ring_peek(const uint8_t *buf, size_t cap, const _Atomic size_t *tail, size_t off, - uint8_t *dst, size_t n) -{ - size_t idx = PROTOCORE_RING_WRAP(PROTO_ATOMIC_LOAD(tail) + off, cap); - for (size_t i = 0; i < n; i++) - { - dst[i] = buf[idx]; - idx = PROTOCORE_RING_WRAP(idx + 1, cap); - } -} - -/** @brief Drop @p n bytes from the tail (advance past already-peeked data). */ -static inline void protocore_ring_consume(_Atomic size_t *tail, size_t cap, size_t n) -{ - PROTO_ATOMIC_STORE(tail, PROTOCORE_RING_WRAP(PROTO_ATOMIC_LOAD(tail) + n, cap)); -} - -// --------------------------------------------------------------------------- -// SPSC ring fill (producer side) -// --------------------------------------------------------------------------- -// The producer owns `head`. The recv callback checks protocore_ring_free() against the -// whole inbound segment (refuse it for lossless backpressure if it will not fit), -// then copies each source span with protocore_ring_write_span() advancing a LOCAL head, -// and publishes that head once at the end (one release store, not per byte). - -/** @brief Free space to write: (cap-1) - used, one slot reserved to tell full from empty. */ -static inline size_t protocore_ring_free(const _Atomic size_t *head, const _Atomic size_t *tail, size_t cap) -{ - size_t used = PROTOCORE_RING_WRAP(PROTO_ATOMIC_LOAD(head) - PROTO_ATOMIC_LOAD(tail), cap); - return (cap - 1) - used; -} - -/** - * @brief Copy @p len bytes from @p src into @p buf at local index @p head, wrap-aware - * (at most two spans across the wrap), returning the advanced local head. - * - * The head is local and unpublished for the whole call: the caller checks protocore_ring_free() - * first and publishes the returned head once, so the consumer never sees a partially - * filled span. - * - * A span here is a whole inbound segment, up to an MTU, and lands wherever the ring's fill - * left off, so the move goes through proto_raw_read: it steps the machine word rather than - * the byte, and it is the one owner of an access whose address carries no alignment. - */ -static inline size_t protocore_ring_write_span(uint8_t *buf, size_t cap, size_t head, const uint8_t *src, size_t len) -{ - while (len > 0) - { - size_t chunk = cap - head; // bytes until the buffer end (wrap point) - if (chunk > len) - { - chunk = len; - } - proto_raw_read(&buf[head], src, chunk); - head = PROTOCORE_RING_WRAP(head + chunk, cap); - src += chunk; - len -= chunk; - } - return head; -} - -// --------------------------------------------------------------------------- -// Segment ring: one message per segment -// --------------------------------------------------------------------------- -// The ring is `nsegs` segments of `seg_size` bytes and one entry fills one segment, so an -// entry is contiguous and a consumer reads it where it was written. The segments from -// `rel` up to `claim` are filled and not yet released. The producer advances `claim` and -// the consumer advances `rel`, one side each, the same rule as the byte ring above. -// Segments release in order. `nsegs` is a power of two, so the index is a mask. - -/** @brief Segments filled and not yet released. */ -static inline size_t protocore_seg_inflight(const _Atomic size_t *claim, const _Atomic size_t *rel) -{ - return PROTO_ATOMIC_LOAD(claim) - PROTO_ATOMIC_LOAD(rel); -} - -/** - * @brief Index of the segment the producer fills next. - * - * Publishing is separate, so a half-filled segment is never visible to the consumer. - * @return false when every segment is in flight. - */ -static inline proto_bool protocore_seg_next(const _Atomic size_t *claim, const _Atomic size_t *rel, size_t nsegs, - size_t *idx) -{ - size_t c = PROTO_ATOMIC_LOAD(claim); - if ((c - PROTO_ATOMIC_LOAD(rel)) >= nsegs) - { - return PROTO_FALSE; - } - *idx = c & (nsegs - 1); - return PROTO_TRUE; -} - -/** @brief Make the filled segment visible to the consumer. */ -static inline void protocore_seg_publish(_Atomic size_t *claim) -{ - PROTO_ATOMIC_STORE(claim, PROTO_ATOMIC_LOAD(claim) + 1); -} - -/** - * @brief Index of the segment the consumer sends next. - * @return false when none is in flight. - */ -static inline proto_bool protocore_seg_front(const _Atomic size_t *claim, const _Atomic size_t *rel, size_t nsegs, - size_t *idx) -{ - size_t r = PROTO_ATOMIC_LOAD(rel); - if (PROTO_ATOMIC_LOAD(claim) == r) - { - return PROTO_FALSE; - } - *idx = r & (nsegs - 1); - return PROTO_TRUE; -} - -/** @brief Free the front segment: the wire has taken those bytes. */ -static inline void protocore_seg_release(_Atomic size_t *rel) -{ - PROTO_ATOMIC_STORE(rel, PROTO_ATOMIC_LOAD(rel) + 1); -} - -/** @brief The contiguous span of segment @p idx, @p seg_size bytes. */ -static inline uint8_t *protocore_seg_at(uint8_t *buf, size_t seg_size, size_t idx) -{ - return &buf[idx * seg_size]; -} - -// --------------------------------------------------------------------------- -// Slot view: a mask per meaning, and the region a hold keeps out -// --------------------------------------------------------------------------- -// The views above index a slot the caller already chose; this one answers which slot. A -// slot count that fits a word makes that a ctz rather than a scan, and a hold one fetch_or -// whose return says whether it was won, so a loser moves on instead of retrying. -// -// A held slot carries the region the wire is still reading. A forward hands the egress -// that pointer and walks its length rather than copying, so the slot cannot be reused -// until the transmit completes and drops it. - -/** @brief Slots a mask can address. A wider pool falls back to the head/tail view. */ -#define PROTOCORE_RING_SLOTS_MAX 32 - -// A shift past the word is undefined, and every index below comes from a ctz that cannot produce -// one - so the bound is here rather than at each call site, the way the pool's state setter carries -// its own. An out-of-range slot names nothing, so it reads as held and is never handed out. -static inline uint32_t protocore_slot_bit(size_t idx) -{ - if (idx >= PROTOCORE_RING_SLOTS_MAX) - { - return 0u; - } - return 1u << idx; -} - -/** @brief Every slot below @p count, as a mask. */ -static inline uint32_t protocore_slot_all(size_t count) -{ - if (count >= PROTOCORE_RING_SLOTS_MAX) - { - return 0xFFFFFFFFu; - } - return (1u << count) - 1u; -} - -/** - * @brief Take slot @p idx if no one holds it. - * @return true when this caller took it; false when another already had it. - */ -static inline proto_bool protocore_slot_take(_Atomic uint32_t *held, size_t idx) -{ - const uint32_t bit = protocore_slot_bit(idx); - if (bit == 0u) - { - return PROTO_FALSE; - } - uint32_t prev = atomic_fetch_or_explicit(held, bit, memory_order_acquire); - return (prev & bit) == 0u; -} - -/** - * @brief Take slot @p idx and record the @p len bytes at @p ptr that the wire will read. - * - * The recorded region is the keepout: it stays valid until protocore_slot_drop(), so an egress - * handed @p ptr walks it in place. - * @return true when this caller took it; false when another already had it. - */ -static inline proto_bool protocore_slot_hold(_Atomic uint32_t *held, protocore_cspan *keepout, size_t idx, - const uint8_t *ptr, size_t len) -{ - if (!protocore_slot_take(held, idx)) - { - return PROTO_FALSE; - } - keepout[idx].buf = ptr; - keepout[idx].len = len; - keepout[idx].pos = 0; - keepout[idx].err = PROTO_FALSE; - return PROTO_TRUE; -} - -/** @brief The region slot @p idx is keeping out, for the egress to walk. */ -static inline const protocore_cspan *protocore_slot_keepout(const protocore_cspan *keepout, size_t idx) -{ - return &keepout[idx]; -} - -/** @brief Give slot @p idx back: the wire has taken its bytes. */ -static inline void protocore_slot_drop(_Atomic uint32_t *held, size_t idx) -{ - atomic_fetch_and_explicit(held, ~protocore_slot_bit(idx), memory_order_release); -} - -/** @brief Mark slot @p idx in @p mask, published after the slot is written. */ -static inline void protocore_slot_mark(_Atomic uint32_t *mask, size_t idx) -{ - atomic_fetch_or_explicit(mask, protocore_slot_bit(idx), memory_order_release); -} - -/** @brief Clear slot @p idx in @p mask, before the slot is written. */ -static inline void protocore_slot_clear(_Atomic uint32_t *mask, size_t idx) -{ - atomic_fetch_and_explicit(mask, ~protocore_slot_bit(idx), memory_order_release); -} - -/** @brief The slots @p mask names, minus the held ones, within @p count. */ -static inline uint32_t protocore_slot_ready(const _Atomic uint32_t *mask, const _Atomic uint32_t *held, size_t count) -{ - return PROTO_ATOMIC_LOAD(mask) & ~PROTO_ATOMIC_LOAD(held) & protocore_slot_all(count); -} - -/** - * @brief Lowest slot set in @p m. - * @return its index, or -1 when @p m is empty. - */ -static inline int32_t protocore_slot_next(uint32_t m) -{ - if (m == 0u) - { - return -1; - } - return (int32_t)__builtin_ctz(m); -} - -#endif // PROTOCORE_RING_H diff --git a/src/mmgr/secure/CMakeLists.txt b/src/mmgr/secure/CMakeLists.txt deleted file mode 100644 index 36122cb82..000000000 --- a/src/mmgr/secure/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/secure - SOURCES secure.c - DEPS - mmgr/protomem - mmgr/span - PRIVATE_DEPS - mmgr/arena -) diff --git a/src/mmgr/secure/secure.c b/src/mmgr/secure/secure.c deleted file mode 100644 index 4d270a880..000000000 --- a/src/mmgr/secure/secure.c +++ /dev/null @@ -1,238 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file secure.c - * @brief Secure pool accessor - implementation. - * - * An access layer, not a second allocator: the pool mechanism is ::protocore_arena and there is exactly one - * of it. This module owns a second set of instances over its own compile-time-sized storage, and - * adds the one control the plaintext side does not have - reclaiming wipes. - */ - -#include "mmgr/secure/secure.h" -#include "config/platform/platform.h" // protocore_platform_context_id() -#include "mmgr/arena/arena.h" -#include - -/** @brief The pool's compile-time backing bytes: one arena's worth per slot, in one block. */ -struct SecureStorage -{ - _Alignas(32) uint8_t mem[PROTOCORE_SEC_POOL_SLOTS][PROTOCORE_SECURE_ARENA_SIZE]; -}; - -/** - * @brief The pool's state: the per-slot arenas, the block they hand out of, and the debug owner - * table. - * - * @var SecureInternal::store the backing block, NULL until the first borrow binds it - * @var SecureInternal::pool one arena per slot, indexed by the calling worker's slot - * @var SecureInternal::owner the execution context that first touched each slot, debug builds only - */ -struct SecureInternal -{ - struct SecureStorage *store; - protocore_arena pool[PROTOCORE_SEC_POOL_SLOTS]; -#if PROTOCORE_DEBUG_CHECKS - uintptr_t owner[PROTOCORE_SEC_POOL_SLOTS]; -#endif -}; - -// Backing storage in its OWN linker symbol, named only from bind() below and therefore only from the -// allocation path. A firmware that never borrows secure storage has the allocator garbage-collected and -// this storage with it. protocore_secure_reset() must NOT bind, for the same reason protocore_plaintext_reset() must -// not: --gc-sections is per-symbol and one always-live reference would anchor the whole block. -static struct SecureStorage s_store; - -// Every mutable this module has, in one object. Zero at boot: bind() fills in the block pointer and -// the slot's arena on that slot's first borrow, so the state holds a reference to the block only -// once something has borrowed from it. -struct SecureInternal protocore_secure_state; - -// The state, under one name. -static inline struct SecureInternal *secure_ctx(void) -{ - return &protocore_secure_state; -} - -// Byte offset of @p p within the whole secure block. The slot count and slot size are compile-time, -// so the pool is ONE region of known extent: no loop, no per-slot compare, just an unsigned -// subtract. A pointer below the base wraps to a huge value and fails the same bound as one past the -// end, so NULL needs no special case and an overrun cannot read as still-inside. -// -// No power-of-two requirement, matching the plaintext pool: the per-die profiles size these to what -// each part can afford (s3 12288, c6 10240), and subtract-and-compare does not care. -static inline uintptr_t secure_offset(const struct SecureInternal *ctx, const void *p) -{ - return (uintptr_t)p - (uintptr_t)ctx->store; -} - -// The clamp guarantees a legal index, and only that: a caller that is not a server worker lands on -// the ghost instead of worker 0. Two such callers still share the ghost, which the tripwire catches. -static inline int cur_worker(void) -{ - int w = protocore_worker_self(); - return (w >= 0 && w < PROTOCORE_SEC_POOL_SLOTS) ? w : PROTOCORE_GHOST_WORKER_SLOT; -} - -// Debug tripwire: one execution context per slot, as on the plaintext side. -static inline void assert_single_owner(struct SecureInternal *ctx, int w) -{ -#if PROTOCORE_DEBUG_CHECKS - // Off by default; see PROTOCORE_DEBUG_CHECKS. The identity comes from test/core_setup/ - the core does - // not name an RTOS. - const uintptr_t cur = protocore_platform_context_id(); - if (ctx->owner[w] == 0) - { - ctx->owner[w] = cur; - } - else - { - assert(ctx->owner[w] == cur && "secure pool borrowed from a foreign task"); - } -#else - (void)ctx; - (void)w; -#endif -} - -// Bind slot @p w to its storage on first use. The ONLY reference to s_store. -static inline protocore_arena *bind(struct SecureInternal *ctx, int w) -{ - protocore_arena *a = &ctx->pool[w]; - if (a->base == NULL) - { - ctx->store = &s_store; - protocore_arena_init(a, ctx->store->mem[w], PROTOCORE_SECURE_ARENA_SIZE); - } - return a; -} - -// The slot WITHOUT binding it, for observers and the reset. An unbound slot has never allocated, so -// it holds nothing to wipe. -static inline protocore_arena *peek(struct SecureInternal *ctx, int w) -{ - protocore_arena *a = &ctx->pool[w]; - return (a->base != NULL) ? a : NULL; -} - -// Wipe the live extent down to @p mark, then move the position. -// -// The order is the whole point. The scratch end grows DOWN, so the live bytes are -// [scratch_top, mark) and reclaiming means raising scratch_top back to mark. Wiping first means the -// region is already zero at the instant it becomes available, so there is no window - not to a -// preempting handler, not to the very next borrow - in which memory still holding the previous -// tenant's key material can be handed out. Reclaiming first and wiping after would leave exactly -// that window. -static inline void wipe_down_to(protocore_arena *a, size_t mark) -{ - const size_t top = protocore_arena_scratch_mark(a); // current position (an offset from the base) - if (mark > top && mark <= a->size) - { - protocore_secure_wipe(a->base + top, mark - top); // volatile: the compiler may not elide it - } - protocore_arena_scratch_release(a, mark); -} - -void *protocore_secure_alloc(size_t n, size_t align) -{ - struct SecureInternal *ctx = secure_ctx(); - int w = cur_worker(); - assert_single_owner(ctx, w); - assert((align & (align - 1)) == 0 && "secure alignment must be a power of two"); - return protocore_arena_scratch_alloc_aligned(bind(ctx, w), n, align); -} - -protocore_span protocore_secure_span(size_t n, size_t align) -{ - return protocore_span_from((uint8_t *)protocore_secure_alloc(n, align), n); -} - -protocore_span protocore_secure_persist_span(size_t n) -{ - struct SecureInternal *ctx = secure_ctx(); - int w = cur_worker(); - assert_single_owner(ctx, w); - // The persistent end grows up from the base and the scratch end bumps down from the top, so a - // mark taken on the scratch end never reaches this and no release reclaims it. The arena hands - // these bytes back zeroed. - return protocore_span_from((uint8_t *)protocore_arena_persist_alloc(bind(ctx, w), n), n); -} - -size_t protocore_secure_mark(void) -{ - struct SecureInternal *ctx = secure_ctx(); - int w = cur_worker(); - assert_single_owner(ctx, w); - return protocore_arena_scratch_mark(bind(ctx, w)); -} - -void protocore_secure_release(size_t mark) -{ - struct SecureInternal *ctx = secure_ctx(); - int w = cur_worker(); - assert_single_owner(ctx, w); - wipe_down_to(bind(ctx, w), mark); -} - -void protocore_secure_reset(void) -{ - struct SecureInternal *ctx = secure_ctx(); - int w = cur_worker(); - assert_single_owner(ctx, w); - protocore_arena *a = peek(ctx, w); // must not bind: would anchor the storage into builds that never borrow - if (a != NULL) - { - wipe_down_to(a, a->size); // the empty position: wipes everything live - } -} - -size_t protocore_secure_used(void) -{ - const protocore_arena *a = peek(secure_ctx(), cur_worker()); - return (a != NULL) ? protocore_arena_scratch_used(a) : 0; -} - -size_t protocore_secure_high_water(void) -{ - struct SecureInternal *ctx = secure_ctx(); - size_t peak = 0; - for (int w = 0; w < PROTOCORE_SEC_POOL_SLOTS; w++) - { - const protocore_arena *a = peek(ctx, w); - if (a != NULL && a->scratch_hw > peak) - { - peak = a->scratch_hw; - } - } - return peak; -} - -size_t protocore_secure_capacity(void) -{ - return PROTOCORE_SECURE_ARENA_SIZE; -} - -proto_bool protocore_secure_owns(const void *p) -{ - const struct SecureInternal *ctx = secure_ctx(); - // An unbound block has handed out nothing, so no pointer is inside it and the subtract has no - // base to run against. - return ctx->store != NULL && secure_offset(ctx, p) < (uintptr_t)sizeof(ctx->store->mem); -} - -int protocore_secure_slot_of(const void *p) -{ - const struct SecureInternal *ctx = secure_ctx(); - if (ctx->store == NULL) - { - return -1; - } - const uintptr_t off = secure_offset(ctx, p); - if (off >= (uintptr_t)sizeof(ctx->store->mem)) - { - return -1; - } - // A divide by a compile-time constant, which the compiler emits as a multiply-and-shift. - return (int)(off / PROTOCORE_SECURE_ARENA_SIZE); -} diff --git a/src/mmgr/secure/secure.h b/src/mmgr/secure/secure.h deleted file mode 100644 index 0d2089f13..000000000 --- a/src/mmgr/secure/secure.h +++ /dev/null @@ -1,255 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file secure.h - * @brief Secure pool accessor - borrows that hold key material. - * - * The same pool mechanism as the plaintext side (::protocore_arena, mmgr/arena), instantiated a second - * time. The resource and its mechanics are identical - one instance per worker slot, compile-time - * sized, double-ended, fail-closed, high-water reported. What differs is the access and control - * layer, and the difference is security: - * - * - **Release wipes.** protocore_secure_release() and protocore_secure_reset() zero the region being reclaimed - * before it becomes available again. On the plaintext side reclaiming is just an offset move; a - * secret must not outlive its borrow, so here the wipe IS the release. That makes the rule - * structural instead of a discipline every caller has to remember on every return path - the - * form that had already been missed on two of the SSH key-exchange error paths. - * - * - **Disjoint region.** The two pools occupy different addresses, so protocore_secure_owns() and - * protocore_plaintext_owns() are mutually exclusive by construction. A secure borrow can never be - * accepted where a plaintext one is expected, or the reverse, with no tagging and no metadata. - * - * **What belongs here.** Anything whose bytes are key material: shared secrets, private scalars, - * derived keys, and the working state of an operation over them. Public wire values (a peer's - * public point, a ciphertext about to be transmitted, a staging buffer for an outbound frame) belong - * in the plaintext pool - putting them here only shrinks the room left for real secrets. - * - * **Lifetime is not the axis.** Both pools carry long-lived and ephemeral allocations; the pool a - * borrow comes from is decided by whether its contents are secret, nothing else. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_SECURE_H -#define PROTOCORE_SECURE_H - -#include "mmgr/protomem/protomem.h" -#include "mmgr/span/span.h" - -#include "protocore_config.h" - -PROTOCORE_BEGIN_DECLS - -/** - * @brief Slots in the secure pool. - * - * Sized off the ghost rather than the worker count so the invariant is the definition: the pool - * must reach the highest slot any caller can resolve to, and that is the ghost. - * - * The plaintext pool states its own count (::PROTOCORE_REG_POOL_SLOTS). They are equal today and neither - * is derived from the other - one pool growing a slot is not a reason for the other to. - */ -#define PROTOCORE_SEC_POOL_SLOTS (PROTOCORE_GHOST_WORKER_SLOT + 1) - -/** - * @brief The pool's own state: the per-slot arenas and the block they hand out of. Defined in - * secure.c. - * - * Incomplete here, so nothing outside secure.c can name a field, size the block or reach a slot - * around the accessors. The calls below take no handle - each resolves the calling worker's slot - * itself - so this is named only to give the state one owner. - */ -struct SecureInternal; - -/** - * @brief The secure pool: the same mechanism as @ref plain, with reclaiming that wipes. - * - * @var SecureNs::alloc borrow @c n bytes aligned to @c align, or NULL if it does not fit - * @var SecureNs::span the same borrow as a span, so the length travels with the pointer - * @var SecureNs::persist_span borrow from the end no mark walks, zeroed, for the life of the program - * @var SecureNs::reset wipe and empty the calling worker's arena - * @var SecureNs::mark capture the arena offset, to release back to - * @var SecureNs::release wipe everything borrowed since a mark, then reclaim it, LIFO - * @var SecureNs::used bytes currently handed out - * @var SecureNs::high_water the largest @c used any slot has reached, for sizing the arena - * @var SecureNs::capacity one arena's total extent - * @var SecureNs::owns whether a pointer lies inside the pool - * @var SecureNs::slot_of which slot holds a pointer, or -1 - * @var SecureNs::internal the per-slot arenas and their backing block, described only in secure.c - * - * @ref SecureNs::owns and protocore_plaintext_owns() are mutually exclusive: the two pools are disjoint - * regions, so a secret can never be handed back where plaintext is expected, or the reverse. - * - * The arenas and their backing bytes belong to secure.c, and a caller reaches its own by calling - - * the slot is resolved from the worker, never passed in. @ref SecureNs::internal names that state - * without describing it. - */ -typedef struct -{ - void *(*alloc)(size_t n, size_t align); - protocore_span (*span)(size_t n, size_t align); - protocore_span (*persist_span)(size_t n); - void (*reset)(void); - size_t (*mark)(void); - void (*release)(size_t mark); - size_t (*used)(void); - size_t (*high_water)(void); - size_t (*capacity)(void); - proto_bool (*owns)(const void *p); - int (*slot_of)(const void *p); - - struct SecureInternal *internal; -} SecureNs; - -/** - * @brief The pool's state, the one object every call in secure.c reaches its slot through. - * - * Zero at boot: the arenas and the block they hand out of bind on the first borrow, so a build that - * never borrows a secret carries neither. - */ -extern struct SecureInternal protocore_secure_state; - -/** - * @brief Securely zero @p len bytes at @p ptr with a volatile store the compiler cannot elide. - * - * The canonical wipe. Use this, never mem.zero(), for any buffer that held key material: a plain - * store whose result is never observed (the buffer dies at return) is a dead store and may be - * optimized away, leaving the bytes in memory. The volatile write forces it even when the memory is - * never read again. - * - * It lives here because wiping is a memory-manager operation, not a cryptographic one. It is the - * secure pool's own reclaim primitive, and it is equally what any owner needs for storage that was - * never in a pool at all - session key material, a caller's own buffer. Crypto is a consumer of it, - * not its home. - * - * @param ptr Buffer to wipe. - * @param len Number of bytes to zero. - */ -static inline void protocore_secure_wipe(void *ptr, size_t len) -{ - // Machine-width stores, with byte head/tail only for unaligned edges. Both edges are normally - // empty - pool borrows are aligned and their lengths rounded up - so this is the word loop. - // volatile is per-access. A volatile word store is exactly as un-elidable as a volatile byte - // store; the guarantee is unchanged and the store count drops by the width. - volatile uint8_t *b = (volatile uint8_t *)ptr; - while (len != 0 && (((uintptr_t)b & (sizeof(uintptr_t) - 1)) != 0)) - { - *b++ = 0; - len--; - } - volatile uintptr_t *w = (volatile uintptr_t *)b; - while (len >= sizeof(uintptr_t)) - { - *w++ = 0; - len -= sizeof(uintptr_t); - } - b = (volatile uint8_t *)w; - while (len != 0) - { - *b++ = 0; - len--; - } -} - -/** - * @brief Borrow @p n bytes of secure storage, aligned to @p align. - * - * Returns uninitialized memory (the pool wipes on release, not on hand-out). Returns NULL if the - * request does not fit - callers MUST handle null and fail closed. - * - * @param n bytes requested. - * @param align required alignment in bytes, a power of two (0 selects the platform default). - */ -void *protocore_secure_alloc(size_t n, size_t align); - -/** - * @brief Borrow @p n secure bytes as a span whose capacity is bound to the allocation. - * - * The preferred form: one argument sets both fields, so the capacity cannot drift from what was - * reserved. An over-budget request yields an empty span, so an omitted protocore_span_ok() check writes - * nothing rather than dereferencing null. - */ -protocore_span protocore_secure_span(size_t n, size_t align); - -/** - * @brief Borrow @p n secure bytes that outlive every mark and release. - * - * The arena is double ended (mmgr/arena.h): this takes the persistent end, which grows up from the - * base, while protocore_secure_span() bumps down from the top. A mark walks the top end only, so a table - * taken here is not reclaimed by any release, nor by protocore_secure_reset(). The bytes come back zeroed. - * - * For storage a module holds for the life of the program: a credential table, a key schedule bound - * once at setup. A working set borrowed and returned within one call takes protocore_secure_span(). - */ -protocore_span protocore_secure_persist_span(size_t n); - -/** @brief Capture the current position, to be handed to protocore_secure_release(). */ -size_t protocore_secure_mark(void); - -/** - * @brief Wipe and reclaim everything borrowed since @p mark. - * - * The wipe happens BEFORE the position moves, so the bytes are already zero at the instant they - * become available again - there is no window in which a subsequent borrow could be handed memory - * still holding the previous tenant's key material. Every return path out of a borrow must reach - * this, including the early ones taken when a peer sends something malformed. - */ -void protocore_secure_release(size_t mark); - -/** @brief Wipe and reclaim the whole slot. */ -void protocore_secure_reset(void); - -/** @brief Bytes currently handed out. */ -size_t protocore_secure_used(void); - -/** @brief Peak bytes ever handed out, for sizing PROTOCORE_SECURE_ARENA_SIZE. */ -size_t protocore_secure_high_water(void); - -/** @brief Total per-slot capacity in bytes (PROTOCORE_SECURE_ARENA_SIZE). */ -size_t protocore_secure_capacity(void); - -/** - * @brief True if @p p points inside the secure pool. - * - * One unsigned subtract and compare against the block the first borrow bound: the slot count and - * slot size are compile-time, so the pool is one region of known extent. Mutually exclusive with - * protocore_plaintext_owns() because the regions are disjoint - which is the whole access control, with no - * per-allocation bookkeeping. False while no slot has borrowed, when no pointer into the pool - * exists to ask about. - */ -proto_bool protocore_secure_owns(const void *p); - -/** @brief Which secure slot owns @p p, or -1 if @p p is not in the secure pool. */ -int protocore_secure_slot_of(const void *p); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here rather than defined in the .c, for the reason secure.c states - * about its storage: a table object in the .c names every member, so a build that only ever calls - * @ref SecureNs::reset would still reference @ref SecureNs::alloc, and through it `bind()` and the - * pool's backing bytes. Initialized here, the member read resolves in the reading translation unit - * and the table is dropped, so `--gc-sections` still reclaims the storage from firmware that never - * borrows a secret. - * - * `unused` because this header reaches files that take none of it. - */ -// Designated, so a member's position in the struct does not decide what it binds to. -static const SecureNs secure __attribute__((unused)) = {.alloc = protocore_secure_alloc, - .span = protocore_secure_span, - .persist_span = protocore_secure_persist_span, - .reset = protocore_secure_reset, - .mark = protocore_secure_mark, - .release = protocore_secure_release, - .used = protocore_secure_used, - .high_water = protocore_secure_high_water, - .capacity = protocore_secure_capacity, - .owns = protocore_secure_owns, - .slot_of = protocore_secure_slot_of, - .internal = &protocore_secure_state}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_SECURE_H diff --git a/src/mmgr/span/CMakeLists.txt b/src/mmgr/span/CMakeLists.txt deleted file mode 100644 index c5c200d16..000000000 --- a/src/mmgr/span/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/span - SOURCES span.c -) diff --git a/src/mmgr/span/span.c b/src/mmgr/span/span.c deleted file mode 100644 index ac792c9cc..000000000 --- a/src/mmgr/span/span.c +++ /dev/null @@ -1,103 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file span.c - * @brief The bounded byte-region accessors - see span.h. - * - * A constructor normalizes the empty case: a pointer with no capacity, or a capacity with no - * pointer, becomes `{NULL, 0}`, so the two fields never disagree. A sub-region clamps its offset and - * its length to what the parent holds, so a truncated frame yields a zero-capacity region instead of - * a pointer past the allocation. - * - * The one symbol this file exports is @ref span. - */ - -#include "mmgr/span/span.h" - -protocore_span protocore_span_from(uint8_t *p, size_t cap) -{ - protocore_span s; - s.buf = (p != NULL && cap != 0) ? p : NULL; - s.cap = (s.buf != NULL) ? cap : 0; - s.pos = 0; - s.overflow = PROTO_FALSE; - return s; -} - -protocore_cspan protocore_cspan_from(const uint8_t *p, size_t len) -{ - protocore_cspan s; - s.buf = (p != NULL && len != 0) ? p : NULL; - s.len = (s.buf != NULL) ? len : 0; - s.pos = 0; - s.err = PROTO_FALSE; - return s; -} - -proto_bool protocore_span_ok(protocore_span s) -{ - return s.buf != NULL && !s.overflow; -} - -proto_bool protocore_span_has_storage(protocore_span s) -{ - return s.buf != NULL; -} - -proto_bool protocore_cspan_ok(protocore_cspan s) -{ - return s.buf != NULL && !s.err; -} - -size_t protocore_span_len(protocore_span s) -{ - return s.pos; -} - -size_t protocore_span_room(protocore_span s) -{ - return (s.pos < s.cap) ? (s.cap - s.pos) : 0; -} - -void protocore_span_reset(protocore_span *s) -{ - s->pos = 0; - s->overflow = PROTO_FALSE; -} - -protocore_span protocore_span_after(protocore_span s, size_t off) -{ - if (!protocore_span_has_storage(s) || off >= s.cap) - { - return protocore_span_from(NULL, 0); - } - return protocore_span_from(s.buf + off, s.cap - off); -} - -protocore_span protocore_span_first(protocore_span s, size_t n) -{ - if (!protocore_span_has_storage(s)) - { - return protocore_span_from(NULL, 0); - } - return protocore_span_from(s.buf, (n < s.cap) ? n : s.cap); -} - -protocore_cspan protocore_span_produced(protocore_span s) -{ - if (!protocore_span_ok(s)) - { - return protocore_cspan_from(NULL, 0); - } - return protocore_cspan_from(s.buf, s.pos); -} - -protocore_cspan protocore_span_read(protocore_span s, size_t len) -{ - if (!protocore_span_has_storage(s)) - { - return protocore_cspan_from(NULL, 0); - } - return protocore_cspan_from(s.buf, (len < s.cap) ? len : s.cap); -} diff --git a/src/mmgr/span/span.h b/src/mmgr/span/span.h deleted file mode 100644 index cebab1937..000000000 --- a/src/mmgr/span/span.h +++ /dev/null @@ -1,168 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file span.h - * @brief A byte region that carries its own bound, and the accessors that move bytes through it. - * - * `cap` bounds every write. `pos` keeps counting past `cap` on overflow, so an undersized region - * reports the capacity it should have had instead of only failing. - * - * Accessors take the span first. A pointer, a length, and an offset passed separately are this struct - * with its invariant dropped; passing the region keeps the bound attached to the bytes. - * - * A failed allocation yields a null pointer with zero capacity, never a null pointer with a live - * capacity, so a caller that skips span.ok() writes nothing instead of dereferencing null. - * - * The reading accessors take the region by value and span.reset() takes a pointer, so a caller can - * see at the call site which one writes. - * - * The bodies live in span.c and are reached through @ref span. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_SPAN_H -#define PROTOCORE_SPAN_H - -#include "protocore_config.h" // the entry point: protocore_types.h for proto_bool / size_t / uint8_t - -PROTOCORE_BEGIN_DECLS - -/** - * @brief A writable byte region: the storage, the capacity that belongs to it, and what has been - * produced into it. - * - */ -typedef struct -{ - uint8_t *buf; ///< first byte, or NULL when the region could not be obtained - size_t cap; ///< bytes writable at @ref buf (0 whenever @ref buf is NULL) - size_t pos; ///< bytes the payload needs so far; keeps counting past @ref cap on overflow - proto_bool overflow; ///< set once a write did not fit; @ref pos then reports the size required -} protocore_span; - -/** - * @brief A read-only byte region. - * - * Bind with span.cfrom() and check with span.cok(). A read is bounded by the region itself, which is - * why nothing here takes a separate length. - */ -typedef struct -{ - const uint8_t *buf; ///< first byte, or NULL when there is nothing to read - size_t len; ///< readable bytes at @ref buf (0 whenever @ref buf is NULL) - size_t pos; ///< read cursor - proto_bool err; ///< sticky: a read ran past @ref len -} protocore_cspan; - -/** - * @brief The bounded-region module. Every constructor normalizes the empty case; every sub-region - * clamps to what its parent holds. - * - * @var SpanNs::from - * Bind a span to memory whose extent is only known at run time. Storage without capacity, or capacity - * without storage, normalizes to `{NULL, 0}`. - * - * @var SpanNs::ok - * True when the span refers to real storage and every write so far has fit. - * - * @var SpanNs::has_storage - * True when the span refers to real storage, whether or not a write has overflowed. - * - * @var SpanNs::len - * Bytes the payload needs - the backward direction. Equals the bytes written while everything fit. - * After an overflow it keeps counting, so a value greater than @ref protocore_span::cap is exactly the - * capacity the run-length constant should have had. - * - * @var SpanNs::room - * Writable bytes remaining (0 once the region is full or has overflowed). - * - * @var SpanNs::reset - * Rewind to empty, keeping the same storage and clearing the overflow flag. Takes a pointer, so the - * call site shows that this one writes. - * - * @var SpanNs::after - * The sub-span starting @c off bytes into @c s, a fresh empty cursor over that tail. Clamps rather - * than trapping: an @c off past the end yields an empty span, which writes nothing. - * - * @var SpanNs::first - * The first @c n bytes of @c s as a fresh span, clamped to what @c s actually has. - * - * @var SpanNs::produced - * A read-only view of what has been produced into @c s: the length comes from the span's own cursor, - * so a reader is never handed a length that disagrees with the bytes. Yields an empty view when the - * span overflowed. - * - * @var SpanNs::read - * A read-only view of the first @c len bytes of @c s, clamped to its capacity. - * - * @var SpanNs::cfrom - * Bind a read-only span to memory whose extent is only known at run time. Normalizes the empty case - * the way @ref SpanNs::from does. - * - * @var SpanNs::cok - * True when the read-only span refers to real bytes and no read has run past the end. - * - * No storage member: every accessor works on the region the caller passes and holds nothing of its - * own. - */ -typedef struct -{ - protocore_span (*from)(uint8_t *p, size_t cap); - proto_bool (*ok)(protocore_span s); - proto_bool (*has_storage)(protocore_span s); - size_t (*len)(protocore_span s); - size_t (*room)(protocore_span s); - void (*reset)(protocore_span *s); - protocore_span (*after)(protocore_span s, size_t off); - protocore_span (*first)(protocore_span s, size_t n); - protocore_cspan (*produced)(protocore_span s); - protocore_cspan (*read)(protocore_span s, size_t len); - protocore_cspan (*cfrom)(const uint8_t *p, size_t len); - proto_bool (*cok)(protocore_cspan s); -} SpanNs; - -// The accessors, in span.c. Named here because the table below has to name them, and prefixed -// because that puts them in the linker's namespace. -protocore_span protocore_span_from(uint8_t *p, size_t cap); -proto_bool protocore_span_ok(protocore_span s); -proto_bool protocore_span_has_storage(protocore_span s); -size_t protocore_span_len(protocore_span s); -size_t protocore_span_room(protocore_span s); -void protocore_span_reset(protocore_span *s); -protocore_span protocore_span_after(protocore_span s, size_t off); -protocore_span protocore_span_first(protocore_span s, size_t n); -protocore_cspan protocore_span_produced(protocore_span s); -protocore_cspan protocore_span_read(protocore_span s, size_t len); -protocore_cspan protocore_cspan_from(const uint8_t *p, size_t len); -proto_bool protocore_cspan_ok(protocore_cspan s); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away and the call to the body in span.c is direct, leaving the table referenced by - * nothing for the linker to drop. - * - * `unused` because a header this wide is included by files that take none of it. - */ -// Designated, so a member's position in the struct does not decide what it binds to. -static const SpanNs span __attribute__((unused)) = {.from = protocore_span_from, - .ok = protocore_span_ok, - .has_storage = protocore_span_has_storage, - .len = protocore_span_len, - .room = protocore_span_room, - .reset = protocore_span_reset, - .after = protocore_span_after, - .first = protocore_span_first, - .produced = protocore_span_produced, - .read = protocore_span_read, - .cfrom = protocore_cspan_from, - .cok = protocore_cspan_ok}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_SPAN_H diff --git a/src/mmgr/swar/CMakeLists.txt b/src/mmgr/swar/CMakeLists.txt deleted file mode 100644 index 2261e8faa..000000000 --- a/src/mmgr/swar/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -# SPDX-License-Identifier: AGPL-3.0-or-later - -protocore_add_module(mmgr/swar - SOURCES swar.c - DEPS - mmgr/rawmemcpy -) diff --git a/src/mmgr/swar/swar.c b/src/mmgr/swar/swar.c deleted file mode 100644 index 734279666..000000000 --- a/src/mmgr/swar/swar.c +++ /dev/null @@ -1,202 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file swar.c - * @brief The lane math - see swar.h. - * - * One machine word treated as its byte lanes. Every body here sets the guard bit of each lane before - * subtracting, so a borrow cannot cross out of the lane that raised it, and reads the high bits back - * as the per-lane answer. Nothing branches and nothing walks a buffer. - * - * The table @ref swar names ten of these. The rest are the halves the `_sel` pair chooses between. - */ - -#include "mmgr/swar/swar.h" - -/** @brief Per lane: 0x80 where the lane is >= @p v, else 0. */ -protocore_swar_word protocore_swar_ge(protocore_swar_word a, protocore_swar_word v) -{ - return ((a | PROTOCORE_SWAR_HIGH) - v * PROTOCORE_SWAR_ONES) & PROTOCORE_SWAR_HIGH; -} - -/** @brief Per lane: 0x80 where the lane is <= @p v, else 0. */ -protocore_swar_word protocore_swar_le(protocore_swar_word a, protocore_swar_word v) -{ - return ((v * PROTOCORE_SWAR_ONES | PROTOCORE_SWAR_HIGH) - a) & PROTOCORE_SWAR_HIGH; -} - -/** @brief Widen a 0x80-per-lane mask to 0xFF per lane, without carrying between lanes. */ -protocore_swar_word protocore_swar_spread(protocore_swar_word m) -{ - return m + (m - (m >> 7)); -} - -/** @brief Per lane: (lane - @p lo) in the low 7 bits, guard bit absorbing the borrow. */ -protocore_swar_word protocore_swar_sub7(protocore_swar_word a, protocore_swar_word lo) -{ - return ((a | PROTOCORE_SWAR_HIGH) - lo * PROTOCORE_SWAR_ONES) & PROTOCORE_SWAR_LOW7; -} - -/** - * @brief 0x80 in every lane of @p w that is zero, and only those. - * - * Exact per lane, which is dearer than the usual spelling by one operation and worth it. The cheap - * form is `(w - ONES) & ~w & HIGH`: a lane holding 0x00 borrows into its own high bit, which is the - * answer, but that borrow does not stop at the lane boundary and goes on to mark lanes above it that - * hold no zero at all. A caller reading only ::protocore_swar_zero_lane never sees it, because the lowest - * set bit is always a true one. A caller that ANDs two of these masks together, or reads any lane - * but the first, gets a byte that is not there - `0x0100` reports both of its lanes zero. - * - * Adding LOW7 to the low seven bits of a lane carries into bit 7 for every value except 0x00, and - * ORing @p w back in covers the lane that was exactly 0x80. So the guard bit ends up set on each - * NONZERO lane, with nothing crossing between lanes, and the complement is the answer. - */ -protocore_swar_word protocore_swar_has_zero(protocore_swar_word w) -{ - return ~(((w & PROTOCORE_SWAR_LOW7) + PROTOCORE_SWAR_LOW7) | w) & PROTOCORE_SWAR_HIGH; -} - -/** - * @brief Per lane: 0x80 where the lane equals @p c, else 0. - * - * XOR zeroes exactly the lanes that match, so the zero test finds them. That is what lets ONE load - * answer for as many delimiters as a caller cares about: OR the masks together and the first set - * lane is the first occurrence of any of them. A scan per delimiter would re-load the same word once - * per byte it is looking for, and then have to reconcile which hit came first. - * - * protocore_swar_word w = swar.load(p); - * protocore_swar_word m = swar.eq(w, '&', PROTO_FALSE) | swar.eq(w, '=', PROTO_FALSE); - */ -protocore_swar_word protocore_swar_eq(protocore_swar_word w, uint8_t c) -{ - return protocore_swar_has_zero(w ^ (PROTOCORE_SWAR_ONES * (protocore_swar_word)c)); -} - -/** - * @brief Which lane of a ::protocore_swar_has_zero mask is the first zero byte, in address order. - * - * The answer is one of 0..PROTOCORE_SWAR_BYTES-1 and the mask already holds it - the set guard bit IS the - * position. Re-walking the word's bytes to find out would spend a compare per byte to recover what - * the mask states, which is the same waste the word test just avoided. - * - * Address order is where byte order enters, and only here: the lowest-addressed byte is the least - * significant lane on a little-endian load and the most significant on a big-endian one, so the - * count is taken from the matching end. Nothing else in this module depends on the layout. - */ -size_t protocore_swar_zero_lane(protocore_swar_word m) -{ -#if PROTOCORE_HW_BIG_ENDIAN - // The count runs over the whole builtin width; the carrier sits in the low bits, so drop the pad. - return (size_t)((PROTOCORE_SWAR_CLZ(m) - (PROTOCORE_SWAR_CLZ_WIDTH - PROTO_SWAR_BITS)) >> 3); -#else - return (size_t)(PROTOCORE_SWAR_CTZ(m) >> 3); -#endif -} - -/** - * @brief Load one word from @p p, whatever its alignment. - * - * Deferred to the raw load rather than spelled here: a `*(const protocore_swar_word *)` cast is undefined - * both for an unaligned address and for reading a `char` array as a wider type, and it traps on the - * stricter targets. Taking the width from ::PROTOCORE_SWAR_BYTES keeps this correct when the lane carrier - * is retyped. - */ -protocore_swar_word protocore_swar_load(const char *p) -{ - return (protocore_swar_word)proto_raw_load(p, PROTOCORE_SWAR_BYTES); -} - -/** - * @brief ::protocore_swar_load for an address the caller has already walked to a lane boundary. - * - * Same value, one instruction instead of a synthesized word. ::protocore_swar_load assumes nothing about - * its address, and where PROTOCORE_HW_UNALIGNED_LOAD is 0 the compiler answers that assumption by building - * each word out of byte loads and shifts. A caller that has already paid a prologue to reach a - * boundary throws that away by asking for a load which disclaims alignment. - * - * @p p must be ::PROTOCORE_SWAR_BYTES-aligned. That is a real precondition, not a hint - a strict-alignment - * part faults on it. - */ -protocore_swar_word protocore_swar_load_al(const char *p) -{ - return (protocore_swar_word)proto_al_load(p, PROTOCORE_SWAR_BYTES); -} - -/** @brief The exact syndrome: zero in exactly the lanes where @p wa and @p wb match. */ -protocore_swar_word protocore_swar_xor(protocore_swar_word wa, protocore_swar_word wb) -{ - return wa ^ wb; -} - -/** - * @brief ::protocore_swar_xor with a difference of ASCII case alone cancelled out of it. - * - * The syndrome is @p wa ^ @p wb and the allowed class is {0, 0x20} - identical, or differing in the - * one bit that carries ASCII case - restricted to lanes where flipping that bit still names the same - * letter. Clearing bit 5 of the syndrome on exactly those lanes IS the test: a lane falls to zero - * when its syndrome was in the class, and a lane with any second bit set survives. - * - * So there is nothing to ask afterwards. Testing whether the syndrome WAS 0x20 re-derives what - * clearing the bit decides, and widening a 0x80 lane mask to 0xFF to mask it back down to 0x20 - * spends three operations moving a bit two places that a shift moves in one without leaving its - * lane. 13 operations per word. - * - * Branchless, like every other lane test here: a zero syndrome stays zero through every step, so an - * early-out would spend a branch on parts where a mispredict costs more than it skipped. - * - * ORing 0x20 into one side puts both cases of a letter in `a`..`z`, so the letter test is one range - * rather than two - and only one side needs testing, because a lane whose two sides disagree in any - * bit but 5 fails on that bit regardless of what this decides. - * - * ASCII only, deliberately. Every field this serves is defined as ASCII by its own standard (an HTTP - * field name, RFC 7230 3.2; a Connection or Upgrade token; an SMTP verb), so treating any other byte - * as having a case would be inventing a rule no spec here states. - * - * `& ~lo` is what holds that line, and it is not decoration. ::protocore_swar_ge and ::protocore_swar_le answer - * for 7-bit lanes: the guard bit they borrow into is already set on a lane above 0x7F, so the - * comparison it was standing in for is gone and such a lane range-tests as a letter. 0xDB and 0xFB - * differ by exactly the case bit and would have been accepted as a case pair - a Latin-1 or UTF-8 - * byte silently matching a different one. The mask keeps a lane out of the range test's answer - * whenever bit 7 says the answer is not the test's to give. - */ -protocore_swar_word protocore_swar_xor_ci(protocore_swar_word wa, protocore_swar_word wb) -{ - protocore_swar_word x = wa ^ wb; - protocore_swar_word lo = wa | (PROTOCORE_SWAR_ONES * 0x20u); - protocore_swar_word alpha = protocore_swar_ge(lo, 'a') & protocore_swar_le(lo, 'z') & ~lo; - return x & ~(alpha >> 2); // 0x80 per letter lane, shifted onto the case bit it is allowed to eat -} - -/** - * @brief ::protocore_swar_eq ignoring ASCII case: 0x80 per lane equal to @p c under case folding. - * - * The case bit cannot simply be masked out of both sides. Bit 5 is the case bit only for a letter; - * clearing it elsewhere merges pairs that are not a case pair at all, and `'0'` (0x30) would report - * equal to DLE (0x10). ::protocore_swar_xor_ci is the syndrome that cancels bit 5 on letter lanes only, so - * a zero lane of it is a case-insensitive match and the same zero test reads the answer. - */ -protocore_swar_word protocore_swar_eq_ci(protocore_swar_word w, uint8_t c) -{ - return protocore_swar_has_zero(protocore_swar_xor_ci(w, PROTOCORE_SWAR_ONES * (protocore_swar_word)c)); -} - -// Exact and case-folding are separate tests, so the bool names which one runs rather than travelling -// into it. -protocore_swar_word protocore_swar_eq_sel(protocore_swar_word w, uint8_t c, proto_bool ci) -{ - if (ci) - { - return protocore_swar_eq_ci(w, c); - } - return protocore_swar_eq(w, c); -} - -protocore_swar_word protocore_swar_xor_sel(protocore_swar_word wa, protocore_swar_word wb, proto_bool ci) -{ - if (ci) - { - return protocore_swar_xor_ci(wa, wb); - } - return protocore_swar_xor(wa, wb); -} diff --git a/src/mmgr/swar/swar.h b/src/mmgr/swar/swar.h deleted file mode 100644 index 4e442f601..000000000 --- a/src/mmgr/swar/swar.h +++ /dev/null @@ -1,213 +0,0 @@ -// ProtoCore v1.0.16 - Copyright (C) 2026 Douglas Quigg (dstroy0) -// SPDX-License-Identifier: AGPL-3.0-or-later - -/** - * @file swar.h - * @brief Lane math: one machine word treated as its byte lanes, tested in parallel. - * - * SWAR is "SIMD within a register" - a plain word holds several bytes, and an arithmetic trick - * answers a question about all of them at once. The trick is the guard bit: set every lane's high - * bit before subtracting so a borrow cannot cross out of its lane, then read the high bits back as - * the per-lane answer. What would be one compare and one branch per byte becomes two arithmetic - * operations and no branches at all. - * - * **The width is a typedef, not a decision.** The algebra is identical at any width - the lane masks - * are derived from ::protocore_swar_word rather than written out, so the carrier follows ::PROTO_SWAR_BITS - * and every constant follows it. That knob defaults to the register width the die declares in - * vendor/board_profiles/, so nothing here infers a width from the toolchain. - * - * **This is the access layer.** Load a word, test its lanes, name the lane that fired. Nothing here - * walks a buffer or takes a capacity, which is what keeps the byte-order claim under - * ::SwarNs::zero_lane true: a lane count is the one place address order is decided, and stepping - * across a word pair is not this file's business. The scans, compares, searches and the bounded copy - * built on these live in mmgr/protostr.h, behind @ref str. - * - * **Constant time.** Every operation here is branchless and data-independent, which is why the - * base64 decoder classifies characters with ::SwarNs::ge and ::SwarNs::le rather than a table: an - * address derived from a secret byte leaks it through the cache, and an arithmetic mask cannot. The - * walks behind @ref str are NOT in that class - they stop at the byte they find, which is the whole - * point of a bounded scan. Never run one over a secret. - * - * The lane constants are macros because they are constant expressions a caller puts in an array - * bound, a `#if` or a static_assert. The lane tests are functions and their bodies are in swar.c. - * - * @author Douglas Quigg (dstroy0) - * @date 2026 - */ - -#ifndef PROTOCORE_SWAR_H -#define PROTOCORE_SWAR_H - -#include "mmgr/rawmemcpy/rawmemcpy.h" // proto_raw_load: the one owner of an unaligned wider load - -#include "protocore_config.h" // PROTO_SWAR_BITS: the platform's lane-carrier width - -PROTOCORE_BEGIN_DECLS - -/** - * @brief The lane carrier, selected by the platform width knob. - * - * The type follows ::PROTO_SWAR_BITS rather than the width following the type, so the number that - * every mask below is derived from is a preprocessor value the build can set (-DPROTO_SWAR_BITS) and - * conditionals can test. A typedef alone could do neither. - */ -#if PROTO_SWAR_BITS == 64 -typedef uint64_t protocore_swar_word; -#elif PROTO_SWAR_BITS == 32 -typedef uint32_t protocore_swar_word; -#elif PROTO_SWAR_BITS == 16 -typedef uint16_t protocore_swar_word; -#elif PROTO_SWAR_BITS == 8 -// One lane per word: the algebra is unchanged (ONES is 1, the guard bit is 0x80), it just answers -// for a single byte at a time. The honest setting for a machine with no wider register, and the -// floor the wider rungs are built from. -typedef uint8_t protocore_swar_word; -#else -#error "PROTO_SWAR_BITS must be 8, 16, 32 or 64" -#endif - -#define PROTOCORE_SWAR_BYTES ((size_t)(PROTO_SWAR_BITS / 8u)) ///< lanes per word - -// `static_assert`, not C11's `_Static_assert`: this header rides in through protocore.h to the C++ -// translation units that call this library, where the underscored spelling is not a keyword. See -// protocore_types.h. -static_assert(sizeof(protocore_swar_word) * 8u == PROTO_SWAR_BITS, - "the lane carrier must be exactly PROTO_SWAR_BITS wide"); - -// One bit per lane, derived from the width rather than written out: the all-ones word divided by -// 0xFF leaves exactly bit 0 of each lane (0xFFFFFFFF / 0xFF == 0x01010101), and the other two masks -// are that scaled. Spelling them as hex literals would pin the width in three more places. -#define PROTOCORE_SWAR_ONES (((protocore_swar_word) ~(protocore_swar_word)0) / 0xFFu) ///< bit 0 of every lane -#define PROTOCORE_SWAR_HIGH (PROTOCORE_SWAR_ONES * 0x80u) ///< bit 7 (the guard bit) of every lane -#define PROTOCORE_SWAR_LOW7 (PROTOCORE_SWAR_ONES * 0x7Fu) ///< bits 0-6 of every lane - -/** - * @brief The bit-scan pair ::SwarNs::zero_lane reads a lane position out of, at the carrier's width. - * - * The count is taken at the CARRIER's width, which is why the builtin is selected here rather than - * fixed. `unsigned` alone would truncate a carrier wider than 32 bits - a mask whose only set guard - * bit sits above bit 31 becomes 0, and a zero count is undefined. `unsigned long long` alone asks a - * 32-bit machine to count twice the bits it has, which is two registers to fill for a question that - * fits in one. - * - * The builtin is also how the compiler reaches whatever bit-scan the die has. These stay macros: a - * builtin is not a callable object, and ::PROTOCORE_SWAR_CLZ_WIDTH is a constant expression callers - * put in shift counts. - */ -#if PROTO_SWAR_BITS <= 32 -#define PROTOCORE_SWAR_CTZ(v) __builtin_ctz((unsigned)(v)) -#define PROTOCORE_SWAR_CLZ(v) __builtin_clz((unsigned)(v)) -#define PROTOCORE_SWAR_CLZ_WIDTH 32u -#else -#define PROTOCORE_SWAR_CTZ(v) __builtin_ctzll((unsigned long long)(v)) -#define PROTOCORE_SWAR_CLZ(v) __builtin_clzll((unsigned long long)(v)) -#define PROTOCORE_SWAR_CLZ_WIDTH 64u -#endif - -/// @name What one step of a walk concluded -/// @{ -#define PROTOCORE_SWAR_GO 0 ///< undecided: keep stepping -#define PROTOCORE_SWAR_YES 1 ///< they agree, by whichever rule the caller asked for -#define PROTOCORE_SWAR_NO 2 ///< they do not -/// @} - -/** - * @brief The lane-math module. One word in, a per-lane answer out, branchless throughout. - * - * @var SwarNs::ge - * Per lane: 0x80 where the lane is >= @c v, else 0. The guard bit is set on every lane before the - * subtraction, so a borrow stays inside the lane that raised it and the bit that survives is that - * lane's own answer. - * - * @var SwarNs::le - * Per lane: 0x80 where the lane is <= @c v, else 0. The same subtraction with the operands the other - * way round. - * - * @var SwarNs::spread - * Widen a 0x80-per-lane mask to 0xFF per lane, without carrying between lanes. - * - * @var SwarNs::sub7 - * Per lane: (lane - @c lo) in the low 7 bits, the guard bit absorbing the borrow. - * - * @var SwarNs::has_zero - * 0x80 in every lane of @c w that is zero, and only those. Exact per lane, so two of these masks may - * be ANDed and any lane of one may be read, not just the lowest. - * - * @var SwarNs::eq - * Per lane: 0x80 where the lane equals @c c, else 0. @c ci folds ASCII case, which merges a letter - * with its other case and nothing else. ORing several of these masks answers for several delimiters - * off one load. - * - * @var SwarNs::xor_ - * The syndrome of @c wa against @c wb: zero in exactly the lanes that match. @c ci additionally - * cancels a difference of ASCII case alone, on the lanes where flipping that bit still names the - * same letter. - * - * The member is spelled `xor_` because `xor` is an alternative token in C++, and this header reaches - * the C++ translation units. - * - * @var SwarNs::zero_lane - * Which lane of a mask is the first one set, in address order: 0..PROTOCORE_SWAR_BYTES-1. Address - * order is where byte order enters, and only here. - * - * @var SwarNs::load - * One word from @c p, whatever its alignment. - * - * @var SwarNs::load_al - * The same, for an address the caller has already walked to a lane boundary. @c p must be - * ::PROTOCORE_SWAR_BYTES-aligned; a strict-alignment part faults otherwise. - * - * No storage member: every operation works on the word or pointer handed to it and holds nothing of - * its own. There is no pool, no cursor and no configuration to keep. - */ -typedef struct -{ - protocore_swar_word (*ge)(protocore_swar_word a, protocore_swar_word v); - protocore_swar_word (*le)(protocore_swar_word a, protocore_swar_word v); - protocore_swar_word (*spread)(protocore_swar_word m); - protocore_swar_word (*sub7)(protocore_swar_word a, protocore_swar_word lo); - protocore_swar_word (*has_zero)(protocore_swar_word w); - protocore_swar_word (*eq)(protocore_swar_word w, uint8_t c, proto_bool ci); - protocore_swar_word (*xor_)(protocore_swar_word wa, protocore_swar_word wb, proto_bool ci); - size_t (*zero_lane)(protocore_swar_word m); - protocore_swar_word (*load)(const char *p); - protocore_swar_word (*load_al)(const char *p); -} SwarNs; - -// The lane tests, in swar.c. Named here because the table below has to name them, and prefixed -// because that puts them in the linker's namespace. The `_sel` pair is what the table's `eq` and -// `xor_` members hold: exact and case-folding are separate tests, so the bool names which one runs -// rather than travelling into it. -protocore_swar_word protocore_swar_ge(protocore_swar_word a, protocore_swar_word v); -protocore_swar_word protocore_swar_le(protocore_swar_word a, protocore_swar_word v); -protocore_swar_word protocore_swar_spread(protocore_swar_word m); -protocore_swar_word protocore_swar_sub7(protocore_swar_word a, protocore_swar_word lo); -protocore_swar_word protocore_swar_has_zero(protocore_swar_word w); -protocore_swar_word protocore_swar_eq(protocore_swar_word w, uint8_t c); -protocore_swar_word protocore_swar_eq_ci(protocore_swar_word w, uint8_t c); -protocore_swar_word protocore_swar_eq_sel(protocore_swar_word w, uint8_t c, proto_bool ci); -protocore_swar_word protocore_swar_xor(protocore_swar_word wa, protocore_swar_word wb); -protocore_swar_word protocore_swar_xor_ci(protocore_swar_word wa, protocore_swar_word wb); -protocore_swar_word protocore_swar_xor_sel(protocore_swar_word wa, protocore_swar_word wb, proto_bool ci); -size_t protocore_swar_zero_lane(protocore_swar_word m); -protocore_swar_word protocore_swar_load(const char *p); -protocore_swar_word protocore_swar_load_al(const char *p); - -/** - * @brief The names, aliased. - * - * `static const` and initialized here, not declared `extern` against a definition in the .c: a - * translation unit that can see this initializer knows which function each member holds, so a member - * read folds away and the call to the lane test in swar.c is direct, leaving the table referenced by - * nothing for the linker to drop. - * - * `unused` because a header this wide is included by files that take none of it. - */ -static const SwarNs swar __attribute__((unused)) = { - protocore_swar_ge, protocore_swar_le, protocore_swar_spread, protocore_swar_sub7, - protocore_swar_has_zero, protocore_swar_eq_sel, protocore_swar_xor_sel, protocore_swar_zero_lane, - protocore_swar_load, protocore_swar_load_al}; - -PROTOCORE_END_DECLS - -#endif // PROTOCORE_SWAR_H diff --git a/src/network_drivers/application/binary_asset_blobs/CMakeLists.txt b/src/network_drivers/application/binary_asset_blobs/CMakeLists.txt index aa246f9ae..828719090 100644 --- a/src/network_drivers/application/binary_asset_blobs/CMakeLists.txt +++ b/src/network_drivers/application/binary_asset_blobs/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(network_drivers/application/binary_asset_blobs GATE PROTOCORE_ENABLE_THEMES SOURCES binary_asset_blobs.c PRIVATE_DEPS - mmgr/protostr + mmgr ) diff --git a/src/network_drivers/application/binary_asset_blobs/binary_asset_blobs.c b/src/network_drivers/application/binary_asset_blobs/binary_asset_blobs.c index dec389149..12d29250a 100644 --- a/src/network_drivers/application/binary_asset_blobs/binary_asset_blobs.c +++ b/src/network_drivers/application/binary_asset_blobs/binary_asset_blobs.c @@ -7,7 +7,7 @@ #include "protocore_config.h" // the entry point: the widths #include "binary_asset_blobs.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" #if PROTOCORE_ENABLE_THEMES @@ -2159,13 +2159,14 @@ const char *protocore_binary_asset_blobs_css(uint8_t *work, const char *name) { return NULL; } - // str.eq reads read_cap bytes of both operands, so the lengths are matched first: two + // cellul.eq reads cap bytes of both operands, so the lengths are matched first: two // strings of length n each hold n + 1 readable bytes, the terminator included. - const size_t n = str.len(name, THEME_NAME_CAP); + const size_t n = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = name, .cap = THEME_NAME_CAP); for (size_t i = 0; i < PROTOCORE_THEME_BLOB_COUNT; i++) { const char *have = PROTOCORE_THEME_BLOBS[i].name; - if (str.len(have, THEME_NAME_CAP) == n && str.eq(have, name, n + 1u, PROTO_FALSE)) + if (EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = have, .cap = THEME_NAME_CAP) == n && + EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = have, .other = name, .cap = n + 1u, .ci = PROTO_FALSE)) { return PROTOCORE_THEME_BLOBS[i].css; } diff --git a/src/network_drivers/application/http_range/CMakeLists.txt b/src/network_drivers/application/http_range/CMakeLists.txt index 9144a282b..8fc213a6c 100644 --- a/src/network_drivers/application/http_range/CMakeLists.txt +++ b/src/network_drivers/application/http_range/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(network_drivers/application/http_range GATE PROTOCORE_ENABLE_RANGE SOURCES http_range.c PRIVATE_DEPS - mmgr/protostr + mmgr ) diff --git a/src/network_drivers/application/http_range/http_range.c b/src/network_drivers/application/http_range/http_range.c index 7023a3739..004a03108 100644 --- a/src/network_drivers/application/http_range/http_range.c +++ b/src/network_drivers/application/http_range/http_range.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_RANGE -#include "mmgr/protostr/protostr.h" // str.starts / str.find: the unit prefix and the multi-range comma +#include "cellularum_laboro/cellularum_laboro.h" // cellul.starts / cellul.find: the unit prefix and the multi-range comma #include "network_drivers/application/http_range/http_range.h" // strncasecmp, strchr @@ -31,7 +31,7 @@ int protocore_http_range_http_parse_byte_range(uint8_t *work, const char *hdr, s return 0; } // Require the "bytes=" unit (case-insensitive). - if (!str.starts(hdr, "bytes=", 6, PROTO_TRUE)) + if (!EMBED_CALL(cellul.starts, CatenaFinitaCfg, .src = hdr, .other = "bytes=", .cap = 6, .ci = PROTO_TRUE)) { return 0; } @@ -40,7 +40,8 @@ int protocore_http_range_http_parse_byte_range(uint8_t *work, const char *hdr, s { p++; } - if (str.find(p, MAX_VAL_LEN, ",", sizeof(","), PROTO_FALSE)) // multi-range not supported -> fall back to full 200 + if (EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = p, .cap = MAX_VAL_LEN, .other = ",", .other_cap = sizeof(","), + .ci = PROTO_FALSE)) // multi-range not supported -> fall back to full 200 { return 0; } diff --git a/src/network_drivers/application/nts/CMakeLists.txt b/src/network_drivers/application/nts/CMakeLists.txt index 38b57fef1..51642d183 100644 --- a/src/network_drivers/application/nts/CMakeLists.txt +++ b/src/network_drivers/application/nts/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(network_drivers/application/nts GATE PROTOCORE_ENABLE_NTS SOURCES nts.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/application/nts/nts.c b/src/network_drivers/application/nts/nts.c index 18becc789..6925f9f02 100644 --- a/src/network_drivers/application/nts/nts.c +++ b/src/network_drivers/application/nts/nts.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_NTS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/application/nts/nts.h" PROTOCORE_BEGIN_DECLS @@ -61,7 +61,7 @@ void protocore_nts_ke_record(uint8_t *work) put_u16(out + 2, (uint16_t)body_len); if (body_len) { - mem.cpy(out + 4, body, body_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 4, .src = body, .bytes = body_len); } NtsV.n = n; } @@ -184,7 +184,7 @@ void protocore_nts_ef(uint8_t *work) put_u16(out + 2, (uint16_t)padded); if (value_len) { - mem.cpy(out + 4, value, value_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 4, .src = value, .bytes = value_len); } for (size_t i = total; i < padded; i++) { diff --git a/src/network_drivers/application/ptp/CMakeLists.txt b/src/network_drivers/application/ptp/CMakeLists.txt index 9c59ba11a..23e4bdbd6 100644 --- a/src/network_drivers/application/ptp/CMakeLists.txt +++ b/src/network_drivers/application/ptp/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(network_drivers/application/ptp GATE PROTOCORE_ENABLE_PTP SOURCES ptp.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/application/ptp/ptp.c b/src/network_drivers/application/ptp/ptp.c index 8ffc99691..ba3cea2a6 100644 --- a/src/network_drivers/application/ptp/ptp.c +++ b/src/network_drivers/application/ptp/ptp.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_PTP -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/application/ptp/ptp.h" PROTOCORE_BEGIN_DECLS @@ -136,14 +136,14 @@ void protocore_ptp_build_header(uint8_t *work) PtpV.n = 0; return; } - mem.set(buf, 0, PROTOCORE_PTP_HEADER_LEN); + EMBED_CALL(memor.set, MemoriaCfg, .dst = buf, .val = 0, .bytes = PROTOCORE_PTP_HEADER_LEN); buf[0] = (uint8_t)((h->transport_specific << 4) | (h->message_type & 0x0F)); buf[1] = (uint8_t)(h->version & 0x0F); put_u16(buf + 2, (uint16_t)(PROTOCORE_PTP_HEADER_LEN + body_len)); buf[4] = h->domain; put_u16(buf + 6, h->flags); put_u64(buf + 8, (uint64_t)h->correction); - mem.cpy(buf + 20, h->clock_identity, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 20, .src = h->clock_identity, .bytes = 8); put_u16(buf + 28, h->port_number); put_u16(buf + 30, h->sequence_id); buf[32] = h->control; @@ -170,7 +170,7 @@ void protocore_ptp_parse_header(uint8_t *work) h->domain = s[4]; h->flags = get_u16(s + 6); h->correction = (int64_t)get_u64(s + 8); - mem.cpy(h->clock_identity, s + 20, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = h->clock_identity, .src = s + 20, .bytes = 8); h->port_number = get_u16(s + 28); h->sequence_id = get_u16(s + 30); h->control = s[32]; @@ -270,7 +270,7 @@ void protocore_ptp_build_delay_resp(uint8_t *work) PtpV.ts_write_args.ts = recv; protocore_ptp_ts_write(work); p += PROTOCORE_PTP_TS_LEN; - mem.cpy(p, req_clock_id, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = p, .src = req_clock_id, .bytes = 8); p += 8; put_u16(p, req_port); PtpV.n = PROTOCORE_PTP_HEADER_LEN + body; @@ -305,7 +305,7 @@ void protocore_ptp_build_pdelay_req(uint8_t *work) PtpV.ts_write_args.p = p; PtpV.ts_write_args.ts = origin; protocore_ptp_ts_write(work); - mem.set(p + PROTOCORE_PTP_TS_LEN, 0, 10); // reserved + EMBED_CALL(memor.set, MemoriaCfg, .dst = p + PROTOCORE_PTP_TS_LEN, .val = 0, .bytes = 10); // reserved PtpV.n = PROTOCORE_PTP_HEADER_LEN + body; } @@ -337,7 +337,7 @@ static size_t build_pdelay_resp_msg(uint8_t *work, uint8_t *buf, size_t cap, con PtpV.ts_write_args.ts = ts; Ptp.ts_write(work); p += PROTOCORE_PTP_TS_LEN; - mem.cpy(p, req_clock_id, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = p, .src = req_clock_id, .bytes = 8); p += 8; put_u16(p, req_port); return PROTOCORE_PTP_HEADER_LEN + body; @@ -409,7 +409,7 @@ void protocore_ptp_build_announce(uint8_t *work) put_u16(p, a->gm_variance); p += 2; *p++ = a->gm_priority2; - mem.cpy(p, a->gm_identity, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = p, .src = a->gm_identity, .bytes = 8); p += 8; put_u16(p, a->steps_removed); p += 2; @@ -491,7 +491,7 @@ void protocore_ptp_parse_delay_resp(uint8_t *work) PtpV.ts_read_args.ts = &out->receive; protocore_ptp_ts_read(work); p += PROTOCORE_PTP_TS_LEN; - mem.cpy(out->req_clock_id, p, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->req_clock_id, .src = p, .bytes = 8); p += 8; out->req_port = get_u16(p); PtpV.ok = PROTO_TRUE; @@ -564,7 +564,7 @@ static proto_bool parse_pdelay_resp_msg(uint8_t *work, const uint8_t *s, size_t PtpV.ts_read_args.ts = &out->timestamp; Ptp.ts_read(work); p += PROTOCORE_PTP_TS_LEN; - mem.cpy(out->req_clock_id, p, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->req_clock_id, .src = p, .bytes = 8); p += 8; out->req_port = get_u16(p); return PROTO_TRUE; @@ -638,7 +638,7 @@ void protocore_ptp_parse_announce(uint8_t *work) out->gm_variance = get_u16(p); p += 2; out->gm_priority2 = *p++; - mem.cpy(out->gm_identity, p, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->gm_identity, .src = p, .bytes = 8); p += 8; out->steps_removed = get_u16(p); p += 2; diff --git a/src/network_drivers/application/sftp/sftp/CMakeLists.txt b/src/network_drivers/application/sftp/sftp/CMakeLists.txt index be92313f8..c9679a954 100644 --- a/src/network_drivers/application/sftp/sftp/CMakeLists.txt +++ b/src/network_drivers/application/sftp/sftp/CMakeLists.txt @@ -5,8 +5,6 @@ protocore_add_module(network_drivers/application/sftp/sftp GATE PROTOCORE_ENABLE_SSH_SFTP SOURCES sftp.c PRIVATE_DEPS - mmgr/membuild - mmgr/protomem - mmgr/protostr + mmgr shared/time_compat ) diff --git a/src/network_drivers/application/sftp/sftp/sftp.c b/src/network_drivers/application/sftp/sftp/sftp.c index abb83ce46..b880e3684 100644 --- a/src/network_drivers/application/sftp/sftp/sftp.c +++ b/src/network_drivers/application/sftp/sftp/sftp.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_SSH_SFTP -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/application/sftp/sftp/sftp.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain #include "shared/time_compat/time_compat.h" // protocore_gmtime_r (portable reentrant UTC) @@ -267,7 +267,7 @@ void protocore_sftp_wr_bytes(uint8_t *work) w->ovf = PROTO_TRUE; return; } - mem.cpy(w->p + w->off, b, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = w->p + w->off, .src = b, .bytes = n); w->off += n; } @@ -437,7 +437,7 @@ void protocore_sftp_build_status(uint8_t *work) SftpV.wr_u32_args.w = &w; SftpV.wr_u32_args.v = code; protocore_sftp_wr_u32(work); - size_t ml = msg ? str.len(msg, cap) : 0; + size_t ml = msg ? EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = msg, .cap = cap) : 0; SftpV.wr_string_args.w = &w; SftpV.wr_string_args.s = msg ? msg : ""; SftpV.wr_string_args.n = (uint32_t)ml; @@ -554,11 +554,11 @@ void protocore_sftp_build_name1(uint8_t *work) protocore_sftp_wr_u32(work); // one entry SftpV.wr_string_args.w = &w; SftpV.wr_string_args.s = name; - SftpV.wr_string_args.n = (uint32_t)str.len(name, cap); + SftpV.wr_string_args.n = (uint32_t)EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = name, .cap = cap); protocore_sftp_wr_string(work); SftpV.wr_string_args.w = &w; SftpV.wr_string_args.s = longname; - SftpV.wr_string_args.n = (uint32_t)str.len(longname, cap); + SftpV.wr_string_args.n = (uint32_t)EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = longname, .cap = cap); protocore_sftp_wr_string(work); SftpV.wr_attrs_args.w = &w; SftpV.wr_attrs_args.a = a; @@ -590,7 +590,7 @@ void protocore_sftp_format_longname(uint8_t *work) mode[10] = '\0'; struct tm tmv; - mem.set(&tmv, 0, sizeof(tmv)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &tmv, .val = 0, .bytes = sizeof(tmv)); TimeCompatV.args.epoch = (time_t)mtime; // mtime==0 -> epoch, a harmless placeholder date TimeCompatV.args.out = &tmv; TimeCompat.gmtime(work); @@ -605,20 +605,24 @@ void protocore_sftp_format_longname(uint8_t *work) // a directory listing with an empty column. The wire framing is the separate length-prefixed // string written by protocore_sftp_wr_string, and that is never clipped. The date is appended in // place rather than staged: the two column widths are what `ls -l` alignment means, and - // Sb.u64_clip states them directly. - protocore_sb sb_out = {out, cap, 0, PROTO_TRUE}; - Sb.put_clip(&sb_out, mode); - Sb.put_clip(&sb_out, " 1 0 0 "); - Sb.u64_clip(&sb_out, (uint64_t)size, 0); - Sb.put_clip(&sb_out, " "); - Sb.put_clip(&sb_out, kMonths[mon]); - Sb.put_clip(&sb_out, " "); - Sb.u64_clip(&sb_out, (uint64_t)tmv.tm_mday, 2); - Sb.put_clip(&sb_out, " "); - Sb.u64_clip(&sb_out, (uint64_t)(tmv.tm_year + 1900), 5); - Sb.put_clip(&sb_out, " "); - Sb.put_clip(&sb_out, name); - SftpV.n = Sb.finish(&sb_out); + // verba_numerus.u64_clip states them directly. + size_t sb_out = 0; + sb_out = EMBED_CALL(verba_textus.put_clip, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = mode); + sb_out = EMBED_CALL(verba_textus.put_clip, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = " 1 0 0 "); + sb_out = EMBED_CALL(verba_numerus.u64_clip, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint64_t)size, .columns = 0); + sb_out = EMBED_CALL(verba_textus.put_clip, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = " "); + sb_out = + EMBED_CALL(verba_textus.put_clip, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = kMonths[mon]); + sb_out = EMBED_CALL(verba_textus.put_clip, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = " "); + sb_out = EMBED_CALL(verba_numerus.u64_clip, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint64_t)tmv.tm_mday, .columns = 2); + sb_out = EMBED_CALL(verba_textus.put_clip, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = " "); + sb_out = EMBED_CALL(verba_numerus.u64_clip, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint64_t)(tmv.tm_year + 1900), .columns = 5); + sb_out = EMBED_CALL(verba_textus.put_clip, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = " "); + sb_out = EMBED_CALL(verba_textus.put_clip, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = name); + SftpV.n = EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out); } /** @brief The operands and the outcome. */ diff --git a/src/network_drivers/application/smb/ntlmssp/CMakeLists.txt b/src/network_drivers/application/smb/ntlmssp/CMakeLists.txt index ff83ffff4..d5fef0bb5 100644 --- a/src/network_drivers/application/smb/ntlmssp/CMakeLists.txt +++ b/src/network_drivers/application/smb/ntlmssp/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(network_drivers/application/smb/ntlmssp GATE PROTOCORE_ENABLE_SMB SOURCES ntlmssp.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/application/smb/ntlmssp/ntlmssp.c b/src/network_drivers/application/smb/ntlmssp/ntlmssp.c index 36d41048a..bbb9e8bc1 100644 --- a/src/network_drivers/application/smb/ntlmssp/ntlmssp.c +++ b/src/network_drivers/application/smb/ntlmssp/ntlmssp.c @@ -10,19 +10,19 @@ #if PROTOCORE_ENABLE_SMB -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/application/smb/ntlmssp/ntlmssp.h" -#include "mmgr/endian/endian.h" +#include "endian/endian.h" static const uint8_t NTLMSSP_SIG[8] = {'N', 'T', 'L', 'M', 'S', 'S', 'P', 0}; // Write a Len/MaxLen/BufferOffset field triplet at @p f. static void wr_field(uint8_t *f, uint16_t len, uint32_t off) { - endian.wr16le(f + 0, len); - endian.wr16le(f + 2, len); // MaxLen == Len - endian.wr32le(f + 4, off); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = f + 0, .val = len, .width = MMGR_ENDIAN_16); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = f + 2, .val = len, .width = MMGR_ENDIAN_16); // MaxLen == Len + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = f + 4, .val = off, .width = MMGR_ENDIAN_32); } // --- the entries ----------------------------------------------------------- @@ -38,12 +38,14 @@ size_t protocore_ntlmssp_build_negotiate(uint8_t *work, uint8_t *buf, size_t cap { return 0; } - mem.set(buf, 0, 32); - mem.cpy(buf + 0, NTLMSSP_SIG, 8); // Signature - endian.wr32le(buf + 8, 1); // MessageType = NEGOTIATE - endian.wr32le(buf + 12, flags); // NegotiateFlags - wr_field(buf + 16, 0, 32); // DomainNameFields (empty; offset = end of header) - wr_field(buf + 24, 0, 32); // WorkstationFields (empty) + EMBED_CALL(memor.set, MemoriaCfg, .dst = buf, .val = 0, .bytes = 32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 0, .src = NTLMSSP_SIG, .bytes = 8); // Signature + // MessageType = NEGOTIATE + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 8, .val = 1, .width = MMGR_ENDIAN_32); + // NegotiateFlags + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 12, .val = flags, .width = MMGR_ENDIAN_32); + wr_field(buf + 16, 0, 32); // DomainNameFields (empty; offset = end of header) + wr_field(buf + 24, 0, 32); // WorkstationFields (empty) return 32; } @@ -55,14 +57,15 @@ proto_bool protocore_ntlmssp_parse_challenge(uint8_t *work, const uint8_t *msg, { return PROTO_FALSE; } - if (mem.cmp(msg, NTLMSSP_SIG, 8) != 0 || endian.rd32le(msg + 8) != 2) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = msg, .other = NTLMSSP_SIG, .bytes = 8) != 0 || + (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = msg + 8, .width = MMGR_ENDIAN_32) != 2) { return PROTO_FALSE; } - out->flags = endian.rd32le(msg + 20); - mem.cpy(out->server_challenge, msg + 24, 8); - uint16_t ti_len = endian.rd16le(msg + 40); - uint32_t ti_off = endian.rd32le(msg + 44); + out->flags = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = msg + 20, .width = MMGR_ENDIAN_32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->server_challenge, .src = msg + 24, .bytes = 8); + uint16_t ti_len = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = msg + 40, .width = MMGR_ENDIAN_16); + uint32_t ti_off = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = msg + 44, .width = MMGR_ENDIAN_32); if (ti_len == 0) { out->target_info = NULL; @@ -128,17 +131,19 @@ size_t protocore_ntlmssp_build_authenticate(uint8_t *work, uint8_t *buf, size_t return 0; } - mem.set(buf, 0, HDR); - mem.cpy(buf + 0, NTLMSSP_SIG, 8); // Signature - endian.wr32le(buf + 8, 3); // MessageType = AUTHENTICATE + EMBED_CALL(memor.set, MemoriaCfg, .dst = buf, .val = 0, .bytes = HDR); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 0, .src = NTLMSSP_SIG, .bytes = 8); // Signature + // MessageType = AUTHENTICATE + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 8, .val = 3, .width = MMGR_ENDIAN_32); if (with_mic) { // Version (offset 64): a plausible Windows build; servers do not validate the value. MIC (offset // 72) stays zero here - the caller writes it after taking HMAC-MD5 over the three messages. - buf[64] = 6; // ProductMajorVersion - buf[65] = 1; // ProductMinorVersion - endian.wr16le(buf + 66, 7601); // ProductBuild - buf[71] = 15; // NTLMRevisionCurrent (NTLMSSP_REVISION_W2K3) + buf[64] = 6; // ProductMajorVersion + buf[65] = 1; // ProductMinorVersion + // ProductBuild + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 66, .val = 7601, .width = MMGR_ENDIAN_16); + buf[71] = 15; // NTLMRevisionCurrent (NTLMSSP_REVISION_W2K3) } // Lay out the payload after the fixed header, then point each field at it. @@ -146,13 +151,13 @@ size_t protocore_ntlmssp_build_authenticate(uint8_t *work, uint8_t *buf, size_t size_t lm_off = off; if (lm_resp && lm_len) { - mem.cpy(buf + off, lm_resp, lm_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + off, .src = lm_resp, .bytes = lm_len); } off += lm_len; size_t nt_off = off; if (nt_resp && nt_len) { - mem.cpy(buf + off, nt_resp, nt_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + off, .src = nt_resp, .bytes = nt_len); } off += nt_len; size_t dom_off = off; @@ -169,7 +174,8 @@ size_t protocore_ntlmssp_build_authenticate(uint8_t *work, uint8_t *buf, size_t wr_field(buf + 36, (uint16_t)ulen, (uint32_t)usr_off); // UserNameFields wr_field(buf + 44, (uint16_t)wlen, (uint32_t)wks_off); // WorkstationFields wr_field(buf + 52, 0, (uint32_t)key_off); // EncryptedRandomSessionKeyFields - endian.wr32le(buf + 60, flags); // NegotiateFlags + // NegotiateFlags + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 60, .val = flags, .width = MMGR_ENDIAN_32); return total; } diff --git a/src/network_drivers/application/smb/spnego/CMakeLists.txt b/src/network_drivers/application/smb/spnego/CMakeLists.txt index 4925973e6..02b47b354 100644 --- a/src/network_drivers/application/smb/spnego/CMakeLists.txt +++ b/src/network_drivers/application/smb/spnego/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(network_drivers/application/smb/spnego GATE PROTOCORE_ENABLE_SMB SOURCES spnego.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/application/smb/spnego/spnego.c b/src/network_drivers/application/smb/spnego/spnego.c index 0d93afe70..4b4b2ef01 100644 --- a/src/network_drivers/application/smb/spnego/spnego.c +++ b/src/network_drivers/application/smb/spnego/spnego.c @@ -11,7 +11,7 @@ #if PROTOCORE_ENABLE_SMB -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/application/smb/spnego/spnego.h" // OID TLVs (tag + length + content). @@ -118,17 +118,17 @@ size_t protocore_spnego_wrap_negotiate(uint8_t *work, const uint8_t *ntlm, size_ size_t p = 0; wr_tag_len(out, &p, 0x60, ictbody); - mem.cpy(out + p, SPNEGO_OID, sizeof(SPNEGO_OID)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + p, .src = SPNEGO_OID, .bytes = sizeof(SPNEGO_OID)); p += sizeof(SPNEGO_OID); wr_tag_len(out, &p, 0xa0, seq); // [0] negTokenInit wr_tag_len(out, &p, 0x30, mtypes + mt); // SEQUENCE wr_tag_len(out, &p, 0xa0, seqof); // [0] mechTypes wr_tag_len(out, &p, 0x30, sizeof(NTLM_OID)); // SEQUENCE OF - mem.cpy(out + p, NTLM_OID, sizeof(NTLM_OID)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + p, .src = NTLM_OID, .bytes = sizeof(NTLM_OID)); p += sizeof(NTLM_OID); wr_tag_len(out, &p, 0xa2, octet); // [2] mechToken wr_tag_len(out, &p, 0x04, protocore_ntlm_len); - mem.cpy(out + p, ntlm, protocore_ntlm_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + p, .src = ntlm, .bytes = protocore_ntlm_len); p += protocore_ntlm_len; return p; } @@ -156,7 +156,7 @@ size_t protocore_spnego_wrap_authenticate(uint8_t *work, const uint8_t *ntlm, si wr_tag_len(out, &p, 0x30, rt); // SEQUENCE wr_tag_len(out, &p, 0xa2, octet); // [2] responseToken wr_tag_len(out, &p, 0x04, protocore_ntlm_len); - mem.cpy(out + p, ntlm, protocore_ntlm_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + p, .src = ntlm, .bytes = protocore_ntlm_len); p += protocore_ntlm_len; return p; } diff --git a/src/network_drivers/datalink/roaming/CMakeLists.txt b/src/network_drivers/datalink/roaming/CMakeLists.txt index e63ad5c58..baf626be8 100644 --- a/src/network_drivers/datalink/roaming/CMakeLists.txt +++ b/src/network_drivers/datalink/roaming/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(network_drivers/datalink/roaming GATE PROTOCORE_ENABLE_ROAMING SOURCES roaming.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/datalink/roaming/roaming.c b/src/network_drivers/datalink/roaming/roaming.c index d3bf950ea..b2ff14669 100644 --- a/src/network_drivers/datalink/roaming/roaming.c +++ b/src/network_drivers/datalink/roaming/roaming.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_ROAMING -#include "mmgr/protomem/protomem.h" // mem.cmp / mem.cpy / mem.zero +#include "memoria_operor/memoria_operor.h" // memor.cmp / memor.cpy / memor.set #include "network_drivers/datalink/roaming/roaming.h" PROTOCORE_BEGIN_DECLS @@ -34,7 +34,7 @@ PROTOCORE_BEGIN_DECLS static proto_bool mac_eq(const uint8_t *a, const uint8_t *b) { - return mem.cmp(a, b, PROTOCORE_ROAM_BSSID_LEN) == 0; + return EMBED_CALL(memor.cmp, MemoriaCfg, .src = a, .other = b, .bytes = PROTOCORE_ROAM_BSSID_LEN) == 0; } // Index of the strongest candidate that is not the serving BSS, or -1 if there is none. @@ -75,7 +75,8 @@ static void pick(uint8_t *work, int idx, protocore_roam_reason reason) const protocore_roam_neighbor *nb = RoamV.cand.list; RoamV.decision.roam = PROTO_TRUE; - mem.cpy(RoamV.decision.target_bssid, nb[idx].bssid, PROTOCORE_ROAM_BSSID_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = RoamV.decision.target_bssid, .src = nb[idx].bssid, + .bytes = PROTOCORE_ROAM_BSSID_LEN); RoamV.decision.target_channel = nb[idx].channel; RoamV.decision.reason = reason; } @@ -90,7 +91,7 @@ void protocore_roam_decide(uint8_t *work) const protocore_roam_policy *policy = RoamV.rules.policy; RoamV.decision.roam = PROTO_FALSE; - mem.zero(RoamV.decision.target_bssid, PROTOCORE_ROAM_BSSID_LEN); + EMBED_CALL(memor.set, MemoriaCfg, .dst = RoamV.decision.target_bssid, .val = 0, .bytes = PROTOCORE_ROAM_BSSID_LEN); RoamV.decision.target_channel = 0; RoamV.decision.reason = PROTOCORE_ROAM_NONE; if (!serving || (n && !nb)) @@ -172,7 +173,7 @@ void protocore_roam_parse_neighbor_report(uint8_t *work) if (id == PROTOCORE_ROAM_NR_ELEM_ID && elen >= PROTOCORE_ROAM_NR_BODY_MIN) { const uint8_t *body = elems + off + 2; - mem.cpy(out[count].bssid, body, PROTOCORE_ROAM_BSSID_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out[count].bssid, .src = body, .bytes = PROTOCORE_ROAM_BSSID_LEN); out[count].channel = body[PROTOCORE_ROAM_NR_CHANNEL_OFF]; out[count].rssi_dbm = PROTOCORE_ROAM_RSSI_UNKNOWN; count++; @@ -189,7 +190,7 @@ void protocore_roam_parse_btm_request(uint8_t *work) protocore_roam_btm *out = &RoamV.hint; RoamV.ok = PROTO_FALSE; - mem.zero(out, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); if (!frame || len < PROTOCORE_ROAM_BTM_FIXED_LEN || frame[0] != PROTOCORE_ROAM_WNM_CATEGORY || frame[1] != PROTOCORE_ROAM_BTM_REQ_ACTION) { @@ -218,7 +219,8 @@ void protocore_roam_parse_btm_request(uint8_t *work) if ((mode & PROTOCORE_ROAM_BTM_PREF_LIST) && off + 2 + PROTOCORE_ROAM_BSSID_LEN <= len && frame[off] == PROTOCORE_ROAM_NR_ELEM_ID && frame[off + 1] >= PROTOCORE_ROAM_NR_BODY_MIN) { - mem.cpy(out->preferred_bssid, frame + off + 2, PROTOCORE_ROAM_BSSID_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->preferred_bssid, .src = frame + off + 2, + .bytes = PROTOCORE_ROAM_BSSID_LEN); out->has_preferred = PROTO_TRUE; } } diff --git a/src/network_drivers/network/dns/dns_wire/CMakeLists.txt b/src/network_drivers/network/dns/dns_wire/CMakeLists.txt index 249e3b72e..b61aa3a79 100644 --- a/src/network_drivers/network/dns/dns_wire/CMakeLists.txt +++ b/src/network_drivers/network/dns/dns_wire/CMakeLists.txt @@ -4,5 +4,5 @@ protocore_add_module(network_drivers/network/dns/dns_wire SOURCES dns_wire.c PRIVATE_DEPS - mmgr/rawmemcpy + mmgr ) diff --git a/src/network_drivers/network/dns/dns_wire/dns_wire.c b/src/network_drivers/network/dns/dns_wire/dns_wire.c index 58756e958..872e1fa4b 100644 --- a/src/network_drivers/network/dns/dns_wire/dns_wire.c +++ b/src/network_drivers/network/dns/dns_wire/dns_wire.c @@ -8,7 +8,7 @@ #include "network_drivers/network/dns/dns_wire/dns_wire.h" -#include "mmgr/rawmemcpy/rawmemcpy.h" // raw.read: the label octets move whole +#include "proximus_operor/proximus_operor.h" // proxim.read: the label octets move whole PROTOCORE_BEGIN_DECLS @@ -96,7 +96,7 @@ void protocore_dns_wire_decode(uint8_t *work) { return; } - raw.read(out + n, pkt + cur, b); + EMBED_CALL(proxim.read, ProximusCfg, .dst = out + n, .at = pkt + cur, .size = b); n += b; cur += b; } @@ -148,7 +148,7 @@ void protocore_dns_wire_encode(uint8_t *work) } out[w] = (uint8_t)label; w++; - raw.read(out + w, dotted + start, label); + EMBED_CALL(proxim.read, ProximusCfg, .dst = out + w, .at = dotted + start, .size = label); w += label; if (dotted[i] == '\0') { diff --git a/src/network_drivers/presentation/codec/CMakeLists.txt b/src/network_drivers/presentation/codec/CMakeLists.txt index 86d6df8f5..fbf14b05b 100644 --- a/src/network_drivers/presentation/codec/CMakeLists.txt +++ b/src/network_drivers/presentation/codec/CMakeLists.txt @@ -4,7 +4,7 @@ protocore_add_module(network_drivers/presentation/codec HEADER_ONLY DEPS - mmgr/span + mmgr ) add_subdirectory(base64) diff --git a/src/network_drivers/presentation/codec/base64/CMakeLists.txt b/src/network_drivers/presentation/codec/base64/CMakeLists.txt index 70dc23b1b..afd6b130b 100644 --- a/src/network_drivers/presentation/codec/base64/CMakeLists.txt +++ b/src/network_drivers/presentation/codec/base64/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(network_drivers/presentation/codec/base64 GATE PROTOCORE_ENABLE_BASE64 SOURCES base64.c PRIVATE_DEPS - mmgr/protostr - mmgr/swar + mmgr ) diff --git a/src/network_drivers/presentation/codec/base64/base64.c b/src/network_drivers/presentation/codec/base64/base64.c index c74f0ac8a..8841585f4 100644 --- a/src/network_drivers/presentation/codec/base64/base64.c +++ b/src/network_drivers/presentation/codec/base64/base64.c @@ -24,10 +24,9 @@ #include "base64.h" -#include "mmgr/protostr/protostr.h" // str: the bounded-run walks -#include "mmgr/swar/swar.h" // the lane math; the classification below is base64's own -#include "protocore_config.h" // PROTOCORE_BASE64_SWAR (scalar vs SWAR constant-time decode; default SWAR) - // strnlen +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len: the bounded-run walk +#include "protocore_config.h" // PROTOCORE_BASE64_SWAR (scalar vs SWAR constant-time decode; default SWAR) +#include "verbum_scrutor/verbum_scrutor.h" // the lane math; the classification below is base64's own PROTOCORE_BEGIN_DECLS @@ -132,31 +131,41 @@ static inline uint32_t ct_b64_val_plus1(uint32_t c, int urlsafe) #if PROTOCORE_BASE64_SWAR // --------------------------------------------------------------------------- // SWAR variant: classify 4 characters per 32-bit word instead of one at a time (opt-in, PROTOCORE_BASE64_SWAR). -// The lane math itself is mmgr/swar.h; what is base64's own is the classification below. +// The lane math itself is verbum_scrutor; what is base64's own is the classification below. // Every base64 character is < 0x80, so a byte lane never sets its own high bit, which is what lets the // guard-bit subtraction keep borrows inside their lane and the range masks stay data-independent - // same constant-time property as the scalar path, four lanes at once. Whether this actually wins is a HW // measurement, not an assumption (decode is once-per-request); see docs/FEATURE_PERFORMANCE.md. // --------------------------------------------------------------------------- -// A base64 quad is four characters by definition of the encoding, so this path wants exactly four -// lanes - it is the one caller of swar.h that cannot follow a retyped word width. -static_assert(PROTOCORE_SWAR_BYTES == 4, "base64 SWAR decodes one four-character quad per word"); +// A base64 quad is four characters by definition of the encoding, so this path wants at least four +// lanes. The quad rides in the low four; any lane above them holds zero, matches no range, and is +// dropped when the result is narrowed back to 32 bits. +static_assert(MMGR_SWAR_BYTES >= 4, "base64 SWAR decodes one four-character quad per word"); + +// The lanes of @p a in [@p lo, @p hi], widened to 0xFF per lane. +static inline embed_word swar_range(embed_word a, uint8_t lo, uint8_t hi) +{ + embed_word m = EMBED_CALL(lane.ge, ScrutLaneCfg, .word = a, .byte = lo) & + EMBED_CALL(lane.le, ScrutLaneCfg, .word = a, .byte = hi); + return EMBED_CALL(mask.spread, ScrutMaskCfg, .mask = m); +} // Decode 4 packed characters (c0 in the low byte) to 4 packed 6-bit values; *ok gets 0xFF in each valid lane. -static inline uint32_t swar_quad(uint32_t a, uint32_t *ok) +static inline uint32_t swar_quad(uint32_t quad, uint32_t *ok) { - uint32_t mAZ = swar.spread(swar.ge(a, 'A') & swar.le(a, 'Z')); - uint32_t maz = swar.spread(swar.ge(a, 'a') & swar.le(a, 'z')); - uint32_t m09 = swar.spread(swar.ge(a, '0') & swar.le(a, '9')); - uint32_t mpl = swar.spread(swar.ge(a, '+') & swar.le(a, '+')); - uint32_t msl = swar.spread(swar.ge(a, '/') & swar.le(a, '/')); - uint32_t val = (mAZ & (swar.sub7(a, 'A') + 0u * PROTOCORE_SWAR_ONES)) | - (maz & (swar.sub7(a, 'a') + 26u * PROTOCORE_SWAR_ONES)) | - (m09 & (swar.sub7(a, '0') + 52u * PROTOCORE_SWAR_ONES)) | (mpl & (62u * PROTOCORE_SWAR_ONES)) | - (msl & (63u * PROTOCORE_SWAR_ONES)); - *ok = mAZ | maz | m09 | mpl | msl; - return val; + const embed_word a = quad; + embed_word mAZ = swar_range(a, 'A', 'Z'); + embed_word maz = swar_range(a, 'a', 'z'); + embed_word m09 = swar_range(a, '0', '9'); + embed_word mpl = swar_range(a, '+', '+'); + embed_word msl = swar_range(a, '/', '/'); + embed_word val = (mAZ & (EMBED_CALL(lane.sub7, ScrutLaneCfg, .word = a, .byte = 'A') + 0u * MMGR_SWAR_ONES)) | + (maz & (EMBED_CALL(lane.sub7, ScrutLaneCfg, .word = a, .byte = 'a') + 26u * MMGR_SWAR_ONES)) | + (m09 & (EMBED_CALL(lane.sub7, ScrutLaneCfg, .word = a, .byte = '0') + 52u * MMGR_SWAR_ONES)) | + (mpl & (62u * MMGR_SWAR_ONES)) | (msl & (63u * MMGR_SWAR_ONES)); + *ok = (uint32_t)(mAZ | maz | m09 | mpl | msl); + return (uint32_t)val; } void protocore_base64_decode(uint8_t *work) @@ -166,7 +175,7 @@ void protocore_base64_decode(uint8_t *work) uint8_t *dst = Base64V.decode_args.dst; size_t dst_cap = Base64V.decode_args.dst_cap; - size_t src_len = str.len(src, ((dst_cap + 2) / 3) * 4 + 4); + size_t src_len = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = src, .cap = ((dst_cap + 2) / 3) * 4 + 4); if (src_len == 0 || (src_len & 3u) != 0) { Base64V.n = 0; @@ -242,7 +251,7 @@ void protocore_base64_decode(uint8_t *work) // Bounded length (a missing NUL cannot run past what dst_cap could ever hold). Canonical base64 is // whole 4-character quads. - size_t src_len = str.len(src, ((dst_cap + 2) / 3) * 4 + 4); + size_t src_len = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = src, .cap = ((dst_cap + 2) / 3) * 4 + 4); if (src_len == 0 || (src_len & 3u) != 0) { Base64V.n = 0; diff --git a/src/network_drivers/presentation/codec/cbor/cbor.h b/src/network_drivers/presentation/codec/cbor/cbor.h index 24d029319..2c1778416 100644 --- a/src/network_drivers/presentation/codec/cbor/cbor.h +++ b/src/network_drivers/presentation/codec/cbor/cbor.h @@ -11,8 +11,8 @@ * that many items (twice that for a map: key, value, key, value, ...). * * Overflow is tracked, not crashed on: writes past the buffer set the overflow - * flag and stop, while span.len() keeps counting the bytes the full payload would - * need, so a caller can size the buffer and check span.ok(). + * flag and stop, while the span's pos keeps counting the bytes the full payload would + * need, so a caller can size the buffer and check spat.ok(). * * @author Douglas Quigg (dstroy0) * @date 2026 @@ -21,7 +21,7 @@ #ifndef PROTOCORE_CBOR_H #define PROTOCORE_CBOR_H -#include "mmgr/span/span.h" // protocore_span / protocore_cspan - the region, bound with span.from() +#include "spatium/spatium.h" // mmgr_span / mmgr_cspan - the region, bound with spat.from() #include "network_drivers/presentation/codec/codec.h" // protocore_codec_type - one item vocabulary #include "protocore_config.h" @@ -30,10 +30,10 @@ PROTOCORE_BEGIN_DECLS #if PROTOCORE_ENABLE_CBOR -// The encoder writes into a protocore_span and the decoder reads from a protocore_cspan. There is no CBOR-specific -// cursor type: this codec declared one field-identical to protocore_span, MessagePack declared another, and -// the byte verbs were templated only to bind them by field name. Bind with span.from(buf, cap), -// check with span.ok(), and take the encoded length from span.len(). +// The encoder writes into a mmgr_span and the decoder reads from a mmgr_cspan. There is no CBOR-specific +// cursor type: this codec declared one field-identical to mmgr_span, MessagePack declared another, and +// the byte verbs were templated only to bind them by field name. Bind with spat.from(), +// check with spat.ok(), and take the encoded length from the span's pos. /** * @brief CBOR (RFC 8949) as an instance of the codec interface. diff --git a/src/network_drivers/presentation/codec/codec.h b/src/network_drivers/presentation/codec/codec.h index 37d538493..417331e5f 100644 --- a/src/network_drivers/presentation/codec/codec.h +++ b/src/network_drivers/presentation/codec/codec.h @@ -11,8 +11,9 @@ * * Dispatch is a `static const` table of function pointers in rodata. * - * The region types come from span.h and the byte verbs from bytes.h. A codec allocates nothing and - * owns no buffer: it writes into a protocore_span the caller bound and reads from a protocore_cspan. + * The region types come from spatium.h and the byte verbs from octetus_introitus_exitus.h. A codec + * allocates nothing and owns no buffer: it writes into a mmgr_span the caller bound and reads from a + * mmgr_cspan. * * @author Douglas Quigg (dstroy0) * @date 2026 @@ -21,7 +22,7 @@ #ifndef PROTOCORE_CODEC_H #define PROTOCORE_CODEC_H -#include "mmgr/span/span.h" +#include "spatium/spatium.h" #include "protocore_config.h" // PROTOCORE_ENABLE_CBOR / PROTOCORE_ENABLE_MSGPACK gate the instances below @@ -57,17 +58,17 @@ typedef enum PROTO_ENUM_PACKED */ typedef struct { - // --- encode into a caller-bound protocore_span --- - void (*put_uint)(protocore_span *w, uint64_t v); - void (*put_int)(protocore_span *w, int64_t v); - void (*put_bytes)(protocore_span *w, const uint8_t *data, size_t len); - void (*put_str)(protocore_span *w, const char *s); - void (*put_str_n)(protocore_span *w, const char *s, size_t len); - void (*put_bool)(protocore_span *w, proto_bool b); - void (*put_null)(protocore_span *w); - void (*put_float)(protocore_span *w, float f); - void (*put_array)(protocore_span *w, size_t count); - void (*put_map)(protocore_span *w, size_t count); + // --- encode into a caller-bound mmgr_span --- + void (*put_uint)(mmgr_span *w, uint64_t v); + void (*put_int)(mmgr_span *w, int64_t v); + void (*put_bytes)(mmgr_span *w, const uint8_t *data, size_t len); + void (*put_str)(mmgr_span *w, const char *s); + void (*put_str_n)(mmgr_span *w, const char *s, size_t len); + void (*put_bool)(mmgr_span *w, proto_bool b); + void (*put_null)(mmgr_span *w); + void (*put_float)(mmgr_span *w, float f); + void (*put_array)(mmgr_span *w, size_t count); + void (*put_map)(mmgr_span *w, size_t count); /** * @brief Emit a map key, given both spellings of it. @@ -77,19 +78,19 @@ typedef struct * caller hands over both and the format picks the one it is specified to write. Without this the * difference leaks upward and every producer keeps one walk per encoding. */ - void (*put_label)(protocore_span *w, const char *name, int64_t num); + void (*put_label)(mmgr_span *w, const char *name, int64_t num); - // --- decode from a caller-bound protocore_cspan --- - protocore_codec_type (*peek)(protocore_cspan *r); - proto_bool (*get_uint)(protocore_cspan *r, uint64_t *out); - proto_bool (*get_int)(protocore_cspan *r, int64_t *out); - proto_bool (*get_bytes)(protocore_cspan *r, const uint8_t **out, size_t *len); - proto_bool (*get_str)(protocore_cspan *r, const char **out, size_t *len); - proto_bool (*get_array)(protocore_cspan *r, size_t *count); - proto_bool (*get_map)(protocore_cspan *r, size_t *count); - proto_bool (*get_bool)(protocore_cspan *r, proto_bool *out); - proto_bool (*get_null)(protocore_cspan *r); - proto_bool (*get_float)(protocore_cspan *r, float *out); + // --- decode from a caller-bound mmgr_cspan --- + protocore_codec_type (*peek)(mmgr_cspan *r); + proto_bool (*get_uint)(mmgr_cspan *r, uint64_t *out); + proto_bool (*get_int)(mmgr_cspan *r, int64_t *out); + proto_bool (*get_bytes)(mmgr_cspan *r, const uint8_t **out, size_t *len); + proto_bool (*get_str)(mmgr_cspan *r, const char **out, size_t *len); + proto_bool (*get_array)(mmgr_cspan *r, size_t *count); + proto_bool (*get_map)(mmgr_cspan *r, size_t *count); + proto_bool (*get_bool)(mmgr_cspan *r, proto_bool *out); + proto_bool (*get_null)(mmgr_cspan *r); + proto_bool (*get_float)(mmgr_cspan *r, float *out); } protocore_codec; // Each format declares its own instance in its own header: cbor.h has Cbor, msgpack.h has diff --git a/src/network_drivers/presentation/codec/deflate/deflate/CMakeLists.txt b/src/network_drivers/presentation/codec/deflate/deflate/CMakeLists.txt index e5c0c1262..e8ad5a0fe 100644 --- a/src/network_drivers/presentation/codec/deflate/deflate/CMakeLists.txt +++ b/src/network_drivers/presentation/codec/deflate/deflate/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(network_drivers/presentation/codec/deflate/deflate GATE PROTOCORE_ENABLE_WS_DEFLATE SOURCES deflate.c PRIVATE_DEPS - mmgr/bitio - mmgr/protomem + mmgr network_drivers/presentation/codec/deflate/rfc1951 ) diff --git a/src/network_drivers/presentation/codec/deflate/deflate/deflate.c b/src/network_drivers/presentation/codec/deflate/deflate/deflate.c index 5d87dfd62..b81e02a1a 100644 --- a/src/network_drivers/presentation/codec/deflate/deflate/deflate.c +++ b/src/network_drivers/presentation/codec/deflate/deflate/deflate.c @@ -21,10 +21,10 @@ #if PROTOCORE_ENABLE_WS_DEFLATE -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/codec/deflate/deflate/deflate.h" -#include "mmgr/bitio/bitio.h" +#include "bitorum_introitus_exitus/bitorum_introitus_exitus.h" #include "network_drivers/presentation/codec/deflate/rfc1951/rfc1951.h" // RFC1951: the sec 3.2.5 tables #define PROTOCORE_MIN_MATCH 3 // shortest LZ77 back-reference @@ -79,18 +79,12 @@ DeflateResult protocore_deflate_raw(uint8_t *work, const uint8_t *src, size_t sr t->head[i] = PROTOCORE_NONE; } - protocore_bit_writer w; - w.out = dst; - w.cap = dst_cap; - w.cnt = 0; - w.acc = 0; - w.nbits = 0; - w.overflow = PROTO_FALSE; + mmgr_bitor w = EMBED_CALL(bitio.init, BitorumCfg, .out = dst, .cap = dst_cap); // One fixed-Huffman block, not final (permessage-deflate streams never set // BFINAL): BFINAL=0 (1 bit), BTYPE=01 (2 bits, value 1). - bitw.put(&w, 0, 1); - bitw.put(&w, 1, 2); + EMBED_CALL(bitio.put, BitorumCfg, .writer = &w, .val = 0, .bit_count = 1); + EMBED_CALL(bitio.put, BitorumCfg, .writer = &w, .val = 1, .bit_count = 2); size_t i = 0; while (i < src_len) @@ -178,26 +172,22 @@ DeflateResult protocore_deflate_raw(uint8_t *work, const uint8_t *src, size_t sr // End-of-block, then a sync flush: byte-align via an empty stored block and // drop its 0x00 0x00 0xff 0xff tail (RFC 7692 sec 7.2.1), leaving a ready // permessage-deflate payload. - bitw.put(&w, t->ll_code[256], t->ll_len[256]); // end-of-block symbol - bitw.put(&w, 0, 1); // BFINAL=0 (empty stored block) - bitw.put(&w, 0, 2); // BTYPE=00 (stored) - bitw.align(&w); + // end-of-block symbol + EMBED_CALL(bitio.put, BitorumCfg, .writer = &w, .val = t->ll_code[256], .bit_count = t->ll_len[256]); + EMBED_CALL(bitio.put, BitorumCfg, .writer = &w, .val = 0, .bit_count = 1); // BFINAL=0 (empty stored block) + EMBED_CALL(bitio.put, BitorumCfg, .writer = &w, .val = 0, .bit_count = 2); // BTYPE=00 (stored) + EMBED_CALL(bitio.align, BitorumCfg, .writer = &w); static const uint8_t marker[4] = {0x00, 0x00, 0xff, 0xff}; for (int k = 0; k < 4; k++) { - if (w.cnt >= w.cap) - { - w.overflow = PROTO_TRUE; - break; - } - w.out[w.cnt++] = marker[k]; + EMBED_CALL(bitio.put, BitorumCfg, .writer = &w, .val = marker[k], .bit_count = 8); } if (w.overflow) { return DEFLATE_ERR_OVERFLOW; } - *out_len = w.cnt - 4; // strip the marker for the on-wire payload + *out_len = w.bytes_written - 4; // strip the marker for the on-wire payload return DEFLATE_OK; } diff --git a/src/network_drivers/presentation/codec/deflate/rfc1951/CMakeLists.txt b/src/network_drivers/presentation/codec/deflate/rfc1951/CMakeLists.txt index bdeda1648..6670ef867 100644 --- a/src/network_drivers/presentation/codec/deflate/rfc1951/CMakeLists.txt +++ b/src/network_drivers/presentation/codec/deflate/rfc1951/CMakeLists.txt @@ -5,7 +5,5 @@ protocore_add_module(network_drivers/presentation/codec/deflate/rfc1951 GATE PROTOCORE_ENABLE_DEFLATE_RFC1951 SOURCES rfc1951.c DEPS - mmgr/bitio - PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/presentation/codec/deflate/rfc1951/rfc1951.c b/src/network_drivers/presentation/codec/deflate/rfc1951/rfc1951.c index 2f10cb41f..f65dd4163 100644 --- a/src/network_drivers/presentation/codec/deflate/rfc1951/rfc1951.c +++ b/src/network_drivers/presentation/codec/deflate/rfc1951/rfc1951.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_DEFLATE_RFC1951 -#include "mmgr/protomem/protomem.h" // mem.set: build_fixed zeroes its bit-length counts +#include "memoria_operor/memoria_operor.h" // memor.set: build_fixed zeroes its bit-length counts #include "network_drivers/presentation/codec/deflate/rfc1951/rfc1951.h" PROTOCORE_BEGIN_DECLS @@ -82,7 +82,7 @@ void protocore_rfc1951_build_fixed(uint8_t *work) // Canonical code assignment (RFC 1951 sec 3.2.2) for the lit/length alphabet. uint16_t bl_count[16]; - mem.set(bl_count, 0, sizeof(bl_count)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = bl_count, .val = 0, .bytes = sizeof(bl_count)); for (sym = 0; sym < 288; sym++) { bl_count[ll_len[sym]]++; @@ -119,19 +119,19 @@ void protocore_rfc1951_build_fixed(uint8_t *work) void protocore_rfc1951_emit_literal(uint8_t *work) { (void)work; - protocore_bit_writer *w = Rfc1951V.emit_literal_args.w; + mmgr_bitor *w = Rfc1951V.emit_literal_args.w; const uint16_t *ll_code = Rfc1951V.emit_literal_args.ll_code; const uint8_t *ll_len = Rfc1951V.emit_literal_args.ll_len; uint8_t b = Rfc1951V.emit_literal_args.b; - bitw.put(w, ll_code[b], ll_len[b]); + EMBED_CALL(bitio.put, BitorumCfg, .writer = w, .val = ll_code[b], .bit_count = ll_len[b]); } // A (len, dist) back-reference through the fixed code tables (RFC 1951 sec 3.2.5). void protocore_rfc1951_emit_match(uint8_t *work) { (void)work; - protocore_bit_writer *w = Rfc1951V.emit_match_args.w; + mmgr_bitor *w = Rfc1951V.emit_match_args.w; const uint16_t *ll_code = Rfc1951V.emit_match_args.ll_code; const uint8_t *ll_len = Rfc1951V.emit_match_args.ll_len; const uint16_t *d_code = Rfc1951V.emit_match_args.d_code; @@ -145,10 +145,11 @@ void protocore_rfc1951_emit_match(uint8_t *work) li++; } int lsym = 257 + li; - bitw.put(w, ll_code[lsym], ll_len[lsym]); + EMBED_CALL(bitio.put, BitorumCfg, .writer = w, .val = ll_code[lsym], .bit_count = ll_len[lsym]); if (len_extra[li]) { - bitw.put(w, (uint32_t)(len - len_base[li]), len_extra[li]); + EMBED_CALL(bitio.put, BitorumCfg, .writer = w, .val = (uint32_t)(len - len_base[li]), + .bit_count = len_extra[li]); } int di = 0; @@ -156,10 +157,11 @@ void protocore_rfc1951_emit_match(uint8_t *work) { di++; } - bitw.put(w, d_code[di], d_len[di]); + EMBED_CALL(bitio.put, BitorumCfg, .writer = w, .val = d_code[di], .bit_count = d_len[di]); if (dist_extra[di]) { - bitw.put(w, (uint32_t)(dist - dist_base[di]), dist_extra[di]); + EMBED_CALL(bitio.put, BitorumCfg, .writer = w, .val = (uint32_t)(dist - dist_base[di]), + .bit_count = dist_extra[di]); } } diff --git a/src/network_drivers/presentation/codec/deflate/rfc1951/rfc1951.h b/src/network_drivers/presentation/codec/deflate/rfc1951/rfc1951.h index 20e636157..774d82d72 100644 --- a/src/network_drivers/presentation/codec/deflate/rfc1951/rfc1951.h +++ b/src/network_drivers/presentation/codec/deflate/rfc1951/rfc1951.h @@ -20,7 +20,7 @@ #if PROTOCORE_ENABLE_DEFLATE_RFC1951 -#include "mmgr/bitio/bitio.h" // protocore_bit_writer - what the emitters write through +#include "bitorum_introitus_exitus/bitorum_introitus_exitus.h" // mmgr_bitor - what the emitters write through PROTOCORE_BEGIN_DECLS @@ -47,7 +47,7 @@ typedef struct /** @brief What emit_literal takes: the writer, the lit/length code tables, and the byte. */ typedef struct { - protocore_bit_writer *w; ///< the bit writer the code goes out through + mmgr_bitor *w; ///< the bit writer the code goes out through const uint16_t *ll_code; ///< 288 entries, from build_fixed const uint8_t *ll_len; ///< 288 entries, from build_fixed uint8_t b; ///< the literal byte @@ -56,7 +56,7 @@ typedef struct /** @brief What emit_match takes: the writer, all four code tables, and the back-reference. */ typedef struct { - protocore_bit_writer *w; ///< the bit writer the codes go out through + mmgr_bitor *w; ///< the bit writer the codes go out through const uint16_t *ll_code; ///< 288 entries, from build_fixed const uint8_t *ll_len; ///< 288 entries, from build_fixed const uint16_t *d_code; ///< 30 entries, from build_fixed diff --git a/src/network_drivers/presentation/codec/hpack_prim/CMakeLists.txt b/src/network_drivers/presentation/codec/hpack_prim/CMakeLists.txt index 5c25f8ef0..c77c99058 100644 --- a/src/network_drivers/presentation/codec/hpack_prim/CMakeLists.txt +++ b/src/network_drivers/presentation/codec/hpack_prim/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(network_drivers/presentation/codec/hpack_prim GATE PROTOCORE_ENABLE_HPACK_PRIM SOURCES hpack_prim.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/presentation/codec/hpack_prim/hpack_prim.c b/src/network_drivers/presentation/codec/hpack_prim/hpack_prim.c index 25dbb7a0c..8a1a6b27a 100644 --- a/src/network_drivers/presentation/codec/hpack_prim/hpack_prim.c +++ b/src/network_drivers/presentation/codec/hpack_prim/hpack_prim.c @@ -13,7 +13,7 @@ #if PROTOCORE_ENABLE_HPACK_PRIM -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/codec/hpack_prim/hpack_prim.h" // --- Huffman tables generated from RFC 7541 Appendix B --------------------------------------- @@ -320,7 +320,7 @@ proto_bool protocore_hpack_prim_decode_str(uint8_t *work, const uint8_t *block, { return PROTO_FALSE; } - mem.cpy(out, block + *pos, slen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = block + *pos, .bytes = slen); *out_len = slen; } *pos += slen; @@ -353,7 +353,7 @@ size_t protocore_hpack_prim_encode_str(uint8_t *work, uint8_t *out, size_t cap, { return 0; } - mem.cpy(out + hdr, s, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + hdr, .src = s, .bytes = n); return hdr + n; } diff --git a/src/network_drivers/presentation/codec/inflate/CMakeLists.txt b/src/network_drivers/presentation/codec/inflate/CMakeLists.txt index a49659399..a74a70b4e 100644 --- a/src/network_drivers/presentation/codec/inflate/CMakeLists.txt +++ b/src/network_drivers/presentation/codec/inflate/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(network_drivers/presentation/codec/inflate GATE PROTOCORE_ENABLE_WS_DEFLATE SOURCES inflate.c PRIVATE_DEPS - mmgr/protomem + mmgr network_drivers/presentation/codec/deflate/rfc1951 ) diff --git a/src/network_drivers/presentation/codec/inflate/inflate.c b/src/network_drivers/presentation/codec/inflate/inflate.c index eeadc04e1..3680cb181 100644 --- a/src/network_drivers/presentation/codec/inflate/inflate.c +++ b/src/network_drivers/presentation/codec/inflate/inflate.c @@ -17,7 +17,7 @@ #if PROTOCORE_ENABLE_WS_DEFLATE #include "inflate.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/codec/deflate/rfc1951/rfc1951.h" // RFC1951: the sec 3.2.5 tables PROTOCORE_BEGIN_DECLS @@ -235,7 +235,7 @@ static InflateResult stored(State *s) { return INFLATE_ERR_OVERFLOW; } - mem.cpy(s->out + s->outcnt, s->in + s->incnt, (size_t)len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = s->out + s->outcnt, .src = s->in + s->incnt, .bytes = (size_t)len); s->incnt += (size_t)len; s->outcnt += (size_t)len; return INFLATE_OK; diff --git a/src/network_drivers/presentation/codec/json/CMakeLists.txt b/src/network_drivers/presentation/codec/json/CMakeLists.txt index fcdfef6b2..e8899b7c5 100644 --- a/src/network_drivers/presentation/codec/json/CMakeLists.txt +++ b/src/network_drivers/presentation/codec/json/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(network_drivers/presentation/codec/json GATE PROTOCORE_ENABLE_JSON SOURCES json.c PRIVATE_DEPS - mmgr/membuild - mmgr/protostr + mmgr shared/hex ) diff --git a/src/network_drivers/presentation/codec/json/json.c b/src/network_drivers/presentation/codec/json/json.c index a668077e3..b6c036020 100644 --- a/src/network_drivers/presentation/codec/json/json.c +++ b/src/network_drivers/presentation/codec/json/json.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_JSON +#include "cellularum_laboro/cellularum_laboro.h" #include "json.h" -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protostr/protostr.h" -#include "shared/hex/hex.h" // PROTOCORE_HEX: the shared digit tables +#include "shared/hex/hex.h" // PROTOCORE_HEX: the shared digit tables +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -255,9 +255,10 @@ void protocore_json_put_int(uint8_t *work) long v = JsonV.put_int_args.v; char tmp[24]; - protocore_sb sb_tmp = {tmp, sizeof(tmp), 0, PROTO_TRUE}; - Sb.i64(&sb_tmp, (int64_t)(v)); - if (Sb.finish(&sb_tmp) == 0) + size_t sb_tmp = 0; + sb_tmp = EMBED_CALL(verba_numerus.i64, VerbaNumerusCfg, .out = tmp, .cap = sizeof(tmp), .at = sb_tmp, + .sval = (int64_t)(v)); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = tmp, .cap = sizeof(tmp), .at = sb_tmp) == 0) { tmp[0] = '\0'; } @@ -272,9 +273,10 @@ void protocore_json_put_uint(uint8_t *work) unsigned long v = JsonV.put_uint_args.v; char tmp[24]; - protocore_sb sb_tmp2 = {tmp, sizeof(tmp), 0, PROTO_TRUE}; - Sb.u32(&sb_tmp2, (uint32_t)(v)); - if (Sb.finish(&sb_tmp2) == 0) + size_t sb_tmp2 = 0; + sb_tmp2 = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = tmp, .cap = sizeof(tmp), .at = sb_tmp2, + .val = (uint32_t)(v)); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = tmp, .cap = sizeof(tmp), .at = sb_tmp2) == 0) { tmp[0] = '\0'; } @@ -486,7 +488,7 @@ static const char *json_find_value(const char *json, const char *key) } p++; // into the object - size_t keylen = str.len(key, JSON_KEY_MAX); + size_t keylen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = key, .cap = JSON_KEY_MAX); while (PROTO_TRUE) { p = skip_ws(p); @@ -502,7 +504,8 @@ static const char *json_find_value(const char *json, const char *key) const char *kstart = p + 1; const char *kend = skip_string(p); // just past closing quote size_t klen = (kend > kstart) ? (size_t)((kend - 1) - kstart) : 0; - proto_bool match = (klen == keylen) && (str.diff(kstart, key, klen, PROTO_FALSE) == klen); + proto_bool match = (klen == keylen) && (EMBED_CALL(cellul.diff, CatenaFinitaCfg, .src = kstart, .other = key, + .cap = klen, .ci = PROTO_FALSE) == klen); p = skip_ws(kend); if (*p != ':') @@ -770,7 +773,7 @@ void protocore_json_get_int(uint8_t *work) return; } const char *end = NULL; - long val = str.to_long(v, &end); + long val = EMBED_CALL(cellul.to_long, TransfiguroCfg, .src = v, .end = &end); if (end == v) { JsonV.ok = PROTO_FALSE; // no digits parsed @@ -798,14 +801,14 @@ void protocore_json_get_bool(uint8_t *work) JsonV.ok = PROTO_FALSE; return; } - if (str.starts(v, "true", 4, PROTO_FALSE) && + if (EMBED_CALL(cellul.starts, CatenaFinitaCfg, .src = v, .other = "true", .cap = 4, .ci = PROTO_FALSE) && (v[4] == '\0' || v[4] == ',' || v[4] == '}' || v[4] == ']' || is_ws(v[4]))) { *out = PROTO_TRUE; JsonV.ok = PROTO_TRUE; return; } - if (str.starts(v, "false", 5, PROTO_FALSE) && + if (EMBED_CALL(cellul.starts, CatenaFinitaCfg, .src = v, .other = "false", .cap = 5, .ci = PROTO_FALSE) && (v[5] == '\0' || v[5] == ',' || v[5] == '}' || v[5] == ']' || is_ws(v[5]))) { *out = PROTO_FALSE; diff --git a/src/network_drivers/presentation/codec/msgpack/CMakeLists.txt b/src/network_drivers/presentation/codec/msgpack/CMakeLists.txt index 8e3128674..1f2f96c76 100644 --- a/src/network_drivers/presentation/codec/msgpack/CMakeLists.txt +++ b/src/network_drivers/presentation/codec/msgpack/CMakeLists.txt @@ -5,10 +5,6 @@ protocore_add_module(network_drivers/presentation/codec/msgpack GATE PROTOCORE_ENABLE_MSGPACK SOURCES msgpack.c DEPS - mmgr/span + mmgr network_drivers/presentation/codec - PRIVATE_DEPS - mmgr/bytes - mmgr/protomem - mmgr/protostr ) diff --git a/src/network_drivers/presentation/codec/msgpack/msgpack.c b/src/network_drivers/presentation/codec/msgpack/msgpack.c index d4fdbcf93..5edb5311f 100644 --- a/src/network_drivers/presentation/codec/msgpack/msgpack.c +++ b/src/network_drivers/presentation/codec/msgpack/msgpack.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_MSGPACK -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "msgpack.h" #include "mmgr/bytes/bytes.h" @@ -121,7 +121,7 @@ static void protocore_msgpack_str_n(protocore_span *w, const char *s, size_t len static void protocore_msgpack_str(protocore_span *w, const char *s) { - protocore_msgpack_str_n(w, s, s ? str.len(s, w->cap + 1) : 0); + protocore_msgpack_str_n(w, s, s ? EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = w->cap + 1) : 0); } static void protocore_msgpack_bytes(protocore_span *w, const uint8_t *data, size_t len) @@ -160,7 +160,7 @@ static void protocore_msgpack_null(protocore_span *w) static void protocore_msgpack_float(protocore_span *w, float f) { uint32_t bits; - mem.cpy(&bits, &f, sizeof(bits)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &bits, .src = &f, .bytes = sizeof(bits)); put(w, 0xca); // float32 put_be(w, bits, 4); } @@ -477,7 +477,7 @@ static proto_bool protocore_msgpack_read_float(protocore_cspan *r, float *out) return PROTO_FALSE; } uint32_t bits = (uint32_t)v; - mem.cpy(out, &bits, sizeof(*out)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = &bits, .bytes = sizeof(*out)); return PROTO_TRUE; } if (b == 0xcb) // float64 -> narrow to float @@ -487,7 +487,7 @@ static proto_bool protocore_msgpack_read_float(protocore_cspan *r, float *out) return PROTO_FALSE; } double d; - mem.cpy(&d, &v, sizeof(d)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &d, .src = &v, .bytes = sizeof(d)); *out = (float)d; return PROTO_TRUE; } diff --git a/src/network_drivers/presentation/codec/msgpack/msgpack.h b/src/network_drivers/presentation/codec/msgpack/msgpack.h index ca41e8dc7..bace6506f 100644 --- a/src/network_drivers/presentation/codec/msgpack/msgpack.h +++ b/src/network_drivers/presentation/codec/msgpack/msgpack.h @@ -13,13 +13,13 @@ * that for a map: key, value, key, value, ...). * * Overflow is tracked, not crashed on: writes past the buffer set the span's overflow - * flag and stop, while span.len() keeps counting the bytes the full payload - * would need, so a caller can size the buffer and check span.ok(). + * flag and stop, while the span's pos keeps counting the bytes the full payload + * would need, so a caller can size the buffer and check spat.ok(). * * The decoder is a cursor: MsgPack.peek() reports the next object's type and the * MsgPack.get_* calls consume it (strings and binary point into the source buffer, * no copy). Any malformed or out-of-bounds read sets a sticky error - check - * span.cok(). ext and the unused 0xc1 byte are reported as INVALID. + * spat.cok(). ext and the unused 0xc1 byte are reported as INVALID. * * @author Douglas Quigg (dstroy0) * @date 2026 @@ -32,13 +32,13 @@ #if PROTOCORE_ENABLE_MSGPACK -#include "mmgr/span/span.h" // protocore_span / protocore_cspan - the region, bound with span.from() #include "network_drivers/presentation/codec/codec.h" // protocore_codec_type - one item vocabulary +#include "spatium/spatium.h" // mmgr_span / mmgr_cspan - the region, bound with spat.from() PROTOCORE_BEGIN_DECLS -// The encoder writes into a protocore_span and the decoder reads from a protocore_cspan. Bind with -// span.from(buf, cap), check with span.ok(), and take the encoded length from span.len(). +// The encoder writes into a mmgr_span and the decoder reads from a mmgr_cspan. Bind with +// spat.from(), check with spat.ok(), and take the encoded length from the span's pos. /** * @brief MessagePack as an instance of the codec interface. diff --git a/src/network_drivers/presentation/http/http2/h2_conn/h2_conn.c b/src/network_drivers/presentation/http/http2/h2_conn/h2_conn.c index 6cd6bee82..45e2af38a 100644 --- a/src/network_drivers/presentation/http/http2/h2_conn/h2_conn.c +++ b/src/network_drivers/presentation/http/http2/h2_conn/h2_conn.c @@ -662,8 +662,10 @@ static proto_bool dispatch_frame(uint8_t *work, H2FrameHeader h, const uint8_t * static proto_bool process_frame(uint8_t *work) { H2FrameHeader h; - (H2FrameV.parse_args.buf = H2_CONN_FHDR(work), H2FrameV.parse_args.len = H2_FRAME_HEADER_LEN, - H2Frame.parse_header(work), *(&h) = H2FrameV.header, H2FrameV.ok); + H2FrameV.parse_args.buf = H2_CONN_FHDR(work); + H2FrameV.parse_args.len = H2_FRAME_HEADER_LEN; + H2Frame.parse_header(work); + h = H2FrameV.header; const uint8_t *payload = H2_CONN_FBUF(work); // A header block must be continued only by CONTINUATION on the same stream (sec 6.10). diff --git a/src/network_drivers/presentation/http/http2/h2_frame/CMakeLists.txt b/src/network_drivers/presentation/http/http2/h2_frame/CMakeLists.txt index f1bf727b1..716bd516d 100644 --- a/src/network_drivers/presentation/http/http2/h2_frame/CMakeLists.txt +++ b/src/network_drivers/presentation/http/http2/h2_frame/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(network_drivers/presentation/http/http2/h2_frame GATE PROTOCORE_ENABLE_HTTP2 SOURCES h2_frame.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/presentation/http/http2/h2_frame/h2_frame.c b/src/network_drivers/presentation/http/http2/h2_frame/h2_frame.c index 4ccaa4a50..b1b23cc69 100644 --- a/src/network_drivers/presentation/http/http2/h2_frame/h2_frame.c +++ b/src/network_drivers/presentation/http/http2/h2_frame/h2_frame.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_HTTP2 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/http/http2/h2_frame/h2_frame.h" PROTOCORE_BEGIN_DECLS @@ -184,7 +184,7 @@ static size_t h2_build_ping_ack_run(uint8_t *out, size_t cap, const uint8_t opaq return 0; } h2_write_header_run(out, cap, 8, H2_PING, H2_FLAG_ACK, 0); - mem.cpy(out + H2_FRAME_HEADER_LEN, opaque, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + H2_FRAME_HEADER_LEN, .src = opaque, .bytes = 8); return H2_FRAME_HEADER_LEN + 8; } @@ -197,7 +197,7 @@ static size_t h2_build_headers_run(uint8_t *out, size_t cap, uint32_t stream_id, } uint8_t flags = H2_FLAG_END_HEADERS | (end_stream ? H2_FLAG_END_STREAM : 0); h2_write_header_run(out, cap, (uint32_t)block_len, H2_HEADERS, flags, stream_id); - mem.cpy(out + H2_FRAME_HEADER_LEN, block, block_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + H2_FRAME_HEADER_LEN, .src = block, .bytes = block_len); return H2_FRAME_HEADER_LEN + block_len; } @@ -211,7 +211,7 @@ static size_t h2_build_data_run(uint8_t *out, size_t cap, uint32_t stream_id, co h2_write_header_run(out, cap, (uint32_t)data_len, H2_DATA, end_stream ? H2_FLAG_END_STREAM : 0, stream_id); if (data_len) { - mem.cpy(out + H2_FRAME_HEADER_LEN, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + H2_FRAME_HEADER_LEN, .src = data, .bytes = data_len); } return H2_FRAME_HEADER_LEN + data_len; } diff --git a/src/network_drivers/presentation/http/http2/hpack/CMakeLists.txt b/src/network_drivers/presentation/http/http2/hpack/CMakeLists.txt index 05845c71f..4c1813e79 100644 --- a/src/network_drivers/presentation/http/http2/hpack/CMakeLists.txt +++ b/src/network_drivers/presentation/http/http2/hpack/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(network_drivers/presentation/http/http2/hpack GATE PROTOCORE_ENABLE_HTTP2 SOURCES hpack.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr network_drivers/presentation/codec/hpack_prim ) diff --git a/src/network_drivers/presentation/http/http2/hpack/hpack.c b/src/network_drivers/presentation/http/http2/hpack/hpack.c index c57790632..bf8d75df5 100644 --- a/src/network_drivers/presentation/http/http2/hpack/hpack.c +++ b/src/network_drivers/presentation/http/http2/hpack/hpack.c @@ -14,8 +14,8 @@ #if PROTOCORE_ENABLE_HTTP2 -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/codec/hpack_prim/hpack_prim.h" // shared prefix-int + Huffman #include "network_drivers/presentation/http/http2/hpack/hpack.h" @@ -53,8 +53,8 @@ static_assert(HPACK_OFF_CTX + sizeof(HpackDynTable) <= PROTOCORE_HPACK_BORROW, "PROTOCORE_HPACK_BORROW is short of the dynamic table - raise it in protocore_config.h," " which sums it into the connection that owns it"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(HPACK_OFF_CTX % _Alignof(HpackDynTable) == 0, @@ -234,12 +234,12 @@ static proto_bool resolve_name(const HpackDynTable *t, uint32_t idx, char *out, { if (idx >= 1 && idx <= 61) { - size_t nl = str.len(STATIC[idx][0], cap + 1); + size_t nl = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = STATIC[idx][0], .cap = cap + 1); if (nl > cap) { return PROTO_FALSE; } - mem.cpy(out, STATIC[idx][0], nl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = STATIC[idx][0], .bytes = nl); *out_len = nl; return PROTO_TRUE; } @@ -262,14 +262,14 @@ static proto_bool emit_indexed(HpackDynTable *t, uint32_t idx, char *scratch, si size_t vl; if (idx >= 1 && idx <= 61) { - nl = str.len(STATIC[idx][0], cap + 1); - vl = str.len(STATIC[idx][1], cap + 1); + nl = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = STATIC[idx][0], .cap = cap + 1); + vl = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = STATIC[idx][1], .cap = cap + 1); if (nl + vl > cap) { return PROTO_FALSE; } - mem.cpy(scratch, STATIC[idx][0], nl); - mem.cpy(scratch + nl, STATIC[idx][1], vl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = scratch, .src = STATIC[idx][0], .bytes = nl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = scratch + nl, .src = STATIC[idx][1], .bytes = vl); } else { @@ -334,7 +334,7 @@ static proto_bool decode_literal(uint8_t *work, HpackDynTable *t, const uint8_t static void hpack_dyn_init_run(HpackDynTable *t, uint32_t max_bytes) { - mem.set(t, 0, sizeof(*t)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = t, .val = 0, .bytes = sizeof(*t)); t->max_size = max_bytes ? max_bytes : (uint32_t)HPACK_BYTES; if (t->max_size > HPACK_BYTES) { @@ -409,13 +409,15 @@ static size_t hpack_encode_header_run(uint8_t *work, uint8_t *out, size_t cap, c int full_idx = 0; for (int i = 1; i <= 61; i++) { - if (str.len(STATIC[i][0], name_len + 1) == name_len && mem.cmp(STATIC[i][0], name, name_len) == 0) + if (EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = STATIC[i][0], .cap = name_len + 1) == name_len && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = STATIC[i][0], .other = name, .bytes = name_len) == 0) { if (!name_idx) { name_idx = i; } - if (str.len(STATIC[i][1], value_len + 1) == value_len && mem.cmp(STATIC[i][1], value, value_len) == 0) + if (EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = STATIC[i][1], .cap = value_len + 1) == value_len && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = STATIC[i][1], .other = value, .bytes = value_len) == 0) { full_idx = i; break; diff --git a/src/network_drivers/presentation/http/http3/h3_frame/CMakeLists.txt b/src/network_drivers/presentation/http/http3/h3_frame/CMakeLists.txt index 41a2fa375..f10fb78e1 100644 --- a/src/network_drivers/presentation/http/http3/h3_frame/CMakeLists.txt +++ b/src/network_drivers/presentation/http/http3/h3_frame/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(network_drivers/presentation/http/http3/h3_frame GATE PROTOCORE_ENABLE_HTTP3 SOURCES h3_frame.c PRIVATE_DEPS - mmgr/protomem + mmgr network_drivers/presentation/http/http3/quic_varint ) diff --git a/src/network_drivers/presentation/http/http3/h3_frame/h3_frame.c b/src/network_drivers/presentation/http/http3/h3_frame/h3_frame.c index 6642ef424..5b12f23c3 100644 --- a/src/network_drivers/presentation/http/http3/h3_frame/h3_frame.c +++ b/src/network_drivers/presentation/http/http3/h3_frame/h3_frame.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_HTTP3 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/http/http3/h3_frame/h3_frame.h" #include "network_drivers/presentation/http/http3/quic_varint/quic_varint.h" @@ -133,7 +133,7 @@ size_t protocore_h3_frame_build_data(uint8_t *work, uint8_t *out, size_t cap, co } if (len) { - mem.cpy(out + hn, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + hn, .src = data, .bytes = len); } return hn + len; } @@ -148,7 +148,7 @@ size_t protocore_h3_frame_build_headers(uint8_t *work, uint8_t *out, size_t cap, } if (len) { - mem.cpy(out + hn, block, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + hn, .src = block, .bytes = len); } return hn + len; } diff --git a/src/network_drivers/presentation/http/http3/qpack/CMakeLists.txt b/src/network_drivers/presentation/http/http3/qpack/CMakeLists.txt index f68684acd..7cf260180 100644 --- a/src/network_drivers/presentation/http/http3/qpack/CMakeLists.txt +++ b/src/network_drivers/presentation/http/http3/qpack/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(network_drivers/presentation/http/http3/qpack GATE PROTOCORE_ENABLE_HTTP3 SOURCES qpack.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr network_drivers/presentation/codec/hpack_prim ) diff --git a/src/network_drivers/presentation/http/http3/qpack/qpack.c b/src/network_drivers/presentation/http/http3/qpack/qpack.c index 4fa5713ee..1e5a2b9db 100644 --- a/src/network_drivers/presentation/http/http3/qpack/qpack.c +++ b/src/network_drivers/presentation/http/http3/qpack/qpack.c @@ -14,8 +14,8 @@ #if PROTOCORE_ENABLE_HTTP3 -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/codec/hpack_prim/hpack_prim.h" // shared prefix-int + Huffman #include "network_drivers/presentation/http/http3/qpack/qpack.h" @@ -148,14 +148,15 @@ size_t protocore_qpack_encode_header(uint8_t *work, uint8_t *out, size_t cap, co int name_idx = -1, full_idx = -1; for (int i = 0; i < 99; i++) { - if (str.len(QPACK_STATIC[i][0], name_len + 1) == name_len && mem.cmp(QPACK_STATIC[i][0], name, name_len) == 0) + if (EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = QPACK_STATIC[i][0], .cap = name_len + 1) == name_len && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = QPACK_STATIC[i][0], .other = name, .bytes = name_len) == 0) { if (name_idx < 0) { name_idx = i; } - if (str.len(QPACK_STATIC[i][1], value_len + 1) == value_len && - mem.cmp(QPACK_STATIC[i][1], value, value_len) == 0) + if (EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = QPACK_STATIC[i][1], .cap = value_len + 1) == value_len && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = QPACK_STATIC[i][1], .other = value, .bytes = value_len) == 0) { full_idx = i; break; @@ -213,7 +214,7 @@ size_t protocore_qpack_encode_header(uint8_t *work, uint8_t *out, size_t cap, co { return 0; } - mem.cpy(out + o, name, name_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + o, .src = name, .bytes = name_len); o += name_len; } size_t hpack_prim_n5 = HpackPrim.encode_str(work, out + o, cap - o, value, value_len); @@ -268,7 +269,8 @@ proto_bool protocore_qpack_decode(uint8_t *work, const uint8_t *block, size_t le pos += c; const char *nm = QPACK_STATIC[idx][0]; const char *vl = QPACK_STATIC[idx][1]; - if (!emit(ctx, nm, str.len(nm, scratch_cap + 1), vl, str.len(vl, scratch_cap + 1))) + if (!emit(ctx, nm, EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = nm, .cap = scratch_cap + 1), vl, + EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = vl, .cap = scratch_cap + 1))) { return PROTO_FALSE; } @@ -288,12 +290,12 @@ proto_bool protocore_qpack_decode(uint8_t *work, const uint8_t *block, size_t le return PROTO_FALSE; } const char *nm = QPACK_STATIC[idx][0]; - size_t nlen = str.len(nm, scratch_cap + 1); + size_t nlen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = nm, .cap = scratch_cap + 1); if (nlen > scratch_cap) { return PROTO_FALSE; } - mem.cpy(scratch, nm, nlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = scratch, .src = nm, .bytes = nlen); size_t vlen = 0; proto_bool hpack_prim_ok2 = HpackPrim.decode_str(work, block, len, &pos, scratch + nlen, scratch_cap - nlen, &vlen); @@ -336,7 +338,7 @@ proto_bool protocore_qpack_decode(uint8_t *work, const uint8_t *block, size_t le { return PROTO_FALSE; } - mem.cpy(scratch, block + pos, nlen32); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = scratch, .src = block + pos, .bytes = nlen32); nlen = nlen32; } pos += nlen32; diff --git a/src/network_drivers/presentation/http/http3/quic_frame/CMakeLists.txt b/src/network_drivers/presentation/http/http3/quic_frame/CMakeLists.txt index 522dd2a70..f7f18660c 100644 --- a/src/network_drivers/presentation/http/http3/quic_frame/CMakeLists.txt +++ b/src/network_drivers/presentation/http/http3/quic_frame/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(network_drivers/presentation/http/http3/quic_frame GATE PROTOCORE_ENABLE_HTTP3 SOURCES quic_frame.c PRIVATE_DEPS - mmgr/protomem + mmgr network_drivers/presentation/http/http3/quic_varint ) diff --git a/src/network_drivers/presentation/http/http3/quic_frame/quic_frame.c b/src/network_drivers/presentation/http/http3/quic_frame/quic_frame.c index a05737bd5..89aed2282 100644 --- a/src/network_drivers/presentation/http/http3/quic_frame/quic_frame.c +++ b/src/network_drivers/presentation/http/http3/quic_frame/quic_frame.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_HTTP3 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/http/http3/quic_frame/quic_frame.h" #include "network_drivers/presentation/http/http3/quic_varint/quic_varint.h" @@ -245,7 +245,7 @@ size_t protocore_quic_frame_build_padding(uint8_t *work, uint8_t *out, size_t ca { return 0; } - mem.set(out, 0, n); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = n); return n; } @@ -314,7 +314,7 @@ size_t protocore_quic_frame_build_crypto(uint8_t *work, uint8_t *out, size_t cap } if (len) { - mem.cpy(out + pos, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = data, .bytes = len); } return pos + len; } @@ -342,7 +342,7 @@ size_t protocore_quic_frame_build_stream(uint8_t *work, uint8_t *out, size_t cap } if (len) { - mem.cpy(out + pos, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = data, .bytes = len); } return pos + len; } @@ -387,7 +387,7 @@ size_t protocore_quic_frame_build_connection_close(uint8_t *work, uint8_t *out, } if (reason_len) { - mem.cpy(out + pos, reason, reason_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = reason, .bytes = reason_len); } return pos + reason_len; } diff --git a/src/network_drivers/presentation/http/http3/quic_packet/CMakeLists.txt b/src/network_drivers/presentation/http/http3/quic_packet/CMakeLists.txt index a65a9ad67..cf0a4d76c 100644 --- a/src/network_drivers/presentation/http/http3/quic_packet/CMakeLists.txt +++ b/src/network_drivers/presentation/http/http3/quic_packet/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(network_drivers/presentation/http/http3/quic_packet GATE PROTOCORE_ENABLE_HTTP3 SOURCES quic_packet.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/presentation/http/http3/quic_packet/quic_packet.c b/src/network_drivers/presentation/http/http3/quic_packet/quic_packet.c index d924045e3..7375831ab 100644 --- a/src/network_drivers/presentation/http/http3/quic_packet/quic_packet.c +++ b/src/network_drivers/presentation/http/http3/quic_packet/quic_packet.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_HTTP3 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/http/http3/quic_packet/quic_packet.h" static uint32_t rd_be32(const uint8_t *p) @@ -62,7 +62,7 @@ proto_bool protocore_quic_packet_parse_long_header(uint8_t *work, const uint8_t { return PROTO_FALSE; } - mem.cpy(out->dcid, buf + pos, dcl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->dcid, .src = buf + pos, .bytes = dcl); out->dcid_len = dcl; pos += dcl; uint8_t scl = buf[pos++]; @@ -70,7 +70,7 @@ proto_bool protocore_quic_packet_parse_long_header(uint8_t *work, const uint8_t { return PROTO_FALSE; } - mem.cpy(out->scid, buf + pos, scl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->scid, .src = buf + pos, .bytes = scl); out->scid_len = scl; pos += scl; out->hdr_len = pos; @@ -97,10 +97,10 @@ size_t protocore_quic_packet_build_long_header(uint8_t *work, uint8_t *out, size wr_be32(out + 1, version); size_t pos = 5; out[pos++] = dcid_len; - mem.cpy(out + pos, dcid, dcid_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = dcid, .bytes = dcid_len); pos += dcid_len; out[pos++] = scid_len; - mem.cpy(out + pos, scid, scid_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = scid, .bytes = scid_len); pos += scid_len; return pos; } @@ -120,7 +120,7 @@ proto_bool protocore_quic_packet_parse_short_header(uint8_t *work, const uint8_t out->spin = (uint8_t)((buf[0] & 0x20) ? 1 : 0); out->key_phase = (uint8_t)((buf[0] & 0x04) ? 1 : 0); out->pn_len = (uint8_t)((buf[0] & 0x03) + 1); - mem.cpy(out->dcid, buf + 1, dcid_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->dcid, .src = buf + 1, .bytes = dcid_len); out->dcid_len = dcid_len; out->hdr_len = (size_t)1 + dcid_len; return PROTO_TRUE; @@ -145,10 +145,10 @@ size_t protocore_quic_packet_build_version_negotiation(uint8_t *work, uint8_t *o wr_be32(out + 1, 0); // Version = 0 marks a Version Negotiation packet size_t pos = 5; out[pos++] = dcid_len; - mem.cpy(out + pos, dcid, dcid_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = dcid, .bytes = dcid_len); pos += dcid_len; out[pos++] = scid_len; - mem.cpy(out + pos, scid, scid_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = scid, .bytes = scid_len); pos += scid_len; for (size_t i = 0; i < nversions; i++) { diff --git a/src/network_drivers/presentation/http/http3/quic_tp/CMakeLists.txt b/src/network_drivers/presentation/http/http3/quic_tp/CMakeLists.txt index 5da7688b0..724ab9df4 100644 --- a/src/network_drivers/presentation/http/http3/quic_tp/CMakeLists.txt +++ b/src/network_drivers/presentation/http/http3/quic_tp/CMakeLists.txt @@ -7,6 +7,6 @@ protocore_add_module(network_drivers/presentation/http/http3/quic_tp DEPS network_drivers/presentation/http/http3/quic_packet PRIVATE_DEPS - mmgr/protomem + mmgr network_drivers/presentation/http/http3/quic_varint ) diff --git a/src/network_drivers/presentation/http/http3/quic_tp/quic_tp.c b/src/network_drivers/presentation/http/http3/quic_tp/quic_tp.c index 1f358695b..404210475 100644 --- a/src/network_drivers/presentation/http/http3/quic_tp/quic_tp.c +++ b/src/network_drivers/presentation/http/http3/quic_tp/quic_tp.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_HTTP3 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/presentation/http/http3/quic_tp/quic_tp.h" #include "network_drivers/presentation/http/http3/quic_varint/quic_varint.h" @@ -25,7 +25,7 @@ void protocore_quic_tp_defaults(uint8_t *work, QuicTransportParams *tp) { (void)work; - mem.set(tp, 0, sizeof(*tp)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = tp, .val = 0, .bytes = sizeof(*tp)); tp->max_udp_payload_size = 65527; tp->ack_delay_exponent = 3; tp->max_ack_delay = 25; @@ -58,7 +58,7 @@ static proto_bool put_param(uint8_t *work, uint8_t *out, size_t cap, size_t *p, { return PROTO_FALSE; } - mem.cpy(out + *p, val, val_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + *p, .src = val, .bytes = val_len); *p += val_len; } return PROTO_TRUE; @@ -132,7 +132,7 @@ static proto_bool copy_cid(const uint8_t *val, size_t len, uint8_t *dst, uint8_t { return PROTO_FALSE; } - mem.cpy(dst, val, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = dst, .src = val, .bytes = len); *dst_len = (uint8_t)len; *has = PROTO_TRUE; return PROTO_TRUE; diff --git a/src/network_drivers/presentation/http/http3/tls13_rpk/tls13_rpk.c b/src/network_drivers/presentation/http/http3/tls13_rpk/tls13_rpk.c index bf14ba120..863b03aee 100644 --- a/src/network_drivers/presentation/http/http3/tls13_rpk/tls13_rpk.c +++ b/src/network_drivers/presentation/http/http3/tls13_rpk/tls13_rpk.c @@ -55,15 +55,14 @@ size_t protocore_tls13_rpk_build_certificate(uint8_t *work, uint8_t *out, size_t size_t tls13_rpk_n = Tls13Rpk.ed25519_spki(work, spki, sizeof(spki), ed25519_pub); if (!tls13_rpk_n) { - tls13_rpk_n = 0; - return; + return 0; } Tls13MsgV.build_certificate_args.out = out; Tls13MsgV.build_certificate_args.cap = cap; Tls13MsgV.build_certificate_args.cert_der = spki; Tls13MsgV.build_certificate_args.cert_len = sizeof(spki); Tls13Msg.build_certificate(work); - tls13_rpk_n = Tls13MsgV.n; + return Tls13MsgV.n; } #endif // PROTOCORE_ENABLE_TLS_RPK diff --git a/src/network_drivers/presentation/http/httpcache/CMakeLists.txt b/src/network_drivers/presentation/http/httpcache/CMakeLists.txt index 042c07947..b4a2e8918 100644 --- a/src/network_drivers/presentation/http/httpcache/CMakeLists.txt +++ b/src/network_drivers/presentation/http/httpcache/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(network_drivers/presentation/http/httpcache GATE PROTOCORE_ENABLE_HTTP_CACHE SOURCES httpcache.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/network_drivers/presentation/http/httpcache/httpcache.c b/src/network_drivers/presentation/http/httpcache/httpcache.c index a5d79af34..c0727c194 100644 --- a/src/network_drivers/presentation/http/httpcache/httpcache.c +++ b/src/network_drivers/presentation/http/httpcache/httpcache.c @@ -10,9 +10,9 @@ #if PROTOCORE_ENABLE_HTTP_CACHE +#include "cellularum_laboro/cellularum_laboro.h" #include "httpcache.h" -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "memoria_operor/memoria_operor.h" PROTOCORE_BEGIN_DECLS @@ -85,7 +85,7 @@ static size_t cc_tok(char *buf, size_t cap, size_t n, proto_bool *first, const c { return CC_SENT; } - size_t tlen = str.len(tok, cap); + size_t tlen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = tok, .cap = cap); size_t need = (*first ? 0 : 2) + tlen; if (n + need > cap) { @@ -96,7 +96,7 @@ static size_t cc_tok(char *buf, size_t cap, size_t n, proto_bool *first, const c buf[n++] = ','; buf[n++] = ' '; } - mem.cpy(buf + n, tok, tlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + n, .src = tok, .bytes = tlen); *first = PROTO_FALSE; return n + tlen; } diff --git a/src/network_drivers/presentation/http/route/http_route/CMakeLists.txt b/src/network_drivers/presentation/http/route/http_route/CMakeLists.txt index cdfe9d55e..825248544 100644 --- a/src/network_drivers/presentation/http/route/http_route/CMakeLists.txt +++ b/src/network_drivers/presentation/http/route/http_route/CMakeLists.txt @@ -7,6 +7,6 @@ protocore_add_module(network_drivers/presentation/http/route/http_route DEPS network_drivers/presentation/http PRIVATE_DEPS - mmgr/protomem - mmgr/secure + mmgr + server/core/worker ) diff --git a/src/network_drivers/presentation/http/route/http_route/http_route.c b/src/network_drivers/presentation/http/route/http_route/http_route.c index 1be129b1f..53592e5f3 100644 --- a/src/network_drivers/presentation/http/route/http_route/http_route.c +++ b/src/network_drivers/presentation/http/route/http_route/http_route.c @@ -16,10 +16,10 @@ #if PROTOCORE_ENABLE_HTTP_ROUTE -#include "mmgr/protomem/protomem.h" // mem.zero: the hand-out wipe -#include "mmgr/secure/secure.h" // where the table lives +#include "memoria_operor/memoria_operor.h" // memor.set: the hand-out wipe #include "network_drivers/presentation/http/route/http_route/http_route.h" -#include "protocore.h" // completes HttpRoute; route.h names it only as an opaque tag +#include "protocore.h" // completes HttpRoute; route.h names it only as an opaque tag +#include "server/core/worker/worker.h" // the cellblock the table lives in // The table's layout, known only here. The storage behind it belongs to the secure pool. struct HttpRouteCtx @@ -50,7 +50,7 @@ uint8_t *protocore_http_route_span(void) { if (s_span == NULL) { - s_span = protocore_secure_persist_span(PROTOCORE_HTTP_ROUTE_BORROW).buf; + s_span = (uint8_t *)protocore_secure_persist(PROTOCORE_HTTP_ROUTE_BORROW); } return s_span; } @@ -73,7 +73,7 @@ HttpRoute *protocore_http_routes_add(uint8_t *work) // leaves the rest, so an entry carrying a previous tenant's handler or backend pointer would // dispatch to it. There is no release path - routes are registered at setup and live forever - // so hand-out is the only moment this can be done. - mem.zero(r, sizeof(*r)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = r, .val = 0, .bytes = sizeof(*r)); return r; } diff --git a/src/network_drivers/presentation/ssh/app/server/CMakeLists.txt b/src/network_drivers/presentation/ssh/app/server/CMakeLists.txt index 37def29c1..55a5f59f4 100644 --- a/src/network_drivers/presentation/ssh/app/server/CMakeLists.txt +++ b/src/network_drivers/presentation/ssh/app/server/CMakeLists.txt @@ -6,6 +6,5 @@ protocore_add_module(network_drivers/presentation/ssh/app/server DEPS network_drivers/presentation/ssh/connection PRIVATE_DEPS - mmgr/bytes - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/presentation/ssh/app/server/server.c b/src/network_drivers/presentation/ssh/app/server/server.c index ae012a423..8a8d8cd64 100644 --- a/src/network_drivers/presentation/ssh/app/server/server.c +++ b/src/network_drivers/presentation/ssh/app/server/server.c @@ -7,8 +7,9 @@ */ #include "network_drivers/presentation/ssh/app/server/server.h" -#include "mmgr/bytes/bytes.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" +#include "octetus_introitus_exitus/octetus_introitus_exitus.h" // byteio.rd_str: the RFC 4251 sec 5 string reader +#include "spatium/spatium.h" // spat.cfrom: the request payload as a read span #if PROTOCORE_ENABLE_SSH_SFTP || PROTOCORE_ENABLE_SSH_SCP // A subsystem/exec CHANNEL_REQUEST may name a file-transfer service (SFTP or SCP). Tag @p c and fire the @@ -22,20 +23,22 @@ void protocore_ssh_app_server_classify(uint8_t *work) const uint32_t channel = SshAppServerV.channel; const uint8_t *rtype = SshAppServerV.req.rtype; const uint32_t rtype_len = SshAppServerV.req.rtype_len; - const uint8_t *payload = SshAppServerV.req.payload; - const size_t len = SshAppServerV.req.len; - size_t *off = &SshAppServerV.req.off; + // The request payload, read from the request-specific argument on; its cursor is handed back below. + mmgr_cspan req = + EMBED_CALL(spat.cfrom, SpatiumCfg, .cbuf = SshAppServerV.req.payload, .cap = SshAppServerV.req.len); + req.pos = SshAppServerV.req.off; proto_bool *accept = &SshAppServerV.accept; #if !PROTOCORE_ENABLE_SSH_SFTP (void)accept; // only the SFTP subsystem path flips acceptance; scp exec is already accepted #endif #if PROTOCORE_ENABLE_SSH_SFTP // subsystem "sftp": not in the base accept set, so accept it here and tag the channel for the SFTP binding. - if (rtype_len == 9 && mem.cmp(rtype, "subsystem", 9) == 0) + if (rtype_len == 9 && EMBED_CALL(memor.cmp, MemoriaCfg, .src = rtype, .other = "subsystem", .bytes = 9) == 0) { const uint8_t *arg = NULL; - uint32_t arg_len = 0; - if (bytes.rd_str(payload, len, off, &arg, &arg_len) && arg_len == 4 && mem.cmp(arg, "sftp", 4) == 0) + size_t arg_len = 0; + if (EMBED_CALL(byteio.rd_str, OctetusCfg, .read_span = &req, .blob = &arg, .blob_bytes = &arg_len) && + arg_len == 4 && EMBED_CALL(memor.cmp, MemoriaCfg, .src = arg, .other = "sftp", .bytes = 4) == 0) { *accept = PROTO_TRUE; SshConnectionV.chan.slot = i; @@ -52,11 +55,12 @@ void protocore_ssh_app_server_classify(uint8_t *work) #endif #if PROTOCORE_ENABLE_SSH_SCP // exec "scp …": already accepted (exec is in the base set); tag the channel + hand the command to the binding. - if (rtype_len == 4 && mem.cmp(rtype, "exec", 4) == 0) + if (rtype_len == 4 && EMBED_CALL(memor.cmp, MemoriaCfg, .src = rtype, .other = "exec", .bytes = 4) == 0) { const uint8_t *arg = NULL; - uint32_t arg_len = 0; - if (bytes.rd_str(payload, len, off, &arg, &arg_len) && arg_len >= 4 && mem.cmp(arg, "scp ", 4) == 0) + size_t arg_len = 0; + if (EMBED_CALL(byteio.rd_str, OctetusCfg, .read_span = &req, .blob = &arg, .blob_bytes = &arg_len) && + arg_len >= 4 && EMBED_CALL(memor.cmp, MemoriaCfg, .src = arg, .other = "scp ", .bytes = 4) == 0) { SshConnectionV.chan.slot = i; SshConnectionV.chan.channel = channel; @@ -70,6 +74,7 @@ void protocore_ssh_app_server_classify(uint8_t *work) } } #endif + SshAppServerV.req.off = req.pos; } #else diff --git a/src/network_drivers/presentation/ssh/auth/auth.h b/src/network_drivers/presentation/ssh/auth/auth.h index 68218da6f..e592ef1b0 100644 --- a/src/network_drivers/presentation/ssh/auth/auth.h +++ b/src/network_drivers/presentation/ssh/auth/auth.h @@ -197,7 +197,7 @@ typedef struct uint8_t *out; ///< where a reply is written size_t out_len; ///< what was written size_t cap; ///< how much room it has - protocore_span *w; ///< the span a publickey request is built in + mmgr_span *w; ///< the span a publickey request is built in } SshAuthOutArgs; /** @brief RFC 4252 sec 5 / sec 7: the names one USERAUTH_REQUEST carries, and the key it offers. */ diff --git a/src/network_drivers/presentation/ssh/common/CMakeLists.txt b/src/network_drivers/presentation/ssh/common/CMakeLists.txt index 9071e099d..db023350d 100644 --- a/src/network_drivers/presentation/ssh/common/CMakeLists.txt +++ b/src/network_drivers/presentation/ssh/common/CMakeLists.txt @@ -9,7 +9,6 @@ protocore_add_module(network_drivers/presentation/ssh/common crypto/cipher/aes256ctr crypto/mac/hmac_sha256 crypto/pqc/sntrup761 - mmgr/bytes - mmgr/protostr + mmgr network_drivers/presentation/ssh/transport/ssh_kexhash ) diff --git a/src/network_drivers/presentation/ssh/common/common.h b/src/network_drivers/presentation/ssh/common/common.h index 239bf6a38..c1a448779 100644 --- a/src/network_drivers/presentation/ssh/common/common.h +++ b/src/network_drivers/presentation/ssh/common/common.h @@ -9,14 +9,15 @@ #ifndef PROTOCORE_SSH_COMMON_H #define PROTOCORE_SSH_COMMON_H +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len: the length prefix on a written string #include "crypto/aead/chachapoly/chachapoly.h" // PROTOCORE_CHACHAPOLY_KEY_LEN - the chacha keys in the memory map #include "crypto/asymmetric/bignum/bignum.h" // protocore_bignum - the DH ephemeral in the memory map #include "crypto/cipher/aes256ctr/aes256ctr.h" // PROTOCORE_AES256CTR_KEY_LEN / _CTR_LEN - the aes keys and IVs #include "crypto/mac/hmac_sha256/hmac_sha256.h" // PROTOCORE_HMAC_SHA256_BORROW - the packet MAC scratch #include "crypto/pqc/sntrup761/sntrup761.h" // PROTOCORE_SNTRUP761_PK_BYTES - the PQC public key in the memory map -#include "mmgr/bytes/bytes.h" // protocore_span, bytes.* writers, bytes.rd_str / bytes.rd_u32 readers -#include "mmgr/protostr/protostr.h" // str.len: the length prefix on a written string +#include "memoria_operor/memoria_operor.h" // memor.cpy: the copy out of a read string #include "network_drivers/presentation/ssh/transport/ssh_kexhash/ssh_kexhash.h" // SSH_KEXHASH_MAX_LEN - the session id span +#include "octetus_introitus_exitus/octetus_introitus_exitus.h" // mmgr_span, byteio.* writers, byteio.rd_str / byteio.take_be readers #include "protocore_config.h" // protocore_types.h for the fixed widths, PROTOCORE_INLINE, the SSH sizing constants @@ -249,10 +250,10 @@ static inline void write_u32_be(uint8_t *p, uint32_t v) } /** @brief Append a string: uint32 length, then @p n bytes of @p data. */ -PROTOCORE_INLINE void protocore_ssh_wr_str(protocore_span *w, const void *data, size_t n) +PROTOCORE_INLINE void protocore_ssh_wr_str(mmgr_span *w, const void *data, size_t n) { - bytes.put_be(w, (uint64_t)n, 4); - bytes.raw(w, data, n); + EMBED_CALL(byteio.put_be, OctetusCfg, .write_span = w, .value = (uint64_t)n, .bytes = 4); + EMBED_CALL(byteio.raw, OctetusCfg, .write_span = w, .src = data, .bytes = n); } /** @@ -260,16 +261,16 @@ PROTOCORE_INLINE void protocore_ssh_wr_str(protocore_span *w, const void *data, * * A comma-separated name-list (RFC 4253 sec 7.1) is one of these. */ -PROTOCORE_INLINE void protocore_ssh_wr_cstr(protocore_span *w, const char *s) +PROTOCORE_INLINE void protocore_ssh_wr_cstr(mmgr_span *w, const char *s) { - protocore_ssh_wr_str(w, s, str.len(s, w->cap)); + protocore_ssh_wr_str(w, s, EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = w->cap)); } /** * @brief Append @p len big-endian bytes as an mpint: leading zero bytes stripped, a 0x00 prepended * when the top bit is set, and a zero value written as the empty string. */ -PROTOCORE_INLINE void protocore_ssh_wr_mpint(protocore_span *w, const uint8_t *be, size_t len) +PROTOCORE_INLINE void protocore_ssh_wr_mpint(mmgr_span *w, const uint8_t *be, size_t len) { size_t off = 0; while (off < len && be[off] == 0) @@ -278,7 +279,7 @@ PROTOCORE_INLINE void protocore_ssh_wr_mpint(protocore_span *w, const uint8_t *b } if (off == len) { - bytes.put_be(w, 0, 4); + EMBED_CALL(byteio.put_be, OctetusCfg, .write_span = w, .value = 0, .bytes = 4); return; } proto_bool pad = (be[off] & 0x80u) != 0; @@ -287,12 +288,12 @@ PROTOCORE_INLINE void protocore_ssh_wr_mpint(protocore_span *w, const uint8_t *b { mlen++; } - bytes.put_be(w, mlen, 4); + EMBED_CALL(byteio.put_be, OctetusCfg, .write_span = w, .value = mlen, .bytes = 4); if (pad) { - bytes.put(w, 0x00); + EMBED_CALL(byteio.put, OctetusCfg, .write_span = w, .byte = 0x00); } - bytes.raw(w, be + off, len - off); + EMBED_CALL(byteio.raw, OctetusCfg, .write_span = w, .src = be + off, .bytes = len - off); } // --------------------------------------------------------------------------- @@ -422,24 +423,30 @@ PROTOCORE_INLINE uint8_t protocore_ssh_rd_u8(Rd *r) } PROTOCORE_INLINE uint32_t protocore_ssh_rd_u32(Rd *r) { - uint32_t v = 0; - if (!bytes.rd_u32(r->buf, r->len, &r->off, &v)) + mmgr_cspan c = {.buf = r->buf, .len = r->len, .pos = r->off, .err = EMBED_FALSE}; + uint64_t v = 0; + if (!EMBED_CALL(byteio.take_be, OctetusCfg, .read_span = &c, .bytes = 4, .out = &v)) { r->ok = PROTO_FALSE; return 0; } - return v; + r->off = c.pos; + return (uint32_t)v; } // Returns a pointer to an in-place string of length *n; advances past it. Fails closed on overflow. PROTOCORE_INLINE const uint8_t *protocore_ssh_rd_string(Rd *r, uint32_t *n) { + mmgr_cspan c = {.buf = r->buf, .len = r->len, .pos = r->off, .err = EMBED_FALSE}; const uint8_t *p = NULL; - if (!bytes.rd_str(r->buf, r->len, &r->off, &p, n)) + size_t got = 0; + if (!EMBED_CALL(byteio.rd_str, OctetusCfg, .read_span = &c, .blob = &p, .blob_bytes = &got)) { r->ok = PROTO_FALSE; *n = 0; return NULL; } + r->off = c.pos; + *n = (uint32_t)got; // the length was read as four bytes, so it fits return p; } @@ -450,23 +457,23 @@ PROTOCORE_INLINE const uint8_t *protocore_ssh_rd_string(Rd *r, uint32_t *n) // Copy an SSH string into a fixed buffer and null-terminate it. Advances *off. // Returns false on truncation or if the string does not fit (buffer too small). // -// Reading the field by reference is bytes.rd_str()'s job; this only adds the copy and the terminator, +// Reading the field by reference is byteio.rd_str()'s job; this only adds the copy and the terminator, // which is what separates it from the by-reference reads below. static proto_bool read_string(const uint8_t *p, size_t len, size_t *off, char *out, size_t outcap) { - size_t start = *off; + mmgr_cspan c = {.buf = p, .len = len, .pos = *off, .err = EMBED_FALSE}; const uint8_t *s = NULL; - uint32_t n = 0; - if (!bytes.rd_str(p, len, off, &s, &n)) + size_t n = 0; + if (!EMBED_CALL(byteio.rd_str, OctetusCfg, .read_span = &c, .blob = &s, .blob_bytes = &n)) { return PROTO_FALSE; } if (n >= outcap) { - *off = start; // same contract as bytes.rd_str: a failed read leaves the offset on its own field - return PROTO_FALSE; // does not fit our fixed buffer + return PROTO_FALSE; // does not fit our fixed buffer; same contract as byteio.rd_str: *off stays on its own field } - mem.cpy(out, s, n); + *off = c.pos; + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = s, .bytes = n); out[n] = '\0'; return PROTO_TRUE; } diff --git a/src/network_drivers/presentation/ssh/transport/ssh_kexhash/ssh_kexhash.c b/src/network_drivers/presentation/ssh/transport/ssh_kexhash/ssh_kexhash.c index 275d3038b..1ec3f3faa 100644 --- a/src/network_drivers/presentation/ssh/transport/ssh_kexhash/ssh_kexhash.c +++ b/src/network_drivers/presentation/ssh/transport/ssh_kexhash/ssh_kexhash.c @@ -42,8 +42,8 @@ static_assert(KEXHASH_OFF_CTX + sizeof(SshKexHashCtx) <= PROTOCORE_SSH_KEXHASH_B static_assert(PROTOCORE_SHA256_BORROW <= PROTOCORE_SHA512_BORROW, "the SHA-256 arm runs in the SHA-512 region, so it must be the narrower of the two"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(KEXHASH_OFF_CTX % _Alignof(SshKexHashCtx) == 0, diff --git a/src/network_drivers/presentation/ssh/transport/transport/transport.h b/src/network_drivers/presentation/ssh/transport/transport/transport.h index caf5dd848..ff5db25b9 100644 --- a/src/network_drivers/presentation/ssh/transport/transport/transport.h +++ b/src/network_drivers/presentation/ssh/transport/transport/transport.h @@ -13,8 +13,8 @@ #include "crypto/aead/chachapoly/chachapoly.h" #include "crypto/asymmetric/bignum/bignum.h" #include "crypto/cipher/aes256ctr/aes256ctr.h" -#include "crypto/hash/sha256/sha256.h" // PROTOCORE_SHA256_DIGEST_LEN - the exchange hash and session id -#include "mmgr/secure/secure.h" // protocore_secure_wipe (the canonical secure wipe) +#include "crypto/hash/sha256/sha256.h" // PROTOCORE_SHA256_DIGEST_LEN - the exchange hash and session id +#include "locus_carcerum/locus_carcerum.h" // mmgr_zero_buf (the canonical secure wipe) #include "network_drivers/presentation/ssh/common/common.h" #include "network_drivers/presentation/ssh/transport/phase_machine/phase_machine.h" // SshPhase: the session's phase @@ -602,7 +602,7 @@ static inline uint8_t ssh_mac_len(uint8_t mac_mode) return (mac_mode == SSH_MAC_HMAC_SHA512 || mac_mode == SSH_MAC_HMAC_SHA512_ETM) ? 64 : 32; } -// Secure wipe: the canonical protocore_secure_wipe() lives in mmgr/secure.h (included above). Use it for +// Secure wipe: the canonical mmgr_zero_buf() lives in locus_carcerum/locus_carcerum.h (included above). Use it for // any buffer that held key material - a volatile store the compiler may not elide, unlike a dead memset. // --------------------------------------------------------------------------- @@ -768,16 +768,16 @@ static inline void ssh_keymat_wipe(uint8_t i) { AesGcm.key_wipe(km->gcm_ctx_s2c); } - protocore_secure_wipe(km->gcm_ctx_c2s, PROTOCORE_AESGCM_BORROW); - protocore_secure_wipe(km->gcm_ctx_s2c, PROTOCORE_AESGCM_BORROW); - protocore_secure_wipe(km->chacha_key_c2s, PROTOCORE_CHACHAPOLY_KEY_LEN); - protocore_secure_wipe(km->chacha_key_s2c, PROTOCORE_CHACHAPOLY_KEY_LEN); - protocore_secure_wipe(km->mac_key_c2s, 64); - protocore_secure_wipe(km->mac_key_s2c, 64); - protocore_secure_wipe(km->aes_key_c2s, PROTOCORE_AES256CTR_KEY_LEN); - protocore_secure_wipe(km->aes_key_s2c, PROTOCORE_AES256CTR_KEY_LEN); - protocore_secure_wipe(km->aes_iv_c2s, PROTOCORE_AES256CTR_CTR_LEN); - protocore_secure_wipe(km->aes_iv_s2c, PROTOCORE_AES256CTR_CTR_LEN); + mmgr_zero_buf(km->gcm_ctx_c2s, PROTOCORE_AESGCM_BORROW); + mmgr_zero_buf(km->gcm_ctx_s2c, PROTOCORE_AESGCM_BORROW); + mmgr_zero_buf(km->chacha_key_c2s, PROTOCORE_CHACHAPOLY_KEY_LEN); + mmgr_zero_buf(km->chacha_key_s2c, PROTOCORE_CHACHAPOLY_KEY_LEN); + mmgr_zero_buf(km->mac_key_c2s, 64); + mmgr_zero_buf(km->mac_key_s2c, 64); + mmgr_zero_buf(km->aes_key_c2s, PROTOCORE_AES256CTR_KEY_LEN); + mmgr_zero_buf(km->aes_key_s2c, PROTOCORE_AES256CTR_KEY_LEN); + mmgr_zero_buf(km->aes_iv_c2s, PROTOCORE_AES256CTR_CTR_LEN); + mmgr_zero_buf(km->aes_iv_s2c, PROTOCORE_AES256CTR_CTR_LEN); km->mac_mode_c2s = 0; km->mac_mode_s2c = 0; km->cipher_mode_c2s = 0; @@ -802,13 +802,13 @@ static inline void ssh_dh_wipe(uint8_t i) } if (ssh_dh[i].y != NULL) { - protocore_secure_wipe(ssh_dh[i].y, sizeof(protocore_bignum)); - protocore_secure_wipe(ssh_dh[i].f, sizeof(protocore_bignum)); - protocore_secure_wipe(ssh_dh[i].K, sizeof(protocore_bignum)); + mmgr_zero_buf(ssh_dh[i].y, sizeof(protocore_bignum)); + mmgr_zero_buf(ssh_dh[i].f, sizeof(protocore_bignum)); + mmgr_zero_buf(ssh_dh[i].K, sizeof(protocore_bignum)); } if (ssh_sess[i].ecdh_sk != NULL) { - protocore_secure_wipe(ssh_sess[i].ecdh_sk, SSH_ECDH_PAIR_LEN); + mmgr_zero_buf(ssh_sess[i].ecdh_sk, SSH_ECDH_PAIR_LEN); } } diff --git a/src/network_drivers/session/scp/scp/CMakeLists.txt b/src/network_drivers/session/scp/scp/CMakeLists.txt index 03830f6a7..11bf7de94 100644 --- a/src/network_drivers/session/scp/scp/CMakeLists.txt +++ b/src/network_drivers/session/scp/scp/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(network_drivers/session/scp/scp GATE PROTOCORE_ENABLE_SSH_SCP SOURCES scp.c PRIVATE_DEPS - mmgr/membuild - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/session/scp/scp/scp.c b/src/network_drivers/session/scp/scp/scp.c index 0ee13c890..aa0aa7929 100644 --- a/src/network_drivers/session/scp/scp/scp.c +++ b/src/network_drivers/session/scp/scp/scp.c @@ -10,9 +10,9 @@ #if PROTOCORE_ENABLE_SSH_SCP -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/session/scp/scp/scp.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain // Apply one scp flag token (e.g. "-t", "-rf"): -t selects the sink role, -f the source; other letters // (-v/-r/-p/-d and combinations) are accepted and ignored. @@ -82,7 +82,7 @@ ScpMode protocore_scp_parse_cmd(uint8_t *work, const char *cmd, size_t cmd_len, { return SCP_MODE_INVALID; } - mem.cpy(path_out, last_tok, last_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = path_out, .src = last_tok, .bytes = last_len); path_out[last_len] = '\0'; return mode; } @@ -134,7 +134,7 @@ proto_bool protocore_scp_parse_cline(uint8_t *work, const char *line, size_t len { return PROTO_FALSE; } - mem.cpy(name_out, line + ns, nlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = name_out, .src = line + ns, .bytes = nlen); name_out[nlen] = '\0'; if (mode_out) @@ -152,15 +152,17 @@ size_t protocore_scp_build_cline(uint8_t *work, uint32_t mode, uint64_t size, co { (void)work; - protocore_sb sb_out = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out, "C"); - Sb.uint(&sb_out, (uint64_t)((unsigned)(mode & 07777)), 8, 4); - Sb.put(&sb_out, " "); - Sb.u64(&sb_out, (uint64_t)((unsigned long long)size)); - Sb.put(&sb_out, " "); - Sb.put(&sb_out, name); - Sb.put(&sb_out, "\n"); - int n = (int)Sb.finish(&sb_out); + size_t sb_out = 0; + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = "C"); + sb_out = EMBED_CALL(verba_numerus.uint, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint64_t)((unsigned)(mode & 07777)), .base = 8, .min = 4); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = " "); + sb_out = EMBED_CALL(verba_numerus.u64, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint64_t)((unsigned long long)size)); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = " "); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = name); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = "\n"); + int n = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out); // The n <= 0 arm can never be true, so this line is branch-excluded: snprintf returns the length // it WOULD have written (never negative here - no encoding can fail on this format), and that // format always emits at least "C0000 0 \n". Only the truncation arm is reachable, and it is diff --git a/src/network_drivers/transport/diffserv/CMakeLists.txt b/src/network_drivers/transport/diffserv/CMakeLists.txt index beefa63e0..e57d7dd7a 100644 --- a/src/network_drivers/transport/diffserv/CMakeLists.txt +++ b/src/network_drivers/transport/diffserv/CMakeLists.txt @@ -5,5 +5,6 @@ protocore_add_module(network_drivers/transport/diffserv GATE PROTOCORE_ENABLE_DIFFSERV SOURCES diffserv.c PRIVATE_DEPS - mmgr/plaintext + mmgr + server/core/worker ) diff --git a/src/network_drivers/transport/diffserv/diffserv.c b/src/network_drivers/transport/diffserv/diffserv.c index fca4204f3..5226d4870 100644 --- a/src/network_drivers/transport/diffserv/diffserv.c +++ b/src/network_drivers/transport/diffserv/diffserv.c @@ -15,7 +15,7 @@ #if PROTOCORE_ENABLE_DIFFSERV #include "diffserv.h" -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from PROTOCORE_BEGIN_DECLS @@ -58,7 +58,7 @@ uint8_t *protocore_diffserv_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_DIFFSERV_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_DIFFSERV_BORROW); } return s_own.span; } diff --git a/src/network_drivers/transport/proxy_protocol/CMakeLists.txt b/src/network_drivers/transport/proxy_protocol/CMakeLists.txt index 8f6de2a94..f9ba69e3d 100644 --- a/src/network_drivers/transport/proxy_protocol/CMakeLists.txt +++ b/src/network_drivers/transport/proxy_protocol/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(network_drivers/transport/proxy_protocol GATE PROTOCORE_ENABLE_PROXY_PROTOCOL SOURCES proxy_protocol.c PRIVATE_DEPS - mmgr/membuild - mmgr/protomem + mmgr ) diff --git a/src/network_drivers/transport/proxy_protocol/proxy_protocol.c b/src/network_drivers/transport/proxy_protocol/proxy_protocol.c index 32d5ae675..4b4ab9479 100644 --- a/src/network_drivers/transport/proxy_protocol/proxy_protocol.c +++ b/src/network_drivers/transport/proxy_protocol/proxy_protocol.c @@ -10,9 +10,9 @@ #if PROTOCORE_ENABLE_PROXY_PROTOCOL -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "network_drivers/transport/proxy_protocol/proxy_protocol.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -156,9 +156,12 @@ static proto_bool parse_v1(const uint8_t *buf, size_t len, ProxyInfo *out, size_ *consumed = crlf + 2; // "PROXY TCP4 ". TCP4, TCP6 and UNKNOWN are the published family // tokens; any other sequence does not match the protocol and is discarded. - proto_bool tcp4 = (ntok == 6 && tlen[1] == 4 && mem.cmp(tok[1], "TCP4", 4) == 0); - proto_bool tcp6 = (ntok == 6 && tlen[1] == 4 && mem.cmp(tok[1], "TCP6", 4) == 0); - proto_bool unknown = (ntok >= 2 && tlen[1] == 7 && mem.cmp(tok[1], "UNKNOWN", 7) == 0); + proto_bool tcp4 = (ntok == 6 && tlen[1] == 4 && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = tok[1], .other = "TCP4", .bytes = 4) == 0); + proto_bool tcp6 = (ntok == 6 && tlen[1] == 4 && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = tok[1], .other = "TCP6", .bytes = 4) == 0); + proto_bool unknown = (ntok >= 2 && tlen[1] == 7 && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = tok[1], .other = "UNKNOWN", .bytes = 7) == 0); if (!tcp4 && !tcp6 && !unknown) { return PROTO_FALSE; @@ -196,7 +199,8 @@ void protocore_proxy_protocol_parse(uint8_t *work) } // v2: the 12-octet binary signature. - if (len >= PROXY_V2_SIG_LEN && mem.cmp(buf, kV2Sig, PROXY_V2_SIG_LEN) == 0) + if (len >= PROXY_V2_SIG_LEN && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = buf, .other = kV2Sig, .bytes = PROXY_V2_SIG_LEN) == 0) { if (len < 16) // signature + ver_cmd + fam + 2-octet length { @@ -246,7 +250,7 @@ void protocore_proxy_protocol_parse(uint8_t *work) } // v1: the "PROXY " text prefix. - if (len >= 6 && mem.cmp(buf, "PROXY ", 6) == 0) + if (len >= 6 && EMBED_CALL(memor.cmp, MemoriaCfg, .src = buf, .other = "PROXY ", .bytes = 6) == 0) { ProxyProtocolV.ok = parse_v1(buf, len, out, consumed); return; @@ -270,29 +274,39 @@ void protocore_proxy_protocol_v1_build(uint8_t *work) ProxyProtocolV.n = 0; return; } - protocore_sb sb_buf = {buf, cap, 0, PROTO_TRUE}; - Sb.put(&sb_buf, "PROXY TCP4 "); - Sb.u32(&sb_buf, (uint32_t)((unsigned)((src_addr >> 24) & 0xFF))); - Sb.put(&sb_buf, "."); - Sb.u32(&sb_buf, (uint32_t)((unsigned)((src_addr >> 16) & 0xFF))); - Sb.put(&sb_buf, "."); - Sb.u32(&sb_buf, (uint32_t)((unsigned)((src_addr >> 8) & 0xFF))); - Sb.put(&sb_buf, "."); - Sb.u32(&sb_buf, (uint32_t)((unsigned)(src_addr & 0xFF))); - Sb.put(&sb_buf, " "); - Sb.u32(&sb_buf, (uint32_t)((unsigned)((dst_addr >> 24) & 0xFF))); - Sb.put(&sb_buf, "."); - Sb.u32(&sb_buf, (uint32_t)((unsigned)((dst_addr >> 16) & 0xFF))); - Sb.put(&sb_buf, "."); - Sb.u32(&sb_buf, (uint32_t)((unsigned)((dst_addr >> 8) & 0xFF))); - Sb.put(&sb_buf, "."); - Sb.u32(&sb_buf, (uint32_t)((unsigned)(dst_addr & 0xFF))); - Sb.put(&sb_buf, " "); - Sb.u32(&sb_buf, (uint32_t)((unsigned)src_port)); - Sb.put(&sb_buf, " "); - Sb.u32(&sb_buf, (uint32_t)((unsigned)dst_port)); - Sb.put(&sb_buf, "\r\n"); - int n = (int)Sb.finish(&sb_buf); + size_t sb_buf = 0; + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = "PROXY TCP4 "); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)((src_addr >> 24) & 0xFF))); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = "."); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)((src_addr >> 16) & 0xFF))); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = "."); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)((src_addr >> 8) & 0xFF))); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = "."); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)(src_addr & 0xFF))); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = " "); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)((dst_addr >> 24) & 0xFF))); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = "."); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)((dst_addr >> 16) & 0xFF))); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = "."); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)((dst_addr >> 8) & 0xFF))); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = "."); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)(dst_addr & 0xFF))); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = " "); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)src_port)); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = " "); + sb_buf = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_buf, + .val = (uint32_t)((unsigned)dst_port)); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_buf, .text = "\r\n"); + int n = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = buf, .cap = cap, .at = sb_buf); // n < 0 is never true here: the format string uses only %u conversions (no wide/multibyte // specifiers), so snprintf can't fail with an encoding error for this call. if (n < 0 || (size_t)n >= cap) @@ -319,7 +333,7 @@ void protocore_proxy_protocol_v2_build(uint8_t *work) ProxyProtocolV.n = 0; return; } - mem.cpy(buf, kV2Sig, PROXY_V2_SIG_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf, .src = kV2Sig, .bytes = PROXY_V2_SIG_LEN); buf[12] = PROXY_V2_VER_CMD_PROXY; buf[13] = PROXY_V2_FAM_TCP4; buf[14] = 0x00; // address-block length (12), big-endian diff --git a/src/network_drivers/transport/tcp/common/CMakeLists.txt b/src/network_drivers/transport/tcp/common/CMakeLists.txt index 6e7222b67..fd434d3d2 100644 --- a/src/network_drivers/transport/tcp/common/CMakeLists.txt +++ b/src/network_drivers/transport/tcp/common/CMakeLists.txt @@ -4,7 +4,7 @@ protocore_add_module(network_drivers/transport/tcp/common HEADER_ONLY DEPS - mmgr/ring + mmgr network_drivers/transport/tcp/evt shared/ip ) diff --git a/src/network_drivers/transport/tcp/common/common.h b/src/network_drivers/transport/tcp/common/common.h index e3012653a..db8d342d2 100644 --- a/src/network_drivers/transport/tcp/common/common.h +++ b/src/network_drivers/transport/tcp/common/common.h @@ -10,19 +10,18 @@ * server (sec 3.9.1.1 passive OPEN), the client (active OPEN), the protocol engine (sec 3.10) and * the lower-level seam (sec 3.9.2) all read this header and none of them declares its own copy. * - * The event record itself is in evt.h, which this includes: the ring cursors below are `_Atomic`, + * The event record itself is in evt.h, which this includes: the slot state below is `_Atomic`, * which is C11 and not C++, so the header that reaches the sketches has to be the smaller one. * * **Concurrency model** - * | Context | Reads | Writes | - * |------------------|------------------------|-------------------------| - * | stack callbacks | rx_head (to check full)| rx_buffer[], rx_head | - * | main loop | rx_buffer[], rx_tail | rx_tail | + * | Context | Reads | Writes | + * |------------------|------------------------------|--------------------------| + * | stack callbacks | anularis.vacant (to check) | anularis.put | + * | main loop | anularis.available/read/peek | anularis.read/consume | * - * `state`, `rx_head`, and `rx_tail` are `_Atomic`, read and written through - * PROTO_ATOMIC_LOAD / PROTO_ATOMIC_STORE (acquire/release): the single-producer / - * single-consumer ring buffer is correct without a mutex because the release store of an index - * publishes the preceding buffer writes and the acquire load observes them, on either core. + * The receive ring is a memoria_anularis ring over the slot's own aligned rx_buffer: one producer + * (the stack callbacks) and one consumer (the owning worker), with the ordering inside the ring. + * `state` is `_Atomic`, read and written through PROTO_ATOMIC_LOAD / PROTO_ATOMIC_STORE. * * **Backpressure (lossless)** * When a whole inbound segment will not fit the free ring space, the recv callback refuses it @@ -38,9 +37,10 @@ #define PROTOCORE_TCP_COMMON_H #include "config/platform/platform.h" -#include "mmgr/ring/ring.h" // PROTO_ATOMIC_LOAD/STORE + the shared SPSC ring drain primitive +#include "memoria_anularis/memoria_anularis.h" // mmgr_ring: the receive ring, and the loculi the slots are #include "network_drivers/transport/tcp/evt/evt.h" // EvtType, TcpEvt: what this layer posts to a listener queue #include "shared/ip/ip.h" // protocore_ip (family-tagged peer address) +#include // atomic_load_explicit / atomic_store_explicit on the slot state #include "protocore_config.h" @@ -53,7 +53,7 @@ PROTOCORE_BEGIN_DECLS * @brief A single TCP connection context. * * Sized so that `MAX_CONNS` instances fit in a static array without - * fragmentation. All fields except the ring-buffer indices may + * fragmentation. All fields except the ring and the state may * only be accessed from the main-loop task. */ typedef struct TcpConn @@ -63,12 +63,11 @@ typedef struct TcpConn protocore_pcb *pcb; ///< Stack control block; null when slot is free. uint32_t last_activity_ms; ///< `protocore_millis()` timestamp of last TX/RX event. - uint8_t rx_buffer[RX_BUF_SIZE]; ///< Ring buffer storage. - _Atomic size_t rx_head; ///< Producer write index (stack callback context). - _Atomic size_t rx_tail; ///< Consumer read index (worker context). - size_t rx_acked; ///< rx_tail position last ACKed to the stack. Worker-only: - ///< the window is reopened by exactly the bytes drained since, so it - ///< tracks ring occupancy (ack-on-consume) rather than copy. + EMBED_ALIGN(MMGR_ALIGN_BYTES) uint8_t rx_buffer[RX_BUF_SIZE]; ///< The ring's bytes, owned here. + mmgr_ring rx; ///< The receive ring over rx_buffer. + size_t rx_unacked; ///< Bytes drained since the last ACK to the stack. Worker-only: the window is + ///< reopened by exactly these, so it tracks ring occupancy (ack-on-consume) + ///< rather than copy. uint8_t listener_id; ///< Index into listener_pool[]; set at accept time. uint8_t owner; ///< Worker that owns this slot (round-robin at accept). Always 0 at N=1. @@ -85,37 +84,23 @@ typedef struct TcpConn #define PROTOCORE_PROTO_SLOT_NONE 0xFFu // --------------------------------------------------------------------------- -// Slot state, as bits +// Slot state, as loculi // --------------------------------------------------------------------------- // -// A slot's availability is two questions, and each is one bit in a mask rather than a field to -// load and compare: +// A slot's availability is one loculus of the pool's slot ring (protocol/protocol.c), rather than a +// field to load and compare. Loculus i is held while conn_pool[i] is anything but CONN_FREE, keeping +// out that slot's rx_buffer, and dropped when it returns to CONN_FREE. Written through +// protocore_conn_set_state() only, so it stays in lock-step with the state. // -// free bit i set = conn_pool[i] is CONN_FREE. Written through protocore_conn_set_state() only, -// so it stays in lock-step with the state. -// held bit i set = something still owns bytes in slot i - a transfer the wire has not finished -// reading. Taken when that begins and dropped when it completes. -// -// A slot is allocatable only when it is free AND not held: protocore_slot_ready() is -// `free & ~held`, and protocore_slot_next() picks the lowest with one ctz. Holding is what makes -// reuse safe. Without it a slot reads free while a transfer is still walking its bytes, and the -// index is handed to a new connection on top of the old one's in-flight data - the collision RFC -// 9293 sec 3.6.1 keeps a connection identifier out of circulation to avoid, expressed as a bit -// rather than a timer, because a pool index is not a socket and has no quiet period to wait out. - -/** @brief The pool's slot bitmaps. Both are read by the allocator and written from stack and - * worker context, so both are atomic. */ -typedef struct -{ - _Atomic uint32_t free; ///< bit i = conn_pool[i] is CONN_FREE. - _Atomic uint32_t held; ///< bit i = slot i still owns bytes in flight. -} ConnSlotBits; - -/** @brief The one instance, defined in protocol/protocol.c. */ -extern ConnSlotBits protocore_conn_bits; +// A slot is allocatable only when its loculus is free AND not held: anularis.loculus_ready is +// `free & ~held`, and anularis.loculus_next picks the lowest. Holding is what makes reuse safe. +// Without it a slot reads free while its bytes are still in use, and the index is handed to a new +// connection on top of the old one's data - the collision RFC 9293 sec 3.6.1 keeps a connection +// identifier out of circulation to avoid, expressed as a bit rather than a timer, because a pool +// index is not a socket and has no quiet period to wait out. -_Static_assert(MAX_CONNS <= PROTOCORE_RING_SLOTS_MAX, - "the slot bitmaps are uint32; raise them or fall back to a scan if MAX_CONNS exceeds 32"); +_Static_assert(MAX_CONNS <= MMGR_RING_LOCULI, + "every connection slot is a loculus; raise MMGR_RING_LOCULI (and MMGR_RING_WORDS) with MAX_CONNS"); /** * @brief Access-point IPv4 address (network byte order) for STA/AP interface tagging. @@ -133,7 +118,7 @@ extern TcpConn conn_pool[CONN_POOL_SLOTS]; // The receive ring is drained through ::ConnPool - available, read_byte, peek, consume and read - // and a slot is asked about through active, iface, listener_id, tls, owner, proto_of and pcb_of. -// Transport owns the ring: nothing above this layer indexes rx_buffer or advances rx_tail. +// Transport owns the ring: nothing above this layer reaches rx_buffer or the ring itself. // --------------------------------------------------------------------------- // Listener pool entry diff --git a/src/network_drivers/transport/udp/common/CMakeLists.txt b/src/network_drivers/transport/udp/common/CMakeLists.txt index 020a735b6..6c0f209f2 100644 --- a/src/network_drivers/transport/udp/common/CMakeLists.txt +++ b/src/network_drivers/transport/udp/common/CMakeLists.txt @@ -4,7 +4,6 @@ protocore_add_module(network_drivers/transport/udp/common HEADER_ONLY DEPS - mmgr/bytes - mmgr/ring + mmgr shared/ip ) diff --git a/src/network_drivers/transport/udp/common/common.h b/src/network_drivers/transport/udp/common/common.h index a4b8a05a1..2f8513d0d 100644 --- a/src/network_drivers/transport/udp/common/common.h +++ b/src/network_drivers/transport/udp/common/common.h @@ -17,8 +17,8 @@ * 21 len payload * * Every field is written and read at a stated width in network byte order, so the bytes in the ring - * are the same bytes on every target. The header is built through a protocore_span and read through a - * protocore_cspan, which carry the bound and latch an overrun. + * are the same bytes on every target. The header is built through an mmgr_span and read through an + * mmgr_cspan, which carry the bound and latch an overrun. * * The layout is the contract, so it is published rather than opaque. Internal to transport/udp: no * table, no exported symbol. @@ -30,9 +30,10 @@ #ifndef PROTOCORE_UDP_COMMON_H #define PROTOCORE_UDP_COMMON_H -#include "mmgr/bytes/bytes.h" // bytes.put / bytes.put_be / bytes.take_be over a span -#include "mmgr/ring/ring.h" // the SPSC ring the datagrams sit in -#include "shared/ip/ip.h" // protocore_ip: the address a datagram carries, network order +#include "endian/endian.h" // magna_extremitas: the address as two big-endian words +#include "memoria_anularis/memoria_anularis.h" // mmgr_ring: the SPSC ring the datagrams sit in +#include "octetus_introitus_exitus/octetus_introitus_exitus.h" // byteio.put / put_be / take_be over a span +#include "shared/ip/ip.h" // protocore_ip: the address a datagram carries, network order PROTOCORE_BEGIN_DECLS @@ -48,13 +49,17 @@ typedef struct } protocore_udp_dgram; /** @brief Write the header of @p d into @p w at its cursor. */ -PROTOCORE_INLINE void protocore_udp_dgram_encode(protocore_span *w, const protocore_udp_dgram *d) +PROTOCORE_INLINE void protocore_udp_dgram_encode(mmgr_span *w, const protocore_udp_dgram *d) { - bytes.put(w, (uint8_t)d->addr.family); - bytes.put_be(w, d->port, 2); - bytes.put_be(w, d->len, 2); - bytes.put_be(w, endian.rd64be(d->addr.bytes), 8); - bytes.put_be(w, endian.rd64be(d->addr.bytes + 8), 8); + EMBED_CALL(byteio.put, OctetusCfg, .write_span = w, .byte = (uint8_t)d->addr.family); + EMBED_CALL(byteio.put_be, OctetusCfg, .write_span = w, .value = d->port, .bytes = 2); + EMBED_CALL(byteio.put_be, OctetusCfg, .write_span = w, .value = d->len, .bytes = 2); + EMBED_CALL(byteio.put_be, OctetusCfg, .write_span = w, + .value = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = d->addr.bytes, .width = MMGR_ENDIAN_64), + .bytes = 8); + EMBED_CALL(byteio.put_be, OctetusCfg, .write_span = w, + .value = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = d->addr.bytes + 8, .width = MMGR_ENDIAN_64), + .bytes = 8); } /** @@ -63,15 +68,18 @@ PROTOCORE_INLINE void protocore_udp_dgram_encode(protocore_span *w, const protoc * A family byte that is neither 4 nor 6 leaves the address empty, so a caller cannot route on a * value the parser did not recognize. */ -PROTOCORE_INLINE proto_bool protocore_udp_dgram_decode(protocore_cspan *r, protocore_udp_dgram *d) +PROTOCORE_INLINE proto_bool protocore_udp_dgram_decode(mmgr_cspan *r, protocore_udp_dgram *d) { uint64_t family = 0; uint64_t port = 0; uint64_t len = 0; uint64_t hi = 0; uint64_t lo = 0; - if (!bytes.take_be(r, 1, &family) || !bytes.take_be(r, 2, &port) || !bytes.take_be(r, 2, &len) || - !bytes.take_be(r, 8, &hi) || !bytes.take_be(r, 8, &lo)) + if (!EMBED_CALL(byteio.take_be, OctetusCfg, .read_span = r, .bytes = 1, .out = &family) || + !EMBED_CALL(byteio.take_be, OctetusCfg, .read_span = r, .bytes = 2, .out = &port) || + !EMBED_CALL(byteio.take_be, OctetusCfg, .read_span = r, .bytes = 2, .out = &len) || + !EMBED_CALL(byteio.take_be, OctetusCfg, .read_span = r, .bytes = 8, .out = &hi) || + !EMBED_CALL(byteio.take_be, OctetusCfg, .read_span = r, .bytes = 8, .out = &lo)) { return PROTO_FALSE; } @@ -84,8 +92,8 @@ PROTOCORE_INLINE proto_bool protocore_udp_dgram_decode(protocore_cspan *r, proto { d->addr.family = PROTOCORE_IP_V6; } - (void)endian.wr64be(d->addr.bytes, hi); - (void)endian.wr64be(d->addr.bytes + 8, lo); + (void)EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = d->addr.bytes, .val = hi, .width = MMGR_ENDIAN_64); + (void)EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = d->addr.bytes + 8, .val = lo, .width = MMGR_ENDIAN_64); d->port = (uint16_t)port; d->len = (uint16_t)len; return PROTO_TRUE; @@ -98,16 +106,15 @@ PROTOCORE_INLINE proto_bool protocore_udp_dgram_decode(protocore_cspan *r, proto * Peeks the header, consumes it, then reads exactly its payload length, so the tail always lands on * the next entry boundary. Reports false when the ring holds no whole entry. */ -PROTOCORE_INLINE proto_bool protocore_udp_dgram_take(uint8_t *ring, size_t cap, _Atomic size_t *head, - _Atomic size_t *tail, uint8_t *hdr, protocore_udp_dgram *d, +PROTOCORE_INLINE proto_bool protocore_udp_dgram_take(mmgr_ring *ring, uint8_t *hdr, protocore_udp_dgram *d, uint8_t *stage, size_t stage_cap) { - if (protocore_ring_available(head, tail, cap) < PROTOCORE_UDP_DGRAM_HDR) + if (EMBED_CALL(anularis.available, AnularisCfg, .ring = ring) < PROTOCORE_UDP_DGRAM_HDR) { return PROTO_FALSE; } - protocore_ring_peek(ring, cap, tail, 0, hdr, PROTOCORE_UDP_DGRAM_HDR); - protocore_cspan r = span.cfrom(hdr, PROTOCORE_UDP_DGRAM_HDR); + EMBED_CALL(anularis.peek, AnularisCfg, .ring = ring, .dst = hdr, .bytes = PROTOCORE_UDP_DGRAM_HDR, .offset = 0); + mmgr_cspan r = {.buf = hdr, .len = PROTOCORE_UDP_DGRAM_HDR, .pos = 0, .err = EMBED_FALSE}; if (!protocore_udp_dgram_decode(&r, d)) { return PROTO_FALSE; @@ -116,15 +123,16 @@ PROTOCORE_INLINE proto_bool protocore_udp_dgram_take(uint8_t *ring, size_t cap, { // Nothing queues a payload longer than the stage, so a length past it means the ring lost its // entry boundary. Drop the whole ring rather than read past one. - PROTO_ATOMIC_STORE(tail, PROTO_ATOMIC_LOAD(head)); + EMBED_CALL(anularis.consume, AnularisCfg, .ring = ring, + .bytes = EMBED_CALL(anularis.available, AnularisCfg, .ring = ring)); return PROTO_FALSE; } - if (protocore_ring_available(head, tail, cap) < (PROTOCORE_UDP_DGRAM_HDR + (size_t)d->len)) + if (EMBED_CALL(anularis.available, AnularisCfg, .ring = ring) < (PROTOCORE_UDP_DGRAM_HDR + (size_t)d->len)) { return PROTO_FALSE; } - protocore_ring_consume(tail, cap, PROTOCORE_UDP_DGRAM_HDR); - (void)protocore_ring_read(ring, cap, head, tail, stage, d->len); + EMBED_CALL(anularis.consume, AnularisCfg, .ring = ring, .bytes = PROTOCORE_UDP_DGRAM_HDR); + (void)EMBED_CALL(anularis.read, AnularisCfg, .ring = ring, .dst = stage, .bytes = d->len); return PROTO_TRUE; } diff --git a/src/server/core/exc_decoder/CMakeLists.txt b/src/server/core/exc_decoder/CMakeLists.txt index 9d5718533..2f4ddde2b 100644 --- a/src/server/core/exc_decoder/CMakeLists.txt +++ b/src/server/core/exc_decoder/CMakeLists.txt @@ -7,7 +7,6 @@ protocore_add_module(server/core/exc_decoder DEPS server/storage/mnt PRIVATE_DEPS - mmgr/membuild - mmgr/protostr + mmgr shared/hex ) diff --git a/src/server/core/exc_decoder/exc_decoder.c b/src/server/core/exc_decoder/exc_decoder.c index 4b34f804d..37c44928b 100644 --- a/src/server/core/exc_decoder/exc_decoder.c +++ b/src/server/core/exc_decoder/exc_decoder.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_EXC_DECODER -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protostr/protostr.h" // str.find: each field's marker inside the panic dump +#include "cellularum_laboro/cellularum_laboro.h" // cellul.find: each field's marker inside the panic dump #include "server/core/exc_decoder/exc_decoder.h" -#include "shared/hex/hex.h" // PROTOCORE_HEX: the shared digit tables +#include "shared/hex/hex.h" // PROTOCORE_HEX: the shared digit tables +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -72,41 +72,37 @@ static const char *parse_hex(const char *p, uint32_t *out) return p; } -static void put_json_str(protocore_sb *b, const char *s) +static size_t put_json_str(char *out, size_t cap, size_t at, const char *s) { - Sb.put(b, "\""); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "\""); const char *src = s ? s : ""; for (const char *p = src; *p; p++) { if (*p == '"' || *p == '\\') { char esc[3] = {'\\', *p, '\0'}; - Sb.put(b, esc); - } - else if (b->len + 1 < b->cap) - { - b->p[b->len++] = *p; + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = esc); } else { - b->ok = PROTO_FALSE; + at = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = out, .cap = cap, .at = at, .ch = *p); } } - Sb.put(b, "\""); + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "\""); } // Emit a 32-bit value as a JSON string literal "0x........". -static void put_hex32(protocore_sb *b, uint32_t v) +static size_t put_hex32(char *out, size_t cap, size_t at, uint32_t v) { char t[13] = "\"0x00000000\""; for (int i = 0; i < 8; i++) { t[3 + i] = PROTOCORE_HEX.lower[(v >> ((7 - i) * 4)) & 0xF]; } - Sb.put(b, t); + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = t); } -static void put_int(protocore_sb *b, int v) +static size_t put_int(char *out, size_t cap, size_t at, int v) { char t[12]; int n = 0; @@ -128,7 +124,7 @@ static void put_int(protocore_sb *b, int v) o[k++] = t[n - 1 - i]; } o[k] = '\0'; - Sb.put(b, o); + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = o); } // Parse a run of decimal digits at @p p into a small non-negative int, clamped to avoid signed-overflow @@ -150,7 +146,9 @@ static int parse_small_int(const char *p) // Cause: "...panic'ed (LoadProhibited)." static void parse_cause(const char *text, ExcInfo *out) { - const char *c = str.find(text, str.len(text, 0xFFFF) + 1u, "panic'ed (", sizeof("panic'ed ("), PROTO_FALSE); + const char *c = EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = text, + .cap = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = text, .cap = 0xFFFF) + 1u, + .other = "panic'ed (", .other_cap = sizeof("panic'ed ("), .ci = PROTO_FALSE); if (!c) { return; @@ -168,7 +166,9 @@ static void parse_cause(const char *text, ExcInfo *out) // Core number: "Core N ...". static void parse_core(const char *text, ExcInfo *out) { - const char *co = str.find(text, str.len(text, 0xFFFF) + 1u, "Core ", sizeof("Core "), PROTO_FALSE); + const char *co = EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = text, + .cap = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = text, .cap = 0xFFFF) + 1u, + .other = "Core ", .other_cap = sizeof("Core "), .ci = PROTO_FALSE); if (!co) { return; @@ -183,12 +183,16 @@ static void parse_core(const char *text, ExcInfo *out) // EXCVADDR (faulting data address). static void parse_excvaddr(const char *text, ExcInfo *out) { - const char *e = str.find(text, str.len(text, 0xFFFF) + 1u, "EXCVADDR", sizeof("EXCVADDR"), PROTO_FALSE); + const char *e = EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = text, + .cap = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = text, .cap = 0xFFFF) + 1u, + .other = "EXCVADDR", .other_cap = sizeof("EXCVADDR"), .ci = PROTO_FALSE); if (!e) { return; } - const char *colon = str.find(e, str.len(e, 0xFFFF) + 1u, ":", sizeof(":"), PROTO_FALSE); + const char *colon = EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = e, + .cap = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = e, .cap = 0xFFFF) + 1u, + .other = ":", .other_cap = sizeof(":"), .ci = PROTO_FALSE); if (!colon) { return; @@ -204,14 +208,19 @@ static void parse_excvaddr(const char *text, ExcInfo *out) // Register-dump PC: a line that starts with "PC" (not "EPC..."). Anchor to a line break. static void parse_pc(const char *text, ExcInfo *out) { - const char *pcl = str.starts(text, "PC", 2, PROTO_FALSE) - ? text - : str.find(text, str.len(text, 0xFFFF) + 1u, "\nPC", sizeof("\nPC"), PROTO_FALSE); + const char *pcl = + EMBED_CALL(cellul.starts, CatenaFinitaCfg, .src = text, .other = "PC", .cap = 2, .ci = PROTO_FALSE) + ? text + : EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = text, + .cap = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = text, .cap = 0xFFFF) + 1u, + .other = "\nPC", .other_cap = sizeof("\nPC"), .ci = PROTO_FALSE); if (!pcl) { return; } - const char *colon = str.find(pcl, str.len(pcl, 0xFFFF) + 1u, ":", sizeof(":"), PROTO_FALSE); + const char *colon = EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = pcl, + .cap = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = pcl, .cap = 0xFFFF) + 1u, + .other = ":", .other_cap = sizeof(":"), .ci = PROTO_FALSE); if (!colon) { return; @@ -226,7 +235,9 @@ static void parse_pc(const char *text, ExcInfo *out) // Backtrace: "Backtrace: pc:sp pc:sp ...". static void parse_backtrace(const char *text, ExcInfo *out) { - const char *bt = str.find(text, str.len(text, 0xFFFF) + 1u, "Backtrace:", sizeof("Backtrace:"), PROTO_FALSE); + const char *bt = EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = text, + .cap = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = text, .cap = 0xFFFF) + 1u, + .other = "Backtrace:", .other_cap = sizeof("Backtrace:"), .ci = PROTO_FALSE); if (!bt) { return; @@ -298,46 +309,46 @@ void protocore_exc_json(uint8_t *work) ExcV.n = 0; return; } - protocore_sb b = {out, cap, 0, PROTO_TRUE}; - Sb.put(&b, "{"); + size_t b = 0; + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "{"); proto_bool first = PROTO_TRUE; if (info->core >= 0) { - Sb.put(&b, "\"core\":"); - put_int(&b, info->core); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "\"core\":"); + b = put_int(out, cap, b, info->core); first = PROTO_FALSE; } if (!first) { - Sb.put(&b, ","); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ","); } - Sb.put(&b, "\"cause\":"); - put_json_str(&b, info->cause); - Sb.put(&b, ",\"pc\":"); - put_hex32(&b, info->pc); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "\"cause\":"); + b = put_json_str(out, cap, b, info->cause); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"pc\":"); + b = put_hex32(out, cap, b, info->pc); if (info->has_excvaddr) { - Sb.put(&b, ",\"excvaddr\":"); - put_hex32(&b, info->excvaddr); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"excvaddr\":"); + b = put_hex32(out, cap, b, info->excvaddr); } - Sb.put(&b, ",\"backtrace\":["); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"backtrace\":["); for (size_t i = 0; i < info->frame_count; i++) { if (i) { - Sb.put(&b, ","); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ","); } - put_hex32(&b, info->frames[i].pc); + b = put_hex32(out, cap, b, info->frames[i].pc); } - Sb.put(&b, "]}"); - if (!b.ok) + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "]}"); + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = b)) { out[0] = '\0'; ExcV.n = 0; return; } - out[b.len] = '\0'; - ExcV.n = b.len; + out[b] = '\0'; + ExcV.n = b; } #if PROTOCORE_HAS_VENDOR_COREDUMP diff --git a/src/server/core/failsafe/CMakeLists.txt b/src/server/core/failsafe/CMakeLists.txt index 55c3cb06c..9bc433464 100644 --- a/src/server/core/failsafe/CMakeLists.txt +++ b/src/server/core/failsafe/CMakeLists.txt @@ -5,5 +5,6 @@ protocore_add_module(server/core/failsafe GATE PROTOCORE_ENABLE_FAILSAFE SOURCES failsafe.c PRIVATE_DEPS - mmgr/plaintext + mmgr + server/core/worker ) diff --git a/src/server/core/failsafe/failsafe.c b/src/server/core/failsafe/failsafe.c index 5e373e7b6..ab1294af2 100644 --- a/src/server/core/failsafe/failsafe.c +++ b/src/server/core/failsafe/failsafe.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_FAILSAFE -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/core/failsafe/failsafe.h" PROTOCORE_BEGIN_DECLS @@ -51,7 +51,7 @@ uint8_t *protocore_failsafe_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_FAILSAFE_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_FAILSAFE_BORROW); } return s_own.span; } diff --git a/src/server/core/guardrails/CMakeLists.txt b/src/server/core/guardrails/CMakeLists.txt index 8f7e6446e..072aa6c75 100644 --- a/src/server/core/guardrails/CMakeLists.txt +++ b/src/server/core/guardrails/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(server/core/guardrails GATE PROTOCORE_ENABLE_GUARDRAILS SOURCES guardrails.c PRIVATE_DEPS - mmgr/membuild - mmgr/plaintext + mmgr + server/core/worker ) diff --git a/src/server/core/guardrails/guardrails.c b/src/server/core/guardrails/guardrails.c index b76019afe..fbaee04d2 100644 --- a/src/server/core/guardrails/guardrails.c +++ b/src/server/core/guardrails/guardrails.c @@ -10,9 +10,9 @@ #if PROTOCORE_ENABLE_GUARDRAILS -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from #include "server/core/guardrails/guardrails.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -48,7 +48,7 @@ uint8_t *protocore_guardrails_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_GUARDRAILS_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_GUARDRAILS_BORROW); } return s_own.span; } @@ -99,20 +99,28 @@ void protocore_guardrails_json(uint8_t *work) { return; } - protocore_sb sb_out = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out, "{\"free_heap\":"); - Sb.u32(&sb_out, (uint32_t)((unsigned)h->free_heap)); - Sb.put(&sb_out, ",\"min_free_heap\":"); - Sb.u32(&sb_out, (uint32_t)((unsigned)h->min_free_heap)); - Sb.put(&sb_out, ",\"largest_free_block\":"); - Sb.u32(&sb_out, (uint32_t)((unsigned)h->largest_free_block)); - Sb.put(&sb_out, ",\"stack_free\":"); - Sb.u32(&sb_out, (uint32_t)((unsigned)h->stack_free)); - Sb.put(&sb_out, "}"); - const int w = (int)Sb.finish(&sb_out); + size_t sb_out = 0; + sb_out = + EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = "{\"free_heap\":"); + sb_out = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint32_t)((unsigned)h->free_heap)); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, + .text = ",\"min_free_heap\":"); + sb_out = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint32_t)((unsigned)h->min_free_heap)); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, + .text = ",\"largest_free_block\":"); + sb_out = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint32_t)((unsigned)h->largest_free_block)); + sb_out = + EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = ",\"stack_free\":"); + sb_out = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint32_t)((unsigned)h->stack_free)); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = "}"); + const int w = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out); // w < 0 is unreachable: this format is all %u (unsigned) with literal text, no // multibyte/wide-character conversion, which is the only way snprintf goes negative. - if (!sb_out.ok) + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = sb_out)) { out[0] = '\0'; return; diff --git a/src/server/core/logbuf/CMakeLists.txt b/src/server/core/logbuf/CMakeLists.txt index 214371d95..50d430762 100644 --- a/src/server/core/logbuf/CMakeLists.txt +++ b/src/server/core/logbuf/CMakeLists.txt @@ -5,8 +5,6 @@ protocore_add_module(server/core/logbuf GATE PROTOCORE_ENABLE_LOGBUF SOURCES logbuf.c PRIVATE_DEPS - mmgr/plaintext - mmgr/protoframe - mmgr/protomem - mmgr/protostr + mmgr + server/core/worker ) diff --git a/src/server/core/logbuf/logbuf.c b/src/server/core/logbuf/logbuf.c index 40be8f18f..994902c8f 100644 --- a/src/server/core/logbuf/logbuf.c +++ b/src/server/core/logbuf/logbuf.c @@ -10,16 +10,16 @@ #if PROTOCORE_ENABLE_LOGBUF -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "mmgr/protoframe/protoframe.h" // the one frame engine -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" +#include "numeros_scribo/numeros_scribo.h" // the one frame engine #include "server/core/logbuf/logbuf.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from PROTOCORE_BEGIN_DECLS // A log line is its severity letter, a space, then the message. -static const protocore_field LOG_LINE[] = {PROTOCORE_CH, {PROTOCORE_FK_LIT, 0, 1, " "}, PROTOCORE_STR, PROTOCORE_END}; +static const mmgr_field LOG_LINE[] = {MMGR_CH, {MMGR_FK_LIT, 0, 1, " "}, MMGR_STR, MMGR_END}; /** * @brief The ring's compile-time storage: the lines, their severities, and the cursors over them. @@ -60,7 +60,7 @@ uint8_t *protocore_logbuf_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_LOGBUF_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_LOGBUF_BORROW); } return s_own.span; } @@ -102,8 +102,9 @@ void protocore_logbuf_put(uint8_t *work) LOGBUF_CTX(work)->head = (uint16_t)((LOGBUF_CTX(work)->head + 1) % PROTOCORE_LOG_LINES); } // A NULL msg renders empty and an over-long line empties the slot, both from the frame contract. - frame.build(LOGBUF_CTX(work)->lines[slot], PROTOCORE_LOG_LINE_LEN, LOG_LINE, - (const protocore_fval[]){PROTOCORE_VCH(level_letter(level)), PROTOCORE_VSTR(LogbufV.line.msg)}, 2); + EMBED_CALL(numer.build, NumerosCfg, .out = LOGBUF_CTX(work)->lines[slot], .cap = PROTOCORE_LOG_LINE_LEN, + .spec = LOG_LINE, + .vals = (const mmgr_fval[]){MMGR_VCH(level_letter(level)), MMGR_VSTR(LogbufV.line.msg)}, .nvals = 2); LOGBUF_CTX(work)->level[slot] = level; if (LOGBUF_CTX(work)->trap && level >= LOGBUF_CTX(work)->trap_threshold) @@ -144,14 +145,14 @@ void protocore_logbuf_dump(uint8_t *work) for (uint16_t i = 0; i < LOGBUF_CTX(work)->count; i++) { const char *line = LOGBUF_CTX(work)->lines[(LOGBUF_CTX(work)->head + i) % PROTOCORE_LOG_LINES]; - size_t n = str.len(line, cap); + size_t n = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = line, .cap = cap); size_t need = n + (i + 1 < LOGBUF_CTX(work)->count ? 1 : 0); // +1 for the '\n' separator if (pos + need >= cap) // keep room for the null terminator { out[0] = '\0'; return; } - mem.cpy(out + pos, line, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = line, .bytes = n); pos += n; if (i + 1 < LOGBUF_CTX(work)->count) { diff --git a/src/server/core/power_mgmt/CMakeLists.txt b/src/server/core/power_mgmt/CMakeLists.txt index 7a8fb780a..450a6cd96 100644 --- a/src/server/core/power_mgmt/CMakeLists.txt +++ b/src/server/core/power_mgmt/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(server/core/power_mgmt GATE PROTOCORE_ENABLE_POWER_MGMT SOURCES power_mgmt.c PRIVATE_DEPS - mmgr/membuild - mmgr/plaintext + mmgr + server/core/worker ) diff --git a/src/server/core/power_mgmt/power_mgmt.c b/src/server/core/power_mgmt/power_mgmt.c index f28ed20c3..680d42772 100644 --- a/src/server/core/power_mgmt/power_mgmt.c +++ b/src/server/core/power_mgmt/power_mgmt.c @@ -10,9 +10,9 @@ #if PROTOCORE_ENABLE_POWER_MGMT -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from #include "server/core/power_mgmt/power_mgmt.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain // --------------------------------------------------------------------------- // Pure decision @@ -56,7 +56,7 @@ uint8_t *protocore_power_mgmt_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_POWER_MGMT_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_POWER_MGMT_BORROW); } return s_own.span; } @@ -142,24 +142,27 @@ void protocore_power_json(uint8_t *work) } // The two forms differ by one field, so one builder emits both rather than two copies that can // drift apart. - protocore_sb sb = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb, "{\"cpu_mhz\":"); - Sb.u32(&sb, (uint32_t)plan->cpu_mhz); - Sb.put(&sb, ",\"throttled\":"); - Sb.put(&sb, plan->throttled ? "true" : "false"); - Sb.put(&sb, ",\"recovering\":"); - Sb.put(&sb, plan->recovering ? "true" : "false"); - Sb.put(&sb, ",\"temp_c\":"); + size_t sb = 0; + sb = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb, .text = "{\"cpu_mhz\":"); + sb = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb, + .val = (uint32_t)plan->cpu_mhz); + sb = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb, .text = ",\"throttled\":"); + sb = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb, + .text = plan->throttled ? "true" : "false"); + sb = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb, .text = ",\"recovering\":"); + sb = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb, + .text = plan->recovering ? "true" : "false"); + sb = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb, .text = ",\"temp_c\":"); if (temp_c == INT16_MIN) // no sensor: report null rather than a sentinel that reads as a reading { - Sb.put(&sb, "null"); + sb = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb, .text = "null"); } else { - Sb.i64(&sb, (int64_t)temp_c); + sb = EMBED_CALL(verba_numerus.i64, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb, .sval = (int64_t)temp_c); } - Sb.put(&sb, "}"); - size_t n = Sb.finish(&sb); + sb = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb, .text = "}"); + size_t n = EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb); if (n == 0) { // Fail closed: the builder writes the pieces that fit before it latches, so without this diff --git a/src/server/core/preempt_queue/CMakeLists.txt b/src/server/core/preempt_queue/CMakeLists.txt index 61ab2ce6d..497d86d74 100644 --- a/src/server/core/preempt_queue/CMakeLists.txt +++ b/src/server/core/preempt_queue/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(server/core/preempt_queue GATE PROTOCORE_ENABLE_PREEMPT_QUEUE SOURCES preempt_queue.c PRIVATE_DEPS - mmgr/plaintext - mmgr/secure + mmgr + server/core/worker ) diff --git a/src/server/core/preempt_queue/preempt_queue.c b/src/server/core/preempt_queue/preempt_queue.c index 23fabb8f1..affcc7e99 100644 --- a/src/server/core/preempt_queue/preempt_queue.c +++ b/src/server/core/preempt_queue/preempt_queue.c @@ -14,11 +14,10 @@ #if PROTOCORE_ENABLE_PREEMPT_QUEUE -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from #include "server/core/preempt_queue/preempt_queue.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "config/platform/platform.h" -#include "mmgr/secure/secure.h" // protocore_secure_persist_span: the item a lane's task receives into PROTOCORE_BEGIN_DECLS @@ -77,7 +76,7 @@ uint8_t *protocore_preempt_queue_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_PREEMPT_QUEUE_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_PREEMPT_QUEUE_BORROW); } return s_own.span; } @@ -136,19 +135,19 @@ static void pq_task(void *arg) protocore_pq_lane lane = (protocore_pq_lane)((uintptr_t)arg); // The entry never returns, so this item is permanent: it comes from the persistent end, which no // reset or release walks. A lane that cannot get one has nowhere to receive into and stops. - protocore_span item = protocore_secure_persist_span(PROTOCORE_PQ_ITEM_SIZE); - if (!span.has_storage(item)) + uint8_t *const item = (uint8_t *)protocore_secure_persist(PROTOCORE_PQ_ITEM_SIZE); + if (item == NULL) { return; } for (;;) { - if (protocore_platform_queue_recv(PREEMPT_QUEUE_CTX(protocore_preempt_queue_span())->qq.q[(size_t)lane], - item.buf, PROTOCORE_PLATFORM_WAIT_FOREVER) == PROTOCORE_PLATFORM_OK && + if (protocore_platform_queue_recv(PREEMPT_QUEUE_CTX(protocore_preempt_queue_span())->qq.q[(size_t)lane], item, + PROTOCORE_PLATFORM_WAIT_FOREVER) == PROTOCORE_PLATFORM_OK && PREEMPT_QUEUE_CTX(protocore_preempt_queue_span())->pq.handler[(size_t)lane]) { PREEMPT_QUEUE_CTX(protocore_preempt_queue_span()) - ->pq.handler[(size_t)lane](item.buf, + ->pq.handler[(size_t)lane](item, PREEMPT_QUEUE_CTX(protocore_preempt_queue_span())->pq.ctx[(size_t)lane]); } } diff --git a/src/server/core/worker/CMakeLists.txt b/src/server/core/worker/CMakeLists.txt index 54986281e..f593acb48 100644 --- a/src/server/core/worker/CMakeLists.txt +++ b/src/server/core/worker/CMakeLists.txt @@ -4,9 +4,6 @@ protocore_add_module(server/core/worker SOURCES worker.c DEPS + mmgr server/core/preempt_queue - PRIVATE_DEPS - mmgr/arena - mmgr/plaintext - mmgr/ring ) diff --git a/src/server/core/worker/worker.c b/src/server/core/worker/worker.c index 61ec9e139..4609150b9 100644 --- a/src/server/core/worker/worker.c +++ b/src/server/core/worker/worker.c @@ -11,11 +11,149 @@ */ #include "server/core/worker/worker.h" -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from #include "config/platform/platform.h" // the target's queues and tasks, under our names -#include "mmgr/arena/arena.h" // protocore_worker_set_self: identity lives with the pools it indexes -#include "mmgr/ring/ring.h" // PROTO_ATOMIC_LOAD/STORE: the run flag crosses tasks + +#include // PROTO_ATOMIC_LOAD/STORE: the run flag crosses tasks + +// --------------------------------------------------------------------------- +// Worker identity +// --------------------------------------------------------------------------- +// +// Per-task worker id, for a genuine multi-worker build. Default 0: the user loop(), the lwIP +// thread, and unit tests all read worker 0. +// +// The binding is a table keyed on the platform's own answer to "which execution context is running +// me", not a `_Thread_local`. Both reach the same place on an RTOS - the task's own storage - but a +// thread-local makes the compiler emit __emutls_get_address, and libgcc's emulated-TLS allocates +// each block with malloc and calls abort when it cannot. A build that owns no heap after boot +// cannot link that, so the identity is held here instead. +// +// One entry per worker plus the ghost slot, which is every context that can ever bind one; the +// count is fixed at build time, so this is BSS and the claim is a bounded walk. `s_bound` is the +// counter: a context that has never bound reads worker 0. +#define PROTOCORE_WORKER_BINDINGS (PROTOCORE_WORKER_COUNT + 1) + +static uintptr_t s_ctx[PROTOCORE_WORKER_BINDINGS]; +static int s_ctx_worker[PROTOCORE_WORKER_BINDINGS]; +static int s_bound; + +int protocore_worker_count(void) +{ + return PROTOCORE_WORKER_COUNT; +} + +#if PROTOCORE_WORKER_COUNT != 1 +int protocore_worker_self(void) +{ + const uintptr_t me = protocore_platform_context_id(); + for (int i = 0; i < s_bound; i++) + { + if (s_ctx[i] == me) + { + return s_ctx_worker[i]; + } + } + return 0; +} +#endif + +void protocore_worker_set_self(int id) +{ + const uintptr_t me = protocore_platform_context_id(); + for (int i = 0; i < s_bound; i++) + { + if (s_ctx[i] == me) + { + s_ctx_worker[i] = id; // this context rebinding itself + return; + } + } + if (s_bound < PROTOCORE_WORKER_BINDINGS) + { + s_ctx[s_bound] = me; + s_ctx_worker[s_bound] = id; + s_bound++; + } +} + +// --------------------------------------------------------------------------- +// Cellblocks +// --------------------------------------------------------------------------- + +// A cellblock is a power of two, and the arena sizes are sums of what the enabled modules declare, +// so the ghost's pools are each sum rounded up to the next power of two. Smeared on an enum name +// rather than on the sum itself, so the expression is 32 copies of one identifier. +enum +{ + GHOST_PLAIN_WANT = PROTOCORE_PLAINTEXT_ARENA_SIZE, + GHOST_SECURE_WANT = PROTOCORE_SECURE_ARENA_SIZE, +}; +#define WORKER_SMEAR1(x) ((x) | ((x) >> 1)) +#define WORKER_SMEAR2(x) (WORKER_SMEAR1(x) | (WORKER_SMEAR1(x) >> 2)) +#define WORKER_SMEAR4(x) (WORKER_SMEAR2(x) | (WORKER_SMEAR2(x) >> 4)) +#define WORKER_SMEAR8(x) (WORKER_SMEAR4(x) | (WORKER_SMEAR4(x) >> 8)) +#define WORKER_SMEAR16(x) (WORKER_SMEAR8(x) | (WORKER_SMEAR8(x) >> 16)) +#define WORKER_POW2_UP(n) (WORKER_SMEAR16((unsigned long)(n) - 1u) + 1u) + +// The ghost slot's pools: the library's own, borrowed from by every context no worker slot covers. +ParsMemoriaeInternae(ghost_plain, WORKER_POW2_UP(GHOST_PLAIN_WANT)); +ParsMemoriaeInternae(ghost_secure, WORKER_POW2_UP(GHOST_SECURE_WANT)); +LocusCarcerum(ghost_site, MMGR_MINIMUM_SECURITY(ghost_plain), MMGR_MAXIMUM_SECURITY(ghost_secure)); + +// What each worker slot borrows through. NULL is the ghost's. +static const MinimumSecurityGuard *s_plain[PROTOCORE_WORKER_COUNT]; +static const MaximumSecurityGuard *s_secure[PROTOCORE_WORKER_COUNT]; + +void protocore_cellblocks_bind(int worker, const MinimumSecurityGuard *plain, const MaximumSecurityGuard *secure) +{ + if (worker < 0 || worker >= PROTOCORE_WORKER_COUNT) + { + return; + } + s_plain[worker] = plain; + s_secure[worker] = secure; +} + +const MinimumSecurityGuard *protocore_plain_guard(void) +{ + const int w = protocore_worker_self(); + if (w >= 0 && w < PROTOCORE_WORKER_COUNT && s_plain[w] != NULL) + { + return s_plain[w]; + } + return &ghost_site.ghost_plain; +} + +const MaximumSecurityGuard *protocore_secure_guard(void) +{ + const int w = protocore_worker_self(); + if (w >= 0 && w < PROTOCORE_WORKER_COUNT && s_secure[w] != NULL) + { + return s_secure[w]; + } + return &ghost_site.ghost_secure; +} + +void *protocore_plain_persist(size_t n) +{ + void *p = protocore_plain_guard()->persistent_buf_alloc(n); + if (p != NULL) + { + mmgr_zero_buf(p, n); + } + return p; +} + +void *protocore_secure_persist(size_t n) +{ + void *p = protocore_secure_guard()->persistent_buf_alloc(n); + if (p != NULL) + { + mmgr_zero_buf(p, n); + } + return p; +} // --------------------------------------------------------------------------- // Worker tasks @@ -73,7 +211,7 @@ uint8_t *protocore_worker_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_WORKER_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_WORKER_BORROW); } return s_own.span; } diff --git a/src/server/core/worker/worker.h b/src/server/core/worker/worker.h index 91a277d7a..90a7c9d1e 100644 --- a/src/server/core/worker/worker.h +++ b/src/server/core/worker/worker.h @@ -26,15 +26,81 @@ #include "protocore_config.h" +#include "locus_carcerum/locus_carcerum.h" // the cellblock guards each worker slot borrows through + #if PROTOCORE_ENABLE_PREEMPT_QUEUE #include "server/core/preempt_queue/preempt_queue.h" // carried below as Session.workers->queue #endif PROTOCORE_BEGIN_DECLS -// Worker identity (protocore_worker_count / protocore_worker_self / protocore_worker_set_self) is declared in -// mmgr/arena.h, with the pools it indexes. This header is scheduling: starting, waking, stopping -// and deferring onto those workers. +// --------------------------------------------------------------------------- +// Worker identity +// --------------------------------------------------------------------------- + +/** @brief Number of server worker tasks (PROTOCORE_WORKER_COUNT). */ +int protocore_worker_count(void); + +/** + * @brief Worker id [0, count) of the calling task; 0 by default / single-worker. + * + * With PROTOCORE_WORKER_COUNT == 1 (the default) there is exactly one worker, so the answer is 0 by + * construction and this is an inline constant - no lookup, no call. Every borrow asks, so the + * multi-worker lookup is paid only where there is more than one worker to tell apart. + */ +#if PROTOCORE_WORKER_COUNT == 1 +PROTOCORE_INLINE int protocore_worker_self(void) +{ + return 0; +} +#else +int protocore_worker_self(void); +#endif + +/** @brief Bind the calling task/thread to worker id @p id (worker entry / tests). */ +void protocore_worker_set_self(int id); + +// --------------------------------------------------------------------------- +// Cellblocks - the memory each worker slot borrows from +// --------------------------------------------------------------------------- +// +// Each slot borrows through two MMgr cellblock guards: a minimum-security one for plaintext, whose +// bytes are left as they are on release, and a maximum-security one for key material, whose bytes +// are zeroed on release. A slot has exactly one accessor, the worker that owns it, so a borrow is a +// plain bump with no lock. +// +// The worker slots are the application's: it declares the pools and the LocusCarcerum over them in +// its own translation unit and hands the guards in through protocore_cellblocks_bind(). The ghost +// slot (PROTOCORE_GHOST_WORKER_SLOT) is the library's own, declared in worker.c. A slot nothing was +// bound to, and any context outside [0, PROTOCORE_WORKER_COUNT), borrows from the ghost. + +/** + * @brief Hand worker slot @p worker the guards it borrows through. + * + * @param worker a worker id in [0, PROTOCORE_WORKER_COUNT); anything else is ignored. + * @param plain the minimum-security guard for plaintext, or NULL to leave the slot on the ghost's. + * @param secure the maximum-security guard for key material, or NULL to leave it on the ghost's. + */ +void protocore_cellblocks_bind(int worker, const MinimumSecurityGuard *plain, const MaximumSecurityGuard *secure); + +/** @brief The plaintext guard the calling worker borrows through. Never NULL. */ +const MinimumSecurityGuard *protocore_plain_guard(void); + +/** @brief The key-material guard the calling worker borrows through. Never NULL. */ +const MaximumSecurityGuard *protocore_secure_guard(void); + +/** + * @brief @p n persistent plaintext bytes, zeroed, or NULL if the calling worker's cellblock is full. + * + * State that lasts across dispatches starts from zero, and a cellblock hands its cells back as + * they were, so this is the persistent borrow followed by the zeroing. + */ +void *protocore_plain_persist(size_t n); + +/** @brief @p n persistent key-material bytes, zeroed, or NULL if the calling worker's cellblock is full. */ +void *protocore_secure_persist(size_t n); + +// This header is also scheduling: starting, waking, stopping and deferring onto those workers. // --------------------------------------------------------------------------- // Worker tasks diff --git a/src/server/io/middleware/CMakeLists.txt b/src/server/io/middleware/CMakeLists.txt index 372c9ff2c..3ac828b5b 100644 --- a/src/server/io/middleware/CMakeLists.txt +++ b/src/server/io/middleware/CMakeLists.txt @@ -4,7 +4,7 @@ protocore_add_module(server/io/middleware SOURCES middleware.c PRIVATE_DEPS - mmgr/protoframe + mmgr server/clock shared/mime ) diff --git a/src/server/io/middleware/middleware.c b/src/server/io/middleware/middleware.c index b5d118c68..bd11e332f 100644 --- a/src/server/io/middleware/middleware.c +++ b/src/server/io/middleware/middleware.c @@ -10,13 +10,13 @@ * counter that answers 429 + Retry-After past the budget. */ -#include "mmgr/protoframe/protoframe.h" // the one frame engine +#include "numeros_scribo/numeros_scribo.h" // the one frame engine #include "protocore.h" #include "server/clock/clock.h" // protocore_millis: the library clock, not the platform's #include "shared/mime/mime.h" // PROTOCORE_MIME_TEXT_PLAIN // Retry-After carries one number and nothing else. -static const protocore_field RETRY_AFTER[] = {PROTOCORE_U32, PROTOCORE_END}; +static const mmgr_field RETRY_AFTER[] = {MMGR_U32, MMGR_END}; // --------------------------------------------------------------------------- // Middleware chain + built-in rate limiter @@ -110,8 +110,8 @@ proto_bool rate_limit_check(uint8_t slot_id) uint32_t remain_ms = (s_mw.rl_window_ms > elapsed) ? (s_mw.rl_window_ms - elapsed) : 0; char secs[12]; // Fails closed to an empty string on its own, so there is no failure arm to write here. - frame.build(secs, sizeof(secs), RETRY_AFTER, - (const protocore_fval[]){PROTOCORE_VU32((uint32_t)((remain_ms + 999) / 1000))}, 1); + EMBED_CALL(numer.build, NumerosCfg, .out = secs, .cap = sizeof(secs), .spec = RETRY_AFTER, + .vals = (const mmgr_fval[]){MMGR_VU32((uint32_t)((remain_ms + 999) / 1000))}, .nvals = 1); proto_add_response_header(slot_id, "Retry-After", secs); send_text(slot_id, 429, PROTOCORE_MIME_TEXT_PLAIN, "Too Many Requests"); return PROTO_TRUE; diff --git a/src/server/net/gateway/CMakeLists.txt b/src/server/net/gateway/CMakeLists.txt index 92bd281dd..e307c45ca 100644 --- a/src/server/net/gateway/CMakeLists.txt +++ b/src/server/net/gateway/CMakeLists.txt @@ -5,7 +5,7 @@ protocore_add_module(server/net/gateway GATE PROTOCORE_ENABLE_GATEWAY SOURCES gateway.c PRIVATE_DEPS - mmgr/protomem - mmgr/secure + mmgr + server/core/worker server/clock ) diff --git a/src/server/net/gateway/gateway.c b/src/server/net/gateway/gateway.c index 0a42def62..57c570548 100644 --- a/src/server/net/gateway/gateway.c +++ b/src/server/net/gateway/gateway.c @@ -15,8 +15,8 @@ #if PROTOCORE_ENABLE_GATEWAY -#include "mmgr/protomem/protomem.h" -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/net/gateway/gateway.h" #include "server/clock/clock.h" // protocore_millis(): the one time source the rate window reads @@ -53,8 +53,8 @@ static_assert(GATEWAY_OFF_CTX + sizeof(GatewayCtx) <= PROTOCORE_GATEWAY_BORROW, "PROTOCORE_GATEWAY_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(GATEWAY_OFF_CTX % _Alignof(GatewayCtx) == 0, @@ -154,7 +154,7 @@ uint8_t *protocore_gateway_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_GATEWAY_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_GATEWAY_BORROW); } return s_own.span; } @@ -162,12 +162,14 @@ uint8_t *protocore_gateway_span(void) void protocore_gateway_reset(uint8_t *work) { - mem.set(GATEWAY_CTX(work)->ports, 0, sizeof(GATEWAY_CTX(work)->ports)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = GATEWAY_CTX(work)->ports, .val = 0, + .bytes = sizeof(GATEWAY_CTX(work)->ports)); GATEWAY_CTX(work)->uplink = NULL; GATEWAY_CTX(work)->uplink_ctx = NULL; GATEWAY_CTX(work)->prefix = PROTOCORE_GW_DEFAULT_PREFIX; GATEWAY_CTX(work)->seq = 0; - mem.set(&GATEWAY_CTX(work)->stats, 0, sizeof(GATEWAY_CTX(work)->stats)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &GATEWAY_CTX(work)->stats, .val = 0, + .bytes = sizeof(GATEWAY_CTX(work)->stats)); } proto_bool protocore_gateway_add_port(uint8_t *work, const protocore_gateway_port_config *cfg) diff --git a/src/server/net/relay/relay/CMakeLists.txt b/src/server/net/relay/relay/CMakeLists.txt index e01ccec25..13987d104 100644 --- a/src/server/net/relay/relay/CMakeLists.txt +++ b/src/server/net/relay/relay/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(server/net/relay/relay GATE PROTOCORE_ENABLE_RELAY SOURCES relay.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/server/net/relay/relay/relay.c b/src/server/net/relay/relay/relay.c index bf6989321..472faa463 100644 --- a/src/server/net/relay/relay/relay.c +++ b/src/server/net/relay/relay/relay.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_RELAY -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "server/net/relay/relay/relay.h" PROTOCORE_BEGIN_DECLS @@ -111,7 +111,7 @@ void protocore_relay_init(uint8_t *work) { return; } - mem.set(r, 0, sizeof(*r)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = r, .val = 0, .bytes = sizeof(*r)); r->a = *client; r->b = *origin; } diff --git a/src/server/peripherals/ads1115/CMakeLists.txt b/src/server/peripherals/ads1115/CMakeLists.txt index 5ebbb3df7..9b6e5e025 100644 --- a/src/server/peripherals/ads1115/CMakeLists.txt +++ b/src/server/peripherals/ads1115/CMakeLists.txt @@ -5,8 +5,8 @@ protocore_add_module(server/peripherals/ads1115 GATE PROTOCORE_ENABLE_ADS1115 SOURCES ads1115.c PRIVATE_DEPS - mmgr/endian - mmgr/secure + mmgr + server/core/worker server/clock server/peripherals/i2c ) diff --git a/src/server/peripherals/ads1115/ads1115.c b/src/server/peripherals/ads1115/ads1115.c index b1949d490..38aba5e78 100644 --- a/src/server/peripherals/ads1115/ads1115.c +++ b/src/server/peripherals/ads1115/ads1115.c @@ -16,9 +16,9 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/endian/endian.h" // endian.wr16be / endian.rd16be: the registers are big-endian -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from -#include "server/clock/clock.h" // pcdelay +#include "endian/endian.h" // magna_extremitas.wr / magna_extremitas.rd: the registers are big-endian +#include "server/clock/clock.h" // pcdelay +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/ads1115/ads1115.h" #include "server/peripherals/i2c/i2c.h" @@ -51,7 +51,7 @@ uint8_t *protocore_ads1115_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_I2C_DEVICE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_I2C_DEVICE_BORROW); } return s_own.span; } @@ -126,8 +126,8 @@ static_assert(ADS1115_OFF_CTX + sizeof(Ads1115Ctx) <= PROTOCORE_I2C_DEVICE_BORRO "PROTOCORE_I2C_DEVICE_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(ADS1115_OFF_CTX % _Alignof(Ads1115Ctx) == 0, @@ -148,7 +148,8 @@ static uint8_t dev_addr(uint8_t *work) static proto_bool wr16(uint8_t *work, uint8_t reg, uint16_t v) { ADS1115_CTX(work)->frame[0] = reg; - (void)endian.wr16be(&ADS1115_CTX(work)->frame[1], v); + (void)EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = &ADS1115_CTX(work)->frame[1], .val = v, + .width = MMGR_ENDIAN_16); return protocore_i2c_write(dev_addr(work), ADS1115_CTX(work)->frame, sizeof(ADS1115_CTX(work)->frame)); } @@ -158,7 +159,7 @@ static proto_bool rd16(uint8_t *work, uint8_t reg, uint16_t *v) { return PROTO_FALSE; } - *v = endian.rd16be(ADS1115_CTX(work)->frame); + *v = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = ADS1115_CTX(work)->frame, .width = MMGR_ENDIAN_16); return PROTO_TRUE; } diff --git a/src/server/peripherals/dmx/CMakeLists.txt b/src/server/peripherals/dmx/CMakeLists.txt index 7e6bb0738..35c07a060 100644 --- a/src/server/peripherals/dmx/CMakeLists.txt +++ b/src/server/peripherals/dmx/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(server/peripherals/dmx GATE PROTOCORE_ENABLE_DMX SOURCES dmx.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/server/peripherals/dmx/dmx.c b/src/server/peripherals/dmx/dmx.c index b29e92fd3..d7a0ca8f1 100644 --- a/src/server/peripherals/dmx/dmx.c +++ b/src/server/peripherals/dmx/dmx.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_DMX -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "server/peripherals/dmx/dmx.h" PROTOCORE_BEGIN_DECLS @@ -46,7 +46,7 @@ void protocore_dmx_build(uint8_t *work) buf[0] = start_code; if (n) { - mem.cpy(buf + 1, channels, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 1, .src = channels, .bytes = n); } DmxV.n = total; } @@ -143,7 +143,7 @@ void protocore_dmx_rdm_build(uint8_t *work) buf[23] = pdl; if (pdl) { - mem.cpy(buf + 24, pdata, pdl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 24, .src = pdata, .bytes = pdl); } DmxV.rdm_checksum_args.buf = buf; DmxV.rdm_checksum_args.len = ml; diff --git a/src/server/peripherals/fdc2214/CMakeLists.txt b/src/server/peripherals/fdc2214/CMakeLists.txt index 9a612de8c..74cdd2f2a 100644 --- a/src/server/peripherals/fdc2214/CMakeLists.txt +++ b/src/server/peripherals/fdc2214/CMakeLists.txt @@ -5,7 +5,7 @@ protocore_add_module(server/peripherals/fdc2214 GATE PROTOCORE_ENABLE_FDC2214 SOURCES fdc2214.c PRIVATE_DEPS - mmgr/endian - mmgr/secure + mmgr + server/core/worker server/peripherals/i2c ) diff --git a/src/server/peripherals/fdc2214/fdc2214.c b/src/server/peripherals/fdc2214/fdc2214.c index 55fd551a8..53c28d04b 100644 --- a/src/server/peripherals/fdc2214/fdc2214.c +++ b/src/server/peripherals/fdc2214/fdc2214.c @@ -16,8 +16,8 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/endian/endian.h" // endian.wr16be / endian.rd16be: the registers are big-endian -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "endian/endian.h" // magna_extremitas.wr / magna_extremitas.rd: the registers are big-endian +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/fdc2214/fdc2214.h" #include "server/peripherals/i2c/i2c.h" @@ -40,7 +40,7 @@ uint8_t *protocore_fdc2214_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_I2C_DEVICE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_I2C_DEVICE_BORROW); } return s_own.span; } @@ -126,8 +126,8 @@ static_assert(FDC2214_OFF_CTX + sizeof(Fdc2214Ctx) <= PROTOCORE_I2C_DEVICE_BORRO "PROTOCORE_I2C_DEVICE_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(FDC2214_OFF_CTX % _Alignof(Fdc2214Ctx) == 0, @@ -151,14 +151,16 @@ static proto_bool read16(uint8_t *work, uint8_t reg, uint16_t *out) { return PROTO_FALSE; } - *out = endian.rd16be(FDC2214_CTX(work)->frame); + *out = + (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = FDC2214_CTX(work)->frame, .width = MMGR_ENDIAN_16); return PROTO_TRUE; } static proto_bool write16(uint8_t *work, uint8_t reg, uint16_t val) { FDC2214_CTX(work)->frame[0] = reg; - (void)endian.wr16be(&FDC2214_CTX(work)->frame[1], val); + (void)EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = &FDC2214_CTX(work)->frame[1], .val = val, + .width = MMGR_ENDIAN_16); return protocore_i2c_write(dev_addr(work), FDC2214_CTX(work)->frame, sizeof(FDC2214_CTX(work)->frame)); } @@ -189,7 +191,9 @@ void protocore_fdc2214_begin(uint8_t *work) size_t n = Fdc2214V.n; for (size_t i = 0; i + 3 <= n; i += 3) { - if (!write16(work, FDC2214_CTX(work)->config[i], endian.rd16be(&FDC2214_CTX(work)->config[i + 1]))) + if (!write16(work, FDC2214_CTX(work)->config[i], + (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = &FDC2214_CTX(work)->config[i + 1], + .width = MMGR_ENDIAN_16))) { Fdc2214V.ok = PROTO_FALSE; return; diff --git a/src/server/peripherals/hmmd/CMakeLists.txt b/src/server/peripherals/hmmd/CMakeLists.txt index d9399862b..730d8b29f 100644 --- a/src/server/peripherals/hmmd/CMakeLists.txt +++ b/src/server/peripherals/hmmd/CMakeLists.txt @@ -5,7 +5,7 @@ protocore_add_module(server/peripherals/hmmd GATE PROTOCORE_ENABLE_HMMD SOURCES hmmd.c PRIVATE_DEPS - mmgr/protomem - mmgr/secure + mmgr + server/core/worker server/peripherals/uart ) diff --git a/src/server/peripherals/hmmd/hmmd.c b/src/server/peripherals/hmmd/hmmd.c index 091fb0a13..5493e2c67 100644 --- a/src/server/peripherals/hmmd/hmmd.c +++ b/src/server/peripherals/hmmd/hmmd.c @@ -14,8 +14,8 @@ #if PROTOCORE_ENABLE_HMMD -#include "mmgr/protomem/protomem.h" -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/hmmd/hmmd.h" PROTOCORE_BEGIN_DECLS @@ -52,8 +52,8 @@ static_assert(HMMD_OFF_CTX + sizeof(HmmdCtx) <= PROTOCORE_HMMD_BORROW, "PROTOCORE_HMMD_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(HMMD_OFF_CTX % _Alignof(HmmdCtx) == 0, @@ -92,7 +92,7 @@ uint8_t *protocore_hmmd_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_HMMD_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_HMMD_BORROW); } return s_own.span; } @@ -115,7 +115,7 @@ static void hmmd_parse_report(uint8_t *work) Hmmd.ok = PROTO_FALSE; return; } - if (mem.cmp(f, HDR, 4) != 0) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = f, .other = HDR, .bytes = 4) != 0) { Hmmd.ok = PROTO_FALSE; return; @@ -125,7 +125,7 @@ static void hmmd_parse_report(uint8_t *work) Hmmd.ok = PROTO_FALSE; return; // the only report length this module emits } - if (mem.cmp(f + 6 + PROTOCORE_HMMD_REPORT_LEN, FTR, 4) != 0) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = f + 6 + PROTOCORE_HMMD_REPORT_LEN, .other = FTR, .bytes = 4) != 0) { Hmmd.ok = PROTO_FALSE; return; @@ -133,7 +133,7 @@ static void hmmd_parse_report(uint8_t *work) const uint8_t *p = f + 6; HmmdReport r; - mem.set(&r, 0, sizeof(r)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &r, .val = 0, .bytes = sizeof(r)); r.detected = (p[0] == 0x01) ? 1u : 0u; r.distance_cm = rd16(p + 1); for (int i = 0; i < PROTOCORE_HMMD_GATES; i++) @@ -391,7 +391,7 @@ static void hmmd_parse_ack(uint8_t *work) Hmmd.ok = PROTO_FALSE; return; } - if (mem.cmp(f, CMD_HDR, 4) != 0) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = f, .other = CMD_HDR, .bytes = 4) != 0) { Hmmd.ok = PROTO_FALSE; return; @@ -402,7 +402,7 @@ static void hmmd_parse_ack(uint8_t *work) Hmmd.ok = PROTO_FALSE; return; // the declared length must account for exactly this frame } - if (mem.cmp(f + 6 + dl, CMD_FTR, 4) != 0) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = f + 6 + dl, .other = CMD_FTR, .bytes = 4) != 0) { Hmmd.ok = PROTO_FALSE; return; diff --git a/src/server/peripherals/ina219/CMakeLists.txt b/src/server/peripherals/ina219/CMakeLists.txt index c27472587..0afef9c0b 100644 --- a/src/server/peripherals/ina219/CMakeLists.txt +++ b/src/server/peripherals/ina219/CMakeLists.txt @@ -5,7 +5,7 @@ protocore_add_module(server/peripherals/ina219 GATE PROTOCORE_ENABLE_INA219 SOURCES ina219.c PRIVATE_DEPS - mmgr/endian - mmgr/secure + mmgr + server/core/worker server/peripherals/i2c ) diff --git a/src/server/peripherals/ina219/ina219.c b/src/server/peripherals/ina219/ina219.c index 82d179c61..7fcf24713 100644 --- a/src/server/peripherals/ina219/ina219.c +++ b/src/server/peripherals/ina219/ina219.c @@ -16,8 +16,8 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/endian/endian.h" // endian.wr16be / endian.rd16be: the registers are big-endian -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "endian/endian.h" // magna_extremitas.wr / magna_extremitas.rd: the registers are big-endian +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/i2c/i2c.h" #include "server/peripherals/ina219/ina219.h" @@ -40,7 +40,7 @@ uint8_t *protocore_ina219_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_I2C_DEVICE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_I2C_DEVICE_BORROW); } return s_own.span; } @@ -124,8 +124,8 @@ static_assert(INA219_OFF_CTX + sizeof(Ina219Ctx) <= PROTOCORE_I2C_DEVICE_BORROW, "PROTOCORE_I2C_DEVICE_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(INA219_OFF_CTX % _Alignof(Ina219Ctx) == 0, @@ -153,7 +153,8 @@ static uint32_t dev_lsb_ua(uint8_t *work) static proto_bool wr16(uint8_t *work, uint8_t reg, uint16_t v) { INA219_CTX(work)->frame[0] = reg; - (void)endian.wr16be(&INA219_CTX(work)->frame[1], v); + (void)EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = &INA219_CTX(work)->frame[1], .val = v, + .width = MMGR_ENDIAN_16); return protocore_i2c_write(dev_addr(work), INA219_CTX(work)->frame, sizeof(INA219_CTX(work)->frame)); } @@ -164,7 +165,7 @@ static proto_bool rd16(uint8_t *work, uint8_t reg, uint16_t *v) { return PROTO_FALSE; } - *v = endian.rd16be(INA219_CTX(work)->frame); + *v = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = INA219_CTX(work)->frame, .width = MMGR_ENDIAN_16); return PROTO_TRUE; } diff --git a/src/server/peripherals/ld2410/CMakeLists.txt b/src/server/peripherals/ld2410/CMakeLists.txt index e26c6d2ee..f8a541e04 100644 --- a/src/server/peripherals/ld2410/CMakeLists.txt +++ b/src/server/peripherals/ld2410/CMakeLists.txt @@ -5,7 +5,7 @@ protocore_add_module(server/peripherals/ld2410 GATE PROTOCORE_ENABLE_LD2410 SOURCES ld2410.c PRIVATE_DEPS - mmgr/protomem - mmgr/secure + mmgr + server/core/worker server/peripherals/uart ) diff --git a/src/server/peripherals/ld2410/ld2410.c b/src/server/peripherals/ld2410/ld2410.c index 571fbbb74..e00fbf8a3 100644 --- a/src/server/peripherals/ld2410/ld2410.c +++ b/src/server/peripherals/ld2410/ld2410.c @@ -16,8 +16,8 @@ #if PROTOCORE_ENABLE_LD2410 -#include "mmgr/protomem/protomem.h" -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/ld2410/ld2410.h" PROTOCORE_BEGIN_DECLS @@ -56,8 +56,8 @@ static_assert(LD2410_OFF_CTX + sizeof(Ld2410Ctx) <= PROTOCORE_LD2410_BORROW, "PROTOCORE_LD2410_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(LD2410_OFF_CTX % _Alignof(Ld2410Ctx) == 0, @@ -127,7 +127,7 @@ uint8_t *protocore_ld2410_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_LD2410_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_LD2410_BORROW); } return s_own.span; } @@ -153,7 +153,7 @@ static void ld2410_parse_report(uint8_t *work) Ld2410.ok = PROTO_FALSE; return; } - if (mem.cmp(f, HDR, 4) != 0) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = f, .other = HDR, .bytes = 4) != 0) { Ld2410.ok = PROTO_FALSE; return; @@ -164,7 +164,7 @@ static void ld2410_parse_report(uint8_t *work) Ld2410.ok = PROTO_FALSE; return; // length field must frame the buffer exactly } - if (mem.cmp(f + 6 + dl, FTR, 4) != 0) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = f + 6 + dl, .other = FTR, .bytes = 4) != 0) { Ld2410.ok = PROTO_FALSE; return; @@ -172,7 +172,7 @@ static void ld2410_parse_report(uint8_t *work) const uint8_t *p = f + 6; Ld2410Report r; - mem.set(&r, 0, sizeof(r)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &r, .val = 0, .bytes = sizeof(r)); if (p[0] == 0x02) { if (dl != LEN_BASIC) diff --git a/src/server/peripherals/ldc1614/CMakeLists.txt b/src/server/peripherals/ldc1614/CMakeLists.txt index 0f6d26545..0bc55b438 100644 --- a/src/server/peripherals/ldc1614/CMakeLists.txt +++ b/src/server/peripherals/ldc1614/CMakeLists.txt @@ -5,7 +5,7 @@ protocore_add_module(server/peripherals/ldc1614 GATE PROTOCORE_ENABLE_LDC1614 SOURCES ldc1614.c PRIVATE_DEPS - mmgr/endian - mmgr/secure + mmgr + server/core/worker server/peripherals/i2c ) diff --git a/src/server/peripherals/ldc1614/ldc1614.c b/src/server/peripherals/ldc1614/ldc1614.c index fd85686c7..036b7664d 100644 --- a/src/server/peripherals/ldc1614/ldc1614.c +++ b/src/server/peripherals/ldc1614/ldc1614.c @@ -16,8 +16,8 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/endian/endian.h" // endian.wr16be / endian.rd16be: the registers are big-endian -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "endian/endian.h" // magna_extremitas.wr / magna_extremitas.rd: the registers are big-endian +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/i2c/i2c.h" #include "server/peripherals/ldc1614/ldc1614.h" @@ -40,7 +40,7 @@ uint8_t *protocore_ldc1614_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_I2C_DEVICE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_I2C_DEVICE_BORROW); } return s_own.span; } @@ -125,8 +125,8 @@ static_assert(LDC1614_OFF_CTX + sizeof(Ldc1614Ctx) <= PROTOCORE_I2C_DEVICE_BORRO "PROTOCORE_I2C_DEVICE_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(LDC1614_OFF_CTX % _Alignof(Ldc1614Ctx) == 0, @@ -150,14 +150,16 @@ static proto_bool read16(uint8_t *work, uint8_t reg, uint16_t *out) { return PROTO_FALSE; } - *out = endian.rd16be(LDC1614_CTX(work)->frame); + *out = + (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = LDC1614_CTX(work)->frame, .width = MMGR_ENDIAN_16); return PROTO_TRUE; } static proto_bool write16(uint8_t *work, uint8_t reg, uint16_t val) { LDC1614_CTX(work)->frame[0] = reg; - (void)endian.wr16be(&LDC1614_CTX(work)->frame[1], val); + (void)EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = &LDC1614_CTX(work)->frame[1], .val = val, + .width = MMGR_ENDIAN_16); return protocore_i2c_write(dev_addr(work), LDC1614_CTX(work)->frame, sizeof(LDC1614_CTX(work)->frame)); } @@ -188,7 +190,9 @@ void protocore_ldc1614_begin(uint8_t *work) size_t n = Ldc1614V.n; for (size_t i = 0; i + 3 <= n; i += 3) { - if (!write16(work, LDC1614_CTX(work)->config[i], endian.rd16be(&LDC1614_CTX(work)->config[i + 1]))) + if (!write16(work, LDC1614_CTX(work)->config[i], + (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = &LDC1614_CTX(work)->config[i + 1], + .width = MMGR_ENDIAN_16))) { Ldc1614V.ok = PROTO_FALSE; return; diff --git a/src/server/peripherals/mpr121/CMakeLists.txt b/src/server/peripherals/mpr121/CMakeLists.txt index e33e25990..2459ea846 100644 --- a/src/server/peripherals/mpr121/CMakeLists.txt +++ b/src/server/peripherals/mpr121/CMakeLists.txt @@ -5,8 +5,8 @@ protocore_add_module(server/peripherals/mpr121 GATE PROTOCORE_ENABLE_MPR121 SOURCES mpr121.c PRIVATE_DEPS - mmgr/protomem - mmgr/secure + mmgr + server/core/worker server/clock server/peripherals/i2c ) diff --git a/src/server/peripherals/mpr121/mpr121.c b/src/server/peripherals/mpr121/mpr121.c index 99a975882..a9c9a1e4c 100644 --- a/src/server/peripherals/mpr121/mpr121.c +++ b/src/server/peripherals/mpr121/mpr121.c @@ -20,9 +20,9 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/protomem/protomem.h" -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from -#include "server/clock/clock.h" // pcdelay +#include "memoria_operor/memoria_operor.h" +#include "server/clock/clock.h" // pcdelay +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/i2c/i2c.h" #include "server/peripherals/mpr121/mpr121.h" @@ -45,7 +45,7 @@ uint8_t *protocore_mpr121_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_MPR121_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_MPR121_BORROW); } return s_own.span; } @@ -129,7 +129,7 @@ void protocore_mpr121_build_init(uint8_t *work) return; } size_t i = sizeof(fixed); - mem.cpy(buf, fixed, sizeof(fixed)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf, .src = fixed, .bytes = sizeof(fixed)); for (uint8_t e = 0; e < n; e++) { buf[i++] = (uint8_t)(0x41 + 2 * e); // touch threshold reg @@ -171,8 +171,8 @@ static_assert(MPR121_OFF_CTX + sizeof(Mpr121Ctx) <= PROTOCORE_MPR121_BORROW, "PROTOCORE_MPR121_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(MPR121_OFF_CTX % _Alignof(Mpr121Ctx) == 0, diff --git a/src/server/peripherals/pca9685/CMakeLists.txt b/src/server/peripherals/pca9685/CMakeLists.txt index 12897619d..d98ca8486 100644 --- a/src/server/peripherals/pca9685/CMakeLists.txt +++ b/src/server/peripherals/pca9685/CMakeLists.txt @@ -5,7 +5,8 @@ protocore_add_module(server/peripherals/pca9685 GATE PROTOCORE_ENABLE_PCA9685 SOURCES pca9685.c PRIVATE_DEPS - mmgr/secure + mmgr + server/core/worker server/clock server/peripherals/i2c ) diff --git a/src/server/peripherals/pca9685/pca9685.c b/src/server/peripherals/pca9685/pca9685.c index 7838d4fc2..6970e79a1 100644 --- a/src/server/peripherals/pca9685/pca9685.c +++ b/src/server/peripherals/pca9685/pca9685.c @@ -19,8 +19,8 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from -#include "server/clock/clock.h" // protocore_delay_us: the oscillator settle in begin() +#include "server/clock/clock.h" // protocore_delay_us: the oscillator settle in begin() +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/i2c/i2c.h" #include "server/peripherals/pca9685/pca9685.h" @@ -47,7 +47,7 @@ uint8_t *protocore_pca9685_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_I2C_DEVICE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_I2C_DEVICE_BORROW); } return s_own.span; } @@ -151,8 +151,8 @@ static_assert(PCA9685_OFF_CTX + sizeof(Pca9685Ctx) <= PROTOCORE_I2C_DEVICE_BORRO "PROTOCORE_I2C_DEVICE_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(PCA9685_OFF_CTX % _Alignof(Pca9685Ctx) == 0, diff --git a/src/server/peripherals/rcwl0516/CMakeLists.txt b/src/server/peripherals/rcwl0516/CMakeLists.txt index ec0c139cd..c6a49e53c 100644 --- a/src/server/peripherals/rcwl0516/CMakeLists.txt +++ b/src/server/peripherals/rcwl0516/CMakeLists.txt @@ -5,6 +5,7 @@ protocore_add_module(server/peripherals/rcwl0516 GATE PROTOCORE_ENABLE_RCWL0516 SOURCES rcwl0516.c PRIVATE_DEPS - mmgr/plaintext + mmgr + server/core/worker server/clock ) diff --git a/src/server/peripherals/rcwl0516/rcwl0516.c b/src/server/peripherals/rcwl0516/rcwl0516.c index caca013ff..09e72c7a9 100644 --- a/src/server/peripherals/rcwl0516/rcwl0516.c +++ b/src/server/peripherals/rcwl0516/rcwl0516.c @@ -16,8 +16,8 @@ #if PROTOCORE_ENABLE_RCWL0516 -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "server/clock/clock.h" // Clock.millis +#include "server/clock/clock.h" // Clock.millis +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/rcwl0516/rcwl0516.h" #if !PROTOCORE_HAS_GPIO @@ -50,7 +50,7 @@ uint8_t *protocore_rcwl0516_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_RCWL0516_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_RCWL0516_BORROW); } return s_own.span; } @@ -161,8 +161,8 @@ static_assert(RCWL0516_OFF_CTX + sizeof(Rcwl0516Ctx) <= PROTOCORE_RCWL0516_BORRO "PROTOCORE_RCWL0516_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(RCWL0516_OFF_CTX % _Alignof(Rcwl0516Ctx) == 0, diff --git a/src/server/peripherals/rtc/CMakeLists.txt b/src/server/peripherals/rtc/CMakeLists.txt index d2d2a273c..4c35b14d6 100644 --- a/src/server/peripherals/rtc/CMakeLists.txt +++ b/src/server/peripherals/rtc/CMakeLists.txt @@ -5,6 +5,7 @@ protocore_add_module(server/peripherals/rtc GATE PROTOCORE_ENABLE_RTC SOURCES rtc.c PRIVATE_DEPS - mmgr/secure + mmgr + server/core/worker server/peripherals/i2c ) diff --git a/src/server/peripherals/rtc/rtc.c b/src/server/peripherals/rtc/rtc.c index 958e9a3e2..c278576d4 100644 --- a/src/server/peripherals/rtc/rtc.c +++ b/src/server/peripherals/rtc/rtc.c @@ -19,7 +19,7 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/i2c/i2c.h" #include "server/peripherals/rtc/rtc.h" @@ -77,7 +77,7 @@ uint8_t *protocore_rtc_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_I2C_DEVICE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_I2C_DEVICE_BORROW); } return s_own.span; } @@ -166,8 +166,8 @@ static_assert(RTC_OFF_CTX + sizeof(RtcCtx) <= PROTOCORE_I2C_DEVICE_BORROW, "PROTOCORE_I2C_DEVICE_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(RTC_OFF_CTX % _Alignof(RtcCtx) == 0, diff --git a/src/server/peripherals/sdi12/CMakeLists.txt b/src/server/peripherals/sdi12/CMakeLists.txt index feefb9633..71e9c3661 100644 --- a/src/server/peripherals/sdi12/CMakeLists.txt +++ b/src/server/peripherals/sdi12/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(server/peripherals/sdi12 GATE PROTOCORE_ENABLE_SDI12 SOURCES sdi12.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr shared/crc ) diff --git a/src/server/peripherals/sdi12/sdi12.c b/src/server/peripherals/sdi12/sdi12.c index 80489ffa0..6ddbf4803 100644 --- a/src/server/peripherals/sdi12/sdi12.c +++ b/src/server/peripherals/sdi12/sdi12.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_SDI12 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "server/peripherals/sdi12/sdi12.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" #include "shared/crc/crc.h" // PROTOCORE_CRC16_ARC PROTOCORE_BEGIN_DECLS @@ -41,7 +41,7 @@ void protocore_sdi12_build(uint8_t *work) Sdi12V.n = 0; return; } - size_t blen = str.len(body, cap); + size_t blen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = body, .cap = cap); size_t n = 1 + blen + 1; // addr + body + '!' if (cap < n + 1) // + room for the NUL terminator { @@ -49,7 +49,7 @@ void protocore_sdi12_build(uint8_t *work) return; } buf[0] = addr; - mem.cpy(buf + 1, body, blen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 1, .src = body, .bytes = blen); buf[1 + blen] = '!'; buf[n] = '\0'; Sdi12V.n = n; @@ -283,13 +283,13 @@ void protocore_sdi12_parse_measure(uint8_t *work) } for (int i = 1; i <= 3; i++) { - if (!str.digit(resp[i])) + if (!EMBED_CALL(cellul.digit, CatenaFinitaCfg, .src = resp, .at = i)) { Sdi12V.ok = PROTO_FALSE; return; } } - if (!str.digit(resp[4])) + if (!EMBED_CALL(cellul.digit, CatenaFinitaCfg, .src = resp, .at = 4)) { Sdi12V.ok = PROTO_FALSE; return; @@ -304,7 +304,7 @@ void protocore_sdi12_parse_measure(uint8_t *work) } // The value count is the remaining digits (1 digit for aM!, 2 for aC!). uint16_t count = 0; - for (size_t i = 4; i < len && str.digit(resp[i]); i++) + for (size_t i = 4; i < len && EMBED_CALL(cellul.digit, CatenaFinitaCfg, .src = resp, .at = i); i++) { count = (uint16_t)(count * 10 + (resp[i] - '0')); } @@ -342,8 +342,9 @@ void protocore_sdi12_parse_values(uint8_t *work) { const char *start = resp + i; const char *end = start; - // str.to_float handles a leading '-'; for '+' parse the magnitude after the sign. - float v = (c == '+') ? str.to_float(start + 1, &end) : str.to_float(start, &end); + // cellul.to_float handles a leading '-'; for '+' parse the magnitude after the sign. + float v = (c == '+') ? EMBED_CALL(cellul.to_float, TransfiguroCfg, .src = start + 1, .end = &end) + : EMBED_CALL(cellul.to_float, TransfiguroCfg, .src = start, .end = &end); if (end == start || (c == '+' && end == start + 1)) // no digits consumed { i++; @@ -374,13 +375,13 @@ void protocore_sdi12_parse_identify(uint8_t *work) return; } out->addr = resp[0]; - mem.cpy(out->sdi_version, resp + 1, 2); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->sdi_version, .src = resp + 1, .bytes = 2); out->sdi_version[2] = '\0'; - mem.cpy(out->vendor, resp + 3, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->vendor, .src = resp + 3, .bytes = 8); out->vendor[8] = '\0'; - mem.cpy(out->model, resp + 11, 6); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->model, .src = resp + 11, .bytes = 6); out->model[6] = '\0'; - mem.cpy(out->sensor_version, resp + 17, 3); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->sensor_version, .src = resp + 17, .bytes = 3); out->sensor_version[3] = '\0'; Sdi12V.ok = PROTO_TRUE; } @@ -443,7 +444,7 @@ void protocore_sdi12_check_crc(uint8_t *work) Sdi12V.crc_encode_args.crc = crc; Sdi12V.crc_encode_args.out = enc; protocore_sdi12_crc_encode(work); - Sdi12V.ok = mem.cmp(enc, resp + data_len, SDI12_CRC_CHARS) == 0; + Sdi12V.ok = EMBED_CALL(memor.cmp, MemoriaCfg, .src = enc, .other = resp + data_len, .bytes = SDI12_CRC_CHARS) == 0; } /** @brief The operands and the outcome. */ diff --git a/src/server/peripherals/sen0192/CMakeLists.txt b/src/server/peripherals/sen0192/CMakeLists.txt index 472c313ed..1d0987369 100644 --- a/src/server/peripherals/sen0192/CMakeLists.txt +++ b/src/server/peripherals/sen0192/CMakeLists.txt @@ -5,6 +5,7 @@ protocore_add_module(server/peripherals/sen0192 GATE PROTOCORE_ENABLE_SEN0192 SOURCES sen0192.c PRIVATE_DEPS - mmgr/plaintext + mmgr + server/core/worker server/clock ) diff --git a/src/server/peripherals/sen0192/sen0192.c b/src/server/peripherals/sen0192/sen0192.c index 45e8a3d4e..2f938113b 100644 --- a/src/server/peripherals/sen0192/sen0192.c +++ b/src/server/peripherals/sen0192/sen0192.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_SEN0192 -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/sen0192/sen0192.h" #if !PROTOCORE_HAS_GPIO @@ -42,7 +42,7 @@ uint8_t *protocore_sen0192_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_SEN0192_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_SEN0192_BORROW); } return s_own.span; } @@ -132,8 +132,8 @@ static_assert(SEN0192_OFF_CTX + sizeof(Sen0192Ctx) <= PROTOCORE_SEN0192_BORROW, "PROTOCORE_SEN0192_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(SEN0192_OFF_CTX % _Alignof(Sen0192Ctx) == 0, diff --git a/src/server/peripherals/sht3x/CMakeLists.txt b/src/server/peripherals/sht3x/CMakeLists.txt index 7af2a5c71..25582d8fa 100644 --- a/src/server/peripherals/sht3x/CMakeLists.txt +++ b/src/server/peripherals/sht3x/CMakeLists.txt @@ -5,8 +5,8 @@ protocore_add_module(server/peripherals/sht3x GATE PROTOCORE_ENABLE_SHT3X SOURCES sht3x.c PRIVATE_DEPS - mmgr/endian - mmgr/secure + mmgr + server/core/worker server/clock server/peripherals/i2c shared/crc diff --git a/src/server/peripherals/sht3x/sht3x.c b/src/server/peripherals/sht3x/sht3x.c index 39e0eb816..197c49464 100644 --- a/src/server/peripherals/sht3x/sht3x.c +++ b/src/server/peripherals/sht3x/sht3x.c @@ -16,9 +16,9 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/endian/endian.h" // endian.wr16be: the commands and words are big-endian -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from -#include "server/clock/clock.h" // pcdelay +#include "endian/endian.h" // magna_extremitas.wr: the commands and words are big-endian +#include "server/clock/clock.h" // pcdelay +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/i2c/i2c.h" #include "server/peripherals/sht3x/sht3x.h" #include "shared/crc/crc.h" // PROTOCORE_CRC8_NRSC5 @@ -42,7 +42,7 @@ uint8_t *protocore_sht3x_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_I2C_DEVICE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_I2C_DEVICE_BORROW); } return s_own.span; } @@ -149,8 +149,8 @@ static_assert(SHT3X_OFF_CTX + sizeof(Sht3xCtx) <= PROTOCORE_I2C_DEVICE_BORROW, "PROTOCORE_I2C_DEVICE_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(SHT3X_OFF_CTX % _Alignof(Sht3xCtx) == 0, @@ -171,7 +171,8 @@ static uint8_t dev_addr(uint8_t *work) // A command is a bare 16-bit word, big-endian, with no register byte in front of it. static proto_bool send_cmd(uint8_t *work, uint16_t cmd) { - (void)endian.wr16be(SHT3X_CTX(work)->frame, cmd); + (void)EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = SHT3X_CTX(work)->frame, .val = cmd, + .width = MMGR_ENDIAN_16); return protocore_i2c_write(dev_addr(work), SHT3X_CTX(work)->frame, 2); } diff --git a/src/server/peripherals/smbus/CMakeLists.txt b/src/server/peripherals/smbus/CMakeLists.txt index 2a0330b86..4e2a3d90e 100644 --- a/src/server/peripherals/smbus/CMakeLists.txt +++ b/src/server/peripherals/smbus/CMakeLists.txt @@ -5,7 +5,8 @@ protocore_add_module(server/peripherals/smbus GATE PROTOCORE_ENABLE_SMBUS SOURCES smbus.c PRIVATE_DEPS - mmgr/secure + mmgr + server/core/worker server/peripherals/i2c shared/crc ) diff --git a/src/server/peripherals/smbus/smbus.c b/src/server/peripherals/smbus/smbus.c index 09ae42f07..408f4d0e3 100644 --- a/src/server/peripherals/smbus/smbus.c +++ b/src/server/peripherals/smbus/smbus.c @@ -20,7 +20,7 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/i2c/i2c.h" #include "server/peripherals/smbus/smbus.h" #include "shared/crc/crc.h" // PROTOCORE_CRC8_SMBUS: the PEC polynomial, host-tested in test_crc @@ -45,8 +45,8 @@ static_assert(SMBUS_OFF_CTX + sizeof(SmbusCtx) <= PROTOCORE_SMBUS_BORROW, "PROTOCORE_SMBUS_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(SMBUS_OFF_CTX % _Alignof(SmbusCtx) == 0, @@ -73,7 +73,7 @@ uint8_t *protocore_smbus_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_SMBUS_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_SMBUS_BORROW); } return s_own.span; } diff --git a/src/server/peripherals/vl53l0x/CMakeLists.txt b/src/server/peripherals/vl53l0x/CMakeLists.txt index 16873c5d6..5fbf33129 100644 --- a/src/server/peripherals/vl53l0x/CMakeLists.txt +++ b/src/server/peripherals/vl53l0x/CMakeLists.txt @@ -5,6 +5,7 @@ protocore_add_module(server/peripherals/vl53l0x GATE PROTOCORE_ENABLE_VL53L0X SOURCES vl53l0x.c PRIVATE_DEPS - mmgr/secure + mmgr + server/core/worker server/peripherals/i2c ) diff --git a/src/server/peripherals/vl53l0x/vl53l0x.c b/src/server/peripherals/vl53l0x/vl53l0x.c index 0e2c7cf44..f9f3bdb05 100644 --- a/src/server/peripherals/vl53l0x/vl53l0x.c +++ b/src/server/peripherals/vl53l0x/vl53l0x.c @@ -16,7 +16,7 @@ turn the driver off - there is no software stand-in for a part on the other end of a bus." #endif -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/peripherals/i2c/i2c.h" #include "server/peripherals/vl53l0x/vl53l0x.h" @@ -39,7 +39,7 @@ uint8_t *protocore_vl53l0x_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_I2C_DEVICE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_I2C_DEVICE_BORROW); } return s_own.span; } @@ -101,8 +101,8 @@ static_assert(VL53L0X_OFF_CTX + sizeof(Vl53l0xCtx) <= PROTOCORE_I2C_DEVICE_BORRO "PROTOCORE_I2C_DEVICE_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(VL53L0X_OFF_CTX % _Alignof(Vl53l0xCtx) == 0, diff --git a/src/server/signaling/bus_capture/CMakeLists.txt b/src/server/signaling/bus_capture/CMakeLists.txt index 0cb63de32..48b17b84b 100644 --- a/src/server/signaling/bus_capture/CMakeLists.txt +++ b/src/server/signaling/bus_capture/CMakeLists.txt @@ -7,6 +7,7 @@ protocore_add_module(server/signaling/bus_capture DEPS shared/can PRIVATE_DEPS - mmgr/secure + mmgr + server/core/worker shared/pcap ) diff --git a/src/server/signaling/bus_capture/bus_capture.c b/src/server/signaling/bus_capture/bus_capture.c index 70f8cdbc8..0cd48a8b2 100644 --- a/src/server/signaling/bus_capture/bus_capture.c +++ b/src/server/signaling/bus_capture/bus_capture.c @@ -14,7 +14,7 @@ #if PROTOCORE_ENABLE_BUS_CAPTURE #include "config/platform/platform.h" -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/signaling/bus_capture/bus_capture.h" #include "shared/pcap/pcap.h" @@ -35,7 +35,7 @@ uint8_t *protocore_bus_capture_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_BUS_CAPTURE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_BUS_CAPTURE_BORROW); } return s_own.span; } @@ -101,8 +101,8 @@ static_assert(BUS_CAPTURE_OFF_CTX + sizeof(BusCaptureCtx) <= PROTOCORE_BUS_CAPTU "PROTOCORE_BUS_CAPTURE_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert( diff --git a/src/server/signaling/device_id/CMakeLists.txt b/src/server/signaling/device_id/CMakeLists.txt index eccbb14b9..b14734935 100644 --- a/src/server/signaling/device_id/CMakeLists.txt +++ b/src/server/signaling/device_id/CMakeLists.txt @@ -6,7 +6,7 @@ protocore_add_module(server/signaling/device_id SOURCES device_id.c PRIVATE_DEPS crypto/hash/sha1 - mmgr/secure - mmgr/span + mmgr + server/core/worker shared/hex ) diff --git a/src/server/signaling/device_id/device_id.c b/src/server/signaling/device_id/device_id.c index d42bdb3c8..92a31dfe2 100644 --- a/src/server/signaling/device_id/device_id.c +++ b/src/server/signaling/device_id/device_id.c @@ -12,8 +12,7 @@ #if PROTOCORE_ENABLE_DEVICE_ID #include "crypto/hash/sha1/sha1.h" -#include "mmgr/secure/secure.h" // the pool the digest borrow comes from -#include "mmgr/span/span.h" // protocore_span, span.ok +#include "server/core/worker/worker.h" // protocore_secure_guard: the cellblock the digest borrow comes from PROTOCORE_BEGIN_DECLS @@ -49,16 +48,17 @@ void protocore_device_id_from_mac(uint8_t *work) } uint8_t h[PROTOCORE_SHA1_DIGEST_LEN]; - const size_t mark = protocore_secure_mark(); - protocore_span w = protocore_secure_span(PROTOCORE_SHA1_BORROW, 8); - if (!span.ok(w)) + const MaximumSecurityGuard *guard = protocore_secure_guard(); + const size_t mark = guard->temporary_buf_mark(); + uint8_t *w = (uint8_t *)guard->temporary_buf_alloc(PROTOCORE_SHA1_BORROW); + if (!w) { - protocore_secure_release(mark); + guard->temporary_buf_release(mark); out[0] = '\0'; return; } - Sha1.hash(w.buf, input, sizeof(input), h); - protocore_secure_release(mark); + Sha1.hash(w, input, sizeof(input), h); + guard->temporary_buf_release(mark); h[6] = (uint8_t)((h[6] & 0x0F) | 0x50); // version 5 h[8] = (uint8_t)((h[8] & 0x3F) | 0x80); // RFC 4122 variant diff --git a/src/server/signaling/gpio_map/CMakeLists.txt b/src/server/signaling/gpio_map/CMakeLists.txt index 7fd701833..64496d67a 100644 --- a/src/server/signaling/gpio_map/CMakeLists.txt +++ b/src/server/signaling/gpio_map/CMakeLists.txt @@ -5,8 +5,6 @@ protocore_add_module(server/signaling/gpio_map GATE PROTOCORE_ENABLE_GPIO_MAP SOURCES gpio_map.c PRIVATE_DEPS - mmgr/protoframe - mmgr/protomem - mmgr/protostr + mmgr server/clock ) diff --git a/src/server/signaling/gpio_map/gpio_map.c b/src/server/signaling/gpio_map/gpio_map.c index bb711c3a6..cca1db184 100644 --- a/src/server/signaling/gpio_map/gpio_map.c +++ b/src/server/signaling/gpio_map/gpio_map.c @@ -15,12 +15,12 @@ #if PROTOCORE_ENABLE_GPIO_MAP -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "server/clock/clock.h" // protocore_millis() #include "server/signaling/gpio_map/gpio_map.h" -#include "mmgr/protoframe/protoframe.h" +#include "numeros_scribo/numeros_scribo.h" PROTOCORE_BEGIN_DECLS @@ -54,21 +54,21 @@ void protocore_gpio_map_dir_name(uint8_t *work) // The item index selects it; !!i is 0 or 1, so the separator is a load rather than a branch. static const char *const PROTOCORE_JSON_SEP[2] = {"", ","}; -static const protocore_field GPIO_OPEN[] = {{PROTOCORE_FK_LIT, 0, 9, "{\"pins\":["}, PROTOCORE_END}; -static const protocore_field GPIO_PIN[] = { - PROTOCORE_STR, // "," from the second pin on - {PROTOCORE_FK_LIT, 0, 7, "{\"pin\":"}, // - PROTOCORE_U32, // pin number - {PROTOCORE_FK_LIT, 0, 9, ",\"label\":"}, // - PROTOCORE_JSON, // label, quoted and escaped - {PROTOCORE_FK_LIT, 0, 7, ",\"dir\":"}, // - PROTOCORE_JSON, // direction name - {PROTOCORE_FK_LIT, 0, 9, ",\"level\":"}, // - PROTOCORE_U32, // 0 or 1 - {PROTOCORE_FK_LIT, 0, 1, "}"}, // - PROTOCORE_END, +static const mmgr_field GPIO_OPEN[] = {{MMGR_FK_LIT, 0, 9, "{\"pins\":["}, MMGR_END}; +static const mmgr_field GPIO_PIN[] = { + MMGR_STR, // "," from the second pin on + {MMGR_FK_LIT, 0, 7, "{\"pin\":"}, // + MMGR_U32, // pin number + {MMGR_FK_LIT, 0, 9, ",\"label\":"}, // + MMGR_JSON, // label, quoted and escaped + {MMGR_FK_LIT, 0, 7, ",\"dir\":"}, // + MMGR_JSON, // direction name + {MMGR_FK_LIT, 0, 9, ",\"level\":"}, // + MMGR_U32, // 0 or 1 + {MMGR_FK_LIT, 0, 1, "}"}, // + MMGR_END, }; -static const protocore_field GPIO_CLOSE[] = {{PROTOCORE_FK_LIT, 0, 2, "]}"}, PROTOCORE_END}; +static const mmgr_field GPIO_CLOSE[] = {{MMGR_FK_LIT, 0, 2, "]}"}, MMGR_END}; void protocore_gpio_map_json(uint8_t *work) { @@ -89,7 +89,7 @@ void protocore_gpio_map_json(uint8_t *work) GpioMapV.n = -1; return; } - if (frame.append(out, cap, GPIO_OPEN, NULL, 0) == 0) + if (EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = GPIO_OPEN, .vals = NULL, .nvals = 0) == 0) { GpioMapV.n = -1; return; @@ -97,19 +97,19 @@ void protocore_gpio_map_json(uint8_t *work) for (uint8_t i = 0; i < count; i++) { const protocore_gpio_pin *p = &pins[i]; - if (frame.append(out, cap, GPIO_PIN, - (const protocore_fval[]){PROTOCORE_VSTR(PROTOCORE_JSON_SEP[!!i]), - PROTOCORE_VU32((uint32_t)p->pin), PROTOCORE_VJSON(p->label), - PROTOCORE_VJSON(dir_name_of(p->dir)), - PROTOCORE_VU32((uint32_t)(!!p->level))}, - 5) == 0) + if (EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = GPIO_PIN, + .vals = (const mmgr_fval[]){MMGR_VSTR(PROTOCORE_JSON_SEP[!!i]), MMGR_VU32((uint32_t)p->pin), + MMGR_VJSON(p->label), MMGR_VJSON(dir_name_of(p->dir)), + MMGR_VU32((uint32_t)(!!p->level))}, + .nvals = 5) == 0) { GpioMapV.n = -1; return; } } // A document always carries its two braces, so nothing written is the close not fitting. - const int32_t written = (int32_t)frame.append(out, cap, GPIO_CLOSE, NULL, 0); + const int32_t written = (int32_t)EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = GPIO_CLOSE, + .vals = NULL, .nvals = 0); GpioMapV.n = (written == 0) ? -1 : written; } @@ -117,11 +117,12 @@ void protocore_gpio_map_json(uint8_t *work) // false if the field is absent or has no digits. static proto_bool form_field_uint(const char *body, size_t len, const char *name, unsigned *out) { - size_t nlen = str.len(name, len + 1); + size_t nlen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = name, .cap = len + 1); for (size_t i = 0; i + nlen + 1 <= len; i++) { proto_bool at_field = (i == 0) || body[i - 1] == '&'; - if (!at_field || mem.cmp(body + i, name, nlen) != 0 || body[i + nlen] != '=') + if (!at_field || EMBED_CALL(memor.cmp, MemoriaCfg, .src = body + i, .other = name, .bytes = nlen) != 0 || + body[i + nlen] != '=') { continue; } diff --git a/src/server/signaling/hw_health/CMakeLists.txt b/src/server/signaling/hw_health/CMakeLists.txt index 454253259..59cbf911e 100644 --- a/src/server/signaling/hw_health/CMakeLists.txt +++ b/src/server/signaling/hw_health/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(server/signaling/hw_health GATE PROTOCORE_ENABLE_HW_HEALTH SOURCES hw_health.c PRIVATE_DEPS - mmgr/membuild + mmgr ) diff --git a/src/server/signaling/hw_health/hw_health.c b/src/server/signaling/hw_health/hw_health.c index 21815891a..504de0518 100644 --- a/src/server/signaling/hw_health/hw_health.c +++ b/src/server/signaling/hw_health/hw_health.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_HW_HEALTH -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder #include "server/signaling/hw_health/hw_health.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -71,22 +71,22 @@ void protocore_hw_health_rail_json(uint8_t *work) { return; } - protocore_sb b = {out, cap, 0, PROTO_TRUE}; - Sb.put(&b, "{\"nominal_mv\":"); - Sb.u32(&b, m->nominal_mv); - Sb.put(&b, ",\"min_mv\":"); - Sb.u32(&b, m->min_mv); - Sb.put(&b, ",\"sag\":"); - Sb.u32(&b, m->sag_events); - Sb.put(&b, ",\"brownout\":"); - Sb.u32(&b, m->brownout_events); - Sb.put(&b, "}"); - if (!b.ok) + size_t b = 0; + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "{\"nominal_mv\":"); + b = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = b, .val = m->nominal_mv); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"min_mv\":"); + b = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = b, .val = m->min_mv); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"sag\":"); + b = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = b, .val = m->sag_events); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"brownout\":"); + b = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = b, .val = m->brownout_events); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "}"); + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = b)) { return; } - out[b.len] = '\0'; - HwHealthV.n = b.len; + out[b] = '\0'; + HwHealthV.n = b; } void protocore_hw_health_spi_init(uint8_t *work) diff --git a/src/server/signaling/trace_capture/CMakeLists.txt b/src/server/signaling/trace_capture/CMakeLists.txt index 4c77d3d72..daceba651 100644 --- a/src/server/signaling/trace_capture/CMakeLists.txt +++ b/src/server/signaling/trace_capture/CMakeLists.txt @@ -5,7 +5,7 @@ protocore_add_module(server/signaling/trace_capture GATE PROTOCORE_ENABLE_TRACE_CAPTURE SOURCES trace_capture.c PRIVATE_DEPS - mmgr/plaintext - mmgr/protomem + mmgr + server/core/worker server/clock ) diff --git a/src/server/signaling/trace_capture/trace_capture.c b/src/server/signaling/trace_capture/trace_capture.c index 7dbfd67f9..a44fad88d 100644 --- a/src/server/signaling/trace_capture/trace_capture.c +++ b/src/server/signaling/trace_capture/trace_capture.c @@ -18,8 +18,8 @@ #if PROTOCORE_ENABLE_TRACE_CAPTURE -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/signaling/trace_capture/trace_capture.h" #include "server/clock/clock.h" // protocore_cycles() @@ -74,7 +74,7 @@ uint8_t *protocore_trace_capture_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_TRACE_CAPTURE_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_TRACE_CAPTURE_BORROW); } return s_own.span; } @@ -112,7 +112,8 @@ void protocore_trace_capture_begin(uint8_t *work) return; } - mem.set(TRACE_CAPTURE_CTX(work), 0, sizeof(*TRACE_CAPTURE_CTX(work))); + EMBED_CALL(memor.set, MemoriaCfg, .dst = TRACE_CAPTURE_CTX(work), .val = 0, + .bytes = sizeof(*TRACE_CAPTURE_CTX(work))); TRACE_CAPTURE_CTX(work)->sink = cfg->sink; TRACE_CAPTURE_CTX(work)->ctx = cfg->ctx; TRACE_CAPTURE_CTX(work)->pretrigger_samples = cfg->pretrigger_samples; diff --git a/src/server/storage/config_store/CMakeLists.txt b/src/server/storage/config_store/CMakeLists.txt index 5f4d608f8..5a258c60d 100644 --- a/src/server/storage/config_store/CMakeLists.txt +++ b/src/server/storage/config_store/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(server/storage/config_store GATE PROTOCORE_ENABLE_CONFIG_STORE SOURCES config_store.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr - mmgr/secure + mmgr + server/core/worker ) diff --git a/src/server/storage/config_store/config_store.c b/src/server/storage/config_store/config_store.c index 54c182415..2691bbd32 100644 --- a/src/server/storage/config_store/config_store.c +++ b/src/server/storage/config_store/config_store.c @@ -14,10 +14,10 @@ #if PROTOCORE_ENABLE_CONFIG_STORE +#include "cellularum_laboro/cellularum_laboro.h" #include "config_store.h" -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "test/core_setup/hal/nvs.h" @@ -37,8 +37,8 @@ static_assert(CONFIG_STORE_OFF_CTX + sizeof(ConfigStoreCtx) <= PROTOCORE_CONFIG_ "PROTOCORE_CONFIG_STORE_BORROW is short of the module context - raise it in protocore_config.h, which\n" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert( @@ -64,7 +64,7 @@ uint8_t *protocore_config_store_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_CONFIG_STORE_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_CONFIG_STORE_BORROW); } return s_own.span; } @@ -74,13 +74,15 @@ void protocore_config_store_begin(uint8_t *work) (void)work; const char *ns = ConfigStoreV.begin_args.ns; - if (!ns || !ns[0] || str.len(ns, PROTOCORE_CONFIG_KEY_MAX) >= PROTOCORE_CONFIG_KEY_MAX) + if (!ns || !ns[0] || + EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = ns, .cap = PROTOCORE_CONFIG_KEY_MAX) >= PROTOCORE_CONFIG_KEY_MAX) { CONFIG_STORE_CTX(work)->ns[0] = '\0'; ConfigStoreV.ok = PROTO_FALSE; return; } - str.copy(CONFIG_STORE_CTX(work)->ns, ns, sizeof(CONFIG_STORE_CTX(work)->ns)); + EMBED_CALL(cellul.copy, CatenaFinitaCfg, .dst = CONFIG_STORE_CTX(work)->ns, .src = ns, + .cap = sizeof(CONFIG_STORE_CTX(work)->ns)); CONFIG_STORE_CTX(work)->ns[PROTOCORE_CONFIG_KEY_MAX - 1] = '\0'; ConfigStoreV.ok = PROTO_TRUE; return; @@ -117,14 +119,14 @@ void protocore_config_store_get_str(uint8_t *work) return; } // Absent: the default is this layer's, so the seam never has to know there is one. - n = def ? str.len(def, out_cap) : 0; + n = def ? EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = def, .cap = out_cap) : 0; if (n > out_cap - 1) { n = out_cap - 1; } if (n) { - mem.cpy(out, def, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = def, .bytes = n); } out[n] = '\0'; ConfigStoreV.n = n; diff --git a/src/server/storage/filesystem/CMakeLists.txt b/src/server/storage/filesystem/CMakeLists.txt index f3309cec0..314cb4adc 100644 --- a/src/server/storage/filesystem/CMakeLists.txt +++ b/src/server/storage/filesystem/CMakeLists.txt @@ -4,10 +4,7 @@ protocore_add_module(server/storage/filesystem SOURCES filesystem.c DEPS - mmgr/protoframe + mmgr + server/core/worker server/storage/mnt - PRIVATE_DEPS - mmgr/plaintext - mmgr/protomem - mmgr/protostr ) diff --git a/src/server/storage/filesystem/filesystem.c b/src/server/storage/filesystem/filesystem.c index 8b2446e31..04b119453 100644 --- a/src/server/storage/filesystem/filesystem.c +++ b/src/server/storage/filesystem/filesystem.c @@ -10,11 +10,11 @@ */ #include "server/storage/filesystem/filesystem.h" -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" // str: the bounded-run walks - // strncmp (root-name match), memcpy -#include "server/storage/mnt/mnt.h" // Mnt.active: the filesystem every call works through +#include "cellularum_laboro/cellularum_laboro.h" // str: the bounded-run walks +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from + // strncmp (root-name match), memcpy +#include "server/storage/mnt/mnt.h" // Mnt.active: the filesystem every call works through // One bound root. The prefix is a copy, not the caller's pointer, and always ends '/', so the join // concatenates `root` and `dir` without adding a separator. @@ -55,8 +55,8 @@ static_assert(FILESYSTEM_OFF_CTX + sizeof(FilesystemCtx) <= PROTOCORE_FILESYSTEM "PROTOCORE_FILESYSTEM_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert( @@ -82,7 +82,7 @@ uint8_t *protocore_filesystem_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_FILESYSTEM_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_FILESYSTEM_BORROW); } return s_own.span; } @@ -105,7 +105,7 @@ static const protocore_mnt_backend *store(uint8_t *work) // name into a different file's. static size_t walk_push(char *path, size_t len, const char *child) { - size_t n = str.len(child, PROTOCORE_FILESYSTEM_PATH_MAX); + size_t n = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = child, .cap = PROTOCORE_FILESYSTEM_PATH_MAX); // The root already IS the separator, so it is the one path that does not get another. proto_bool need_sep = !(len == 1 && path[0] == '/'); if (len + (need_sep ? 1 : 0) + n + 1 > PROTOCORE_FILESYSTEM_PATH_MAX) @@ -116,7 +116,7 @@ static size_t walk_push(char *path, size_t len, const char *child) { path[len++] = '/'; } - mem.cpy(path + len, child, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = path + len, .src = child, .bytes = n); len += n; path[len] = '\0'; return len; @@ -190,7 +190,8 @@ static void fs_begin(uint8_t *work) // give them two views of one thing. for (uint8_t i = 0; i < FILESYSTEM_CTX(work)->count; i++) { - if (str.eq(FILESYSTEM_CTX(work)->root[i].name, want, PROTOCORE_FS_ROOT_NAME_MAX, PROTO_FALSE)) + if (EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = FILESYSTEM_CTX(work)->root[i].name, .other = want, + .cap = PROTOCORE_FS_ROOT_NAME_MAX, .ci = PROTO_FALSE)) { Fs.i32 = (int)i; return; @@ -205,8 +206,8 @@ static void fs_begin(uint8_t *work) FsRoot *r = &FILESYSTEM_CTX(work)->root[FILESYSTEM_CTX(work)->count]; // One byte of the capacity is held back for the separator below, so appending cannot overrun. - size_t n = frame.build(r->path, PROTOCORE_FILESYSTEM_PATH_MAX - 1, FILESYSTEM_ROOT, - (const protocore_fval[]){PROTOCORE_VSTR(want)}, 1); + size_t n = EMBED_CALL(numer.build, NumerosCfg, .out = r->path, .cap = PROTOCORE_FILESYSTEM_PATH_MAX - 1, + .spec = FILESYSTEM_ROOT, .vals = (const mmgr_fval[]){MMGR_VSTR(want)}, .nvals = 1); if (n == 0) // a root that does not fit - refused, not truncated into another directory { Fs.i32 = -1; @@ -217,8 +218,8 @@ static void fs_begin(uint8_t *work) r->path[n] = '/'; // the separator the join relies on, added once here rather than r->path[n + 1] = '\0'; // tested on every resolve } - if (frame.build(r->name, PROTOCORE_FS_ROOT_NAME_MAX, FILESYSTEM_ROOT, - (const protocore_fval[]){PROTOCORE_VSTR(want)}, 1) == 0) + if (EMBED_CALL(numer.build, NumerosCfg, .out = r->name, .cap = PROTOCORE_FS_ROOT_NAME_MAX, .spec = FILESYSTEM_ROOT, + .vals = (const mmgr_fval[]){MMGR_VSTR(want)}, .nvals = 1) == 0) { Fs.i32 = -1; return; // a name too long to record is a name that could not be matched again @@ -366,8 +367,8 @@ static void fs_remove(uint8_t *work) // Destination resolving here (a mount with an empty fs_root, target "/") turned that into // "remove everything", after which the copy failed and answered 409 over an emptied volume. const char *rp = FILESYSTEM_CTX(work)->root[root].path; - size_t rlen = str.len(rp, PROTOCORE_FILESYSTEM_PATH_MAX); - size_t plen = str.len(p, PROTOCORE_FILESYSTEM_PATH_MAX); + size_t rlen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = rp, .cap = PROTOCORE_FILESYSTEM_PATH_MAX); + size_t plen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = p, .cap = PROTOCORE_FILESYSTEM_PATH_MAX); if (rlen > 0 && rp[rlen - 1] == '/') // the root always carries the separator; a resolve may not { rlen--; @@ -376,7 +377,7 @@ static void fs_remove(uint8_t *work) { plen--; } - if (plen == rlen && mem.cmp(p, rp, plen) == 0) + if (plen == rlen && EMBED_CALL(memor.cmp, MemoriaCfg, .src = p, .other = rp, .bytes = plen) == 0) { FILESYSTEM_CTX(work)->status |= PROTOCORE_FS_BAD_ROOT; Fs.ok = PROTO_FALSE; @@ -402,8 +403,9 @@ static void fs_remove(uint8_t *work) // child, finishing a level truncates back. Each pass re-opens the current level and takes its // first surviving entry, so the cursor is never carried across a removal that would invalidate // it - whatever the previous pass removed is already gone when the next open happens. - size_t len = frame.build(FILESYSTEM_CTX(work)->walk, PROTOCORE_FILESYSTEM_PATH_MAX, FILESYSTEM_ROOT, - (const protocore_fval[]){PROTOCORE_VSTR(p)}, 1); + size_t len = + EMBED_CALL(numer.build, NumerosCfg, .out = FILESYSTEM_CTX(work)->walk, .cap = PROTOCORE_FILESYSTEM_PATH_MAX, + .spec = FILESYSTEM_ROOT, .vals = (const mmgr_fval[]){MMGR_VSTR(p)}, .nvals = 1); if (len == 0) { Fs.ok = PROTO_FALSE; @@ -466,7 +468,8 @@ static void fs_remove(uint8_t *work) Fs.ok = PROTO_FALSE; return; // refuse a pathologically deep tree rather than walk forever } - len = str.len(FILESYSTEM_CTX(work)->walk, PROTOCORE_FILESYSTEM_PATH_MAX); + len = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = FILESYSTEM_CTX(work)->walk, + .cap = PROTOCORE_FILESYSTEM_PATH_MAX); lvl++; } } @@ -553,10 +556,12 @@ static void fs_copy(uint8_t *work) return; } - size_t slen = frame.build(FILESYSTEM_CTX(work)->walk, PROTOCORE_FILESYSTEM_PATH_MAX, FILESYSTEM_ROOT, - (const protocore_fval[]){PROTOCORE_VSTR(sp)}, 1); - size_t dlen = frame.build(FILESYSTEM_CTX(work)->dwalk, PROTOCORE_FILESYSTEM_PATH_MAX, FILESYSTEM_ROOT, - (const protocore_fval[]){PROTOCORE_VSTR(dp)}, 1); + size_t slen = + EMBED_CALL(numer.build, NumerosCfg, .out = FILESYSTEM_CTX(work)->walk, .cap = PROTOCORE_FILESYSTEM_PATH_MAX, + .spec = FILESYSTEM_ROOT, .vals = (const mmgr_fval[]){MMGR_VSTR(sp)}, .nvals = 1); + size_t dlen = + EMBED_CALL(numer.build, NumerosCfg, .out = FILESYSTEM_CTX(work)->dwalk, .cap = PROTOCORE_FILESYSTEM_PATH_MAX, + .spec = FILESYSTEM_ROOT, .vals = (const mmgr_fval[]){MMGR_VSTR(dp)}, .nvals = 1); if (slen == 0 || dlen == 0) { Fs.ok = PROTO_FALSE; @@ -651,7 +656,8 @@ static void fs_copy(uint8_t *work) Fs.ok = PROTO_FALSE; return; } - slen = str.len(FILESYSTEM_CTX(work)->walk, PROTOCORE_FILESYSTEM_PATH_MAX); + slen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = FILESYSTEM_CTX(work)->walk, + .cap = PROTOCORE_FILESYSTEM_PATH_MAX); dlen = ndlen; lvl++; FILESYSTEM_CTX(work)->idx[lvl] = 0; diff --git a/src/server/storage/filesystem/filesystem.h b/src/server/storage/filesystem/filesystem.h index 9f4d3dcf0..dab9c4eaa 100644 --- a/src/server/storage/filesystem/filesystem.h +++ b/src/server/storage/filesystem/filesystem.h @@ -31,7 +31,7 @@ #ifndef PROTOCORE_FILESYSTEM_H #define PROTOCORE_FILESYSTEM_H -#include "mmgr/protoframe/protoframe.h" // the one frame engine +#include "numeros_scribo/numeros_scribo.h" // the one frame engine #include "server/storage/mnt/mnt.h" #include "protocore_config.h" @@ -42,10 +42,10 @@ PROTOCORE_BEGIN_DECLS // dir+name itself and handed the result over would frame the same bytes twice, into two buffers, // for the same result. A mount root ends with '/', and a dir that carries a name ends with '/', so // both separators are already in the strings and the spec needs no literal between the fields. -static const protocore_field FILESYSTEM_JOIN[] = {PROTOCORE_STR, PROTOCORE_STR, PROTOCORE_STR, PROTOCORE_END}; +static const mmgr_field FILESYSTEM_JOIN[] = {MMGR_STR, MMGR_STR, MMGR_STR, MMGR_END}; // The mount root, copied in so its trailing '/' is owned rather than assumed (see protocore_fs_begin). -static const protocore_field FILESYSTEM_ROOT[] = {PROTOCORE_STR, PROTOCORE_END}; +static const mmgr_field FILESYSTEM_ROOT[] = {MMGR_STR, MMGR_END}; /** * @brief Roots that can be bound at once (see protocore_fs_begin). @@ -105,8 +105,8 @@ PROTOCORE_INLINE size_t protocore_fs_join(const char *root, const char *dir, con { dir++; // the root carries the separator; a second one would be "//" } - return frame.build(out, cap, FILESYSTEM_JOIN, - (const protocore_fval[]){PROTOCORE_VSTR(root), PROTOCORE_VSTR(dir), PROTOCORE_VSTR(name)}, 3); + return EMBED_CALL(numer.build, NumerosCfg, .out = out, .cap = cap, .spec = FILESYSTEM_JOIN, + .vals = (const mmgr_fval[]){MMGR_VSTR(root), MMGR_VSTR(dir), MMGR_VSTR(name)}, .nvals = 3); } /** @@ -160,7 +160,7 @@ PROTOCORE_INLINE int protocore_fs_resolve(const char *root, const char *dir, con // and do local-only path work before (or without) ever attaching a store. What it must not do is // look identical to a fault. // -// So the reason is a sticky mask, the same way protocore_cspan carries a sticky ok: bits accumulate as +// So the reason is a sticky mask, the same way mmgr_cspan carries a sticky err: bits accumulate as // operations fail and a caller tests once, at whatever granularity suits it, instead of branching on // every call. Mask it for the bit you care about. // diff --git a/src/server/storage/hotswap/CMakeLists.txt b/src/server/storage/hotswap/CMakeLists.txt index bd0ad3445..7560d6626 100644 --- a/src/server/storage/hotswap/CMakeLists.txt +++ b/src/server/storage/hotswap/CMakeLists.txt @@ -5,7 +5,7 @@ protocore_add_module(server/storage/hotswap GATE PROTOCORE_ENABLE_HOTSWAP SOURCES hotswap.c PRIVATE_DEPS - mmgr/membuild - mmgr/secure + mmgr + server/core/worker server/clock ) diff --git a/src/server/storage/hotswap/hotswap.c b/src/server/storage/hotswap/hotswap.c index d7ce1689d..c9dd66cde 100644 --- a/src/server/storage/hotswap/hotswap.c +++ b/src/server/storage/hotswap/hotswap.c @@ -10,9 +10,9 @@ #if PROTOCORE_ENABLE_HOTSWAP -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/storage/hotswap/hotswap.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain #include "server/clock/clock.h" // protocore_millis @@ -39,7 +39,7 @@ uint8_t *protocore_hotswap_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_HOTSWAP_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_HOTSWAP_BORROW); } return s_own.span; } @@ -179,8 +179,8 @@ static_assert(HOTSWAP_OFF_CTX + sizeof(HotswapCtx) <= PROTOCORE_HOTSWAP_BORROW, "PROTOCORE_HOTSWAP_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(HOTSWAP_OFF_CTX % _Alignof(HotswapCtx) == 0, @@ -340,20 +340,24 @@ void protocore_hotswap_json(uint8_t *work) HotswapV.n = 0; return; } - protocore_sb sb_out = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out, "{\"storage\":\""); + size_t sb_out = 0; + sb_out = + EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = "{\"storage\":\""); HotswapV.state_name_args.s = HOTSWAP_CTX(work)->core.state; protocore_hotswap_state_name(work); - Sb.put(&sb_out, HotswapV.text); - Sb.put(&sb_out, "\",\"mounts\":"); - Sb.u32(&sb_out, (uint32_t)((unsigned)HOTSWAP_CTX(work)->core.mounts)); - Sb.put(&sb_out, ",\"faults\":"); - Sb.u32(&sb_out, (uint32_t)((unsigned)HOTSWAP_CTX(work)->core.faults)); - Sb.put(&sb_out, "}"); - int n = (int)Sb.finish(&sb_out); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = HotswapV.text); + sb_out = + EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = "\",\"mounts\":"); + sb_out = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint32_t)((unsigned)HOTSWAP_CTX(work)->core.mounts)); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = ",\"faults\":"); + sb_out = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint32_t)((unsigned)HOTSWAP_CTX(work)->core.faults)); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = "}"); + int n = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out); // `n < 0` has no true branch to reach: the format is a fixed literal with no encoding-dependent // conversion and cap == 0 was rejected above, so snprintf can only ever report truncation here. - if (!sb_out.ok) + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = sb_out)) { out[0] = '\0'; HotswapV.n = 0; diff --git a/src/server/storage/mnt_ram/CMakeLists.txt b/src/server/storage/mnt_ram/CMakeLists.txt index d47bfd75e..0dde3475d 100644 --- a/src/server/storage/mnt_ram/CMakeLists.txt +++ b/src/server/storage/mnt_ram/CMakeLists.txt @@ -7,6 +7,5 @@ protocore_add_module(server/storage/mnt_ram DEPS server/storage/mnt PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/server/storage/mnt_ram/mnt_ram.c b/src/server/storage/mnt_ram/mnt_ram.c index c464b4c0a..7ad5d5086 100644 --- a/src/server/storage/mnt_ram/mnt_ram.c +++ b/src/server/storage/mnt_ram/mnt_ram.c @@ -14,8 +14,8 @@ #if PROTOCORE_ENABLE_MNT -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "server/storage/mnt_ram/mnt_ram.h" typedef struct @@ -60,7 +60,8 @@ static int ram_find(const char *name) { for (int i = 0; i < PROTOCORE_MNT_RAM_FILES; i++) { - if (ram_used(i) && str.eq(s_mnt.rf[i].name, name, PROTOCORE_MNT_NAME_MAX, PROTO_FALSE)) + if (ram_used(i) && EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = s_mnt.rf[i].name, .other = name, + .cap = PROTOCORE_MNT_NAME_MAX, .ci = PROTO_FALSE)) { return i; } @@ -70,7 +71,8 @@ static int ram_find(const char *name) static int ram_create(const char *name, proto_bool is_dir) { - if (str.len(name, PROTOCORE_MNT_NAME_MAX + 1) >= PROTOCORE_MNT_NAME_MAX) + if (EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = name, .cap = PROTOCORE_MNT_NAME_MAX + 1) >= + PROTOCORE_MNT_NAME_MAX) { return -1; } @@ -82,7 +84,7 @@ static int ram_create(const char *name, proto_bool is_dir) int i = (int)__builtin_ctz(free_bits); s_mnt.used |= (1u << i); s_mnt.rf[i].is_dir = is_dir; - str.copy(s_mnt.rf[i].name, name, sizeof(s_mnt.rf[i].name)); + EMBED_CALL(cellul.copy, CatenaFinitaCfg, .dst = s_mnt.rf[i].name, .src = name, .cap = sizeof(s_mnt.rf[i].name)); s_mnt.rf[i].name[PROTOCORE_MNT_NAME_MAX - 1] = '\0'; s_mnt.rf[i].len = 0; return i; @@ -116,8 +118,8 @@ static const char *ram_dirpath(const RamHandle *h) // own name. The root prefix is "/" and carries its own separator; any other prefix needs one. static proto_bool ram_child_of(const char *name, const char *prefix, const char **rest) { - size_t plen = str.len(prefix, PROTOCORE_MNT_NAME_MAX); - if (!str.starts(name, prefix, plen, PROTO_FALSE)) + size_t plen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = prefix, .cap = PROTOCORE_MNT_NAME_MAX); + if (!EMBED_CALL(cellul.starts, CatenaFinitaCfg, .src = name, .other = prefix, .cap = plen, .ci = PROTO_FALSE)) { return PROTO_FALSE; } @@ -131,7 +133,8 @@ static proto_bool ram_child_of(const char *name, const char *prefix, const char tail++; } if (tail[0] == '\0' || - str.find(tail, PROTOCORE_MNT_NAME_MAX - (size_t)(tail - name), "/", sizeof("/"), PROTO_FALSE) != NULL) + EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = tail, .cap = PROTOCORE_MNT_NAME_MAX - (size_t)(tail - name), + .other = "/", .other_cap = sizeof("/"), .ci = PROTO_FALSE) != NULL) { return PROTO_FALSE; // the prefix itself, or something deeper than one level } @@ -195,7 +198,7 @@ static int ram_read(int h, void *buf, size_t n) RamFile *f = &s_mnt.rf[s_mnt.rh[h].file]; size_t avail = (s_mnt.rh[h].pos < f->len) ? (f->len - s_mnt.rh[h].pos) : 0; size_t k = n < avail ? n : avail; - mem.cpy(buf, f->data + s_mnt.rh[h].pos, k); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf, .src = f->data + s_mnt.rh[h].pos, .bytes = k); s_mnt.rh[h].pos += k; return (int)(k); } @@ -209,7 +212,7 @@ static int ram_write(int h, const void *buf, size_t n) RamFile *f = &s_mnt.rf[s_mnt.rh[h].file]; size_t cap = (s_mnt.rh[h].pos < PROTOCORE_MNT_RAM_FILE_SIZE) ? (PROTOCORE_MNT_RAM_FILE_SIZE - s_mnt.rh[h].pos) : 0; size_t k = n < cap ? n : cap; - mem.cpy(f->data + s_mnt.rh[h].pos, buf, k); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = f->data + s_mnt.rh[h].pos, .src = buf, .bytes = k); s_mnt.rh[h].pos += k; if (s_mnt.rh[h].pos > f->len) { @@ -263,7 +266,8 @@ static proto_bool ram_remove(const char *path) static proto_bool ram_rename(const char *from, const char *to) { - if (from == NULL || to == NULL || str.len(to, PROTOCORE_MNT_NAME_MAX + 1) >= PROTOCORE_MNT_NAME_MAX) + if (from == NULL || to == NULL || + EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = to, .cap = PROTOCORE_MNT_NAME_MAX + 1) >= PROTOCORE_MNT_NAME_MAX) { return PROTO_FALSE; } @@ -277,7 +281,7 @@ static proto_bool ram_rename(const char *from, const char *to) { s_mnt.used &= ~(1u << dst); // overwrite an existing destination } - str.copy(s_mnt.rf[f].name, to, sizeof(s_mnt.rf[f].name)); + EMBED_CALL(cellul.copy, CatenaFinitaCfg, .dst = s_mnt.rf[f].name, .src = to, .cap = sizeof(s_mnt.rf[f].name)); s_mnt.rf[f].name[PROTOCORE_MNT_NAME_MAX - 1] = '\0'; return PROTO_TRUE; } @@ -382,12 +386,12 @@ static proto_bool ram_readdir(int h, protocore_mnt_stat *out, char *name, size_t { continue; } - size_t rl = str.len(rest, name_cap); + size_t rl = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = rest, .cap = name_cap); if (rl >= name_cap) { continue; // the caller's buffer cannot hold this name - skip it rather than truncate } - mem.cpy(name, rest, rl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = name, .src = rest, .bytes = rl); name[rl] = '\0'; ram_fill_stat(&s_mnt.rf[i], out); s_mnt.rh[h].pos = i + 1; diff --git a/src/server/storage/partition_monitor/CMakeLists.txt b/src/server/storage/partition_monitor/CMakeLists.txt index dbc2c5830..6b7f0a589 100644 --- a/src/server/storage/partition_monitor/CMakeLists.txt +++ b/src/server/storage/partition_monitor/CMakeLists.txt @@ -5,8 +5,7 @@ protocore_add_module(server/storage/partition_monitor GATE PROTOCORE_ENABLE_PARTITION_MONITOR SOURCES partition_monitor.c PRIVATE_DEPS - mmgr/protoframe - mmgr/protostr + mmgr ) add_subdirectory(partition_monitor_routes) diff --git a/src/server/storage/partition_monitor/partition_monitor.c b/src/server/storage/partition_monitor/partition_monitor.c index ef4d311c4..f778e6c40 100644 --- a/src/server/storage/partition_monitor/partition_monitor.c +++ b/src/server/storage/partition_monitor/partition_monitor.c @@ -16,8 +16,8 @@ #include "server/storage/partition_monitor/partition_monitor.h" -#include "mmgr/protoframe/protoframe.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "numeros_scribo/numeros_scribo.h" #include "protocore.h" // on_http: the route table the begin entry installs on PROTOCORE_BEGIN_DECLS @@ -95,27 +95,27 @@ void protocore_partition_monitor_kind(uint8_t *work) // The item index selects it; !!i is 0 or 1, so the separator is a load rather than a branch. static const char *const PROTOCORE_JSON_SEP[2] = {"", ","}; -static const protocore_field PART_OPEN[] = {{PROTOCORE_FK_LIT, 0, 15, "{\"partitions\":["}, PROTOCORE_END}; -static const protocore_field PART_ENTRY[] = { - PROTOCORE_STR, // "," from the second entry on - {PROTOCORE_FK_LIT, 0, 9, "{\"label\":"}, // - PROTOCORE_JSON, // label - {PROTOCORE_FK_LIT, 0, 8, ",\"kind\":"}, // - PROTOCORE_JSON, // kind name - {PROTOCORE_FK_LIT, 0, 8, ",\"type\":"}, // - PROTOCORE_U32, // - {PROTOCORE_FK_LIT, 0, 11, ",\"subtype\":"}, // - PROTOCORE_U32, // - {PROTOCORE_FK_LIT, 0, 8, ",\"addr\":"}, // - PROTOCORE_U32, // - {PROTOCORE_FK_LIT, 0, 8, ",\"size\":"}, // - PROTOCORE_U32, // - {PROTOCORE_FK_LIT, 0, 11, ",\"running\":"}, // - PROTOCORE_STR, // "true" / "false" - a JSON keyword, not a string - {PROTOCORE_FK_LIT, 0, 1, "}"}, // - PROTOCORE_END, +static const mmgr_field PART_OPEN[] = {{MMGR_FK_LIT, 0, 15, "{\"partitions\":["}, MMGR_END}; +static const mmgr_field PART_ENTRY[] = { + MMGR_STR, // "," from the second entry on + {MMGR_FK_LIT, 0, 9, "{\"label\":"}, // + MMGR_JSON, // label + {MMGR_FK_LIT, 0, 8, ",\"kind\":"}, // + MMGR_JSON, // kind name + {MMGR_FK_LIT, 0, 8, ",\"type\":"}, // + MMGR_U32, // + {MMGR_FK_LIT, 0, 11, ",\"subtype\":"}, // + MMGR_U32, // + {MMGR_FK_LIT, 0, 8, ",\"addr\":"}, // + MMGR_U32, // + {MMGR_FK_LIT, 0, 8, ",\"size\":"}, // + MMGR_U32, // + {MMGR_FK_LIT, 0, 11, ",\"running\":"}, // + MMGR_STR, // "true" / "false" - a JSON keyword, not a string + {MMGR_FK_LIT, 0, 1, "}"}, // + MMGR_END, }; -static const protocore_field PART_CLOSE[] = {{PROTOCORE_FK_LIT, 0, 2, "]}"}, PROTOCORE_END}; +static const mmgr_field PART_CLOSE[] = {{MMGR_FK_LIT, 0, 2, "]}"}, MMGR_END}; void protocore_partition_monitor_json(uint8_t *work) { @@ -138,7 +138,7 @@ void protocore_partition_monitor_json(uint8_t *work) } // Each arm empties the buffer before reporting 0: a frame that did not fit leaves the document // open, and a caller measuring the buffer instead of reading the count would ship the fragment. - if (frame.append(out, cap, PART_OPEN, NULL, 0) == 0) + if (EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = PART_OPEN, .vals = NULL, .nvals = 0) == 0) { out[0] = '\0'; PartitionMonitorV.n = 0; @@ -150,20 +150,21 @@ void protocore_partition_monitor_json(uint8_t *work) PartitionMonitorV.kind_args.type = p->type; PartitionMonitorV.kind_args.subtype = p->subtype; protocore_partition_monitor_kind(work); - if (frame.append(out, cap, PART_ENTRY, - (const protocore_fval[]){ - PROTOCORE_VSTR(PROTOCORE_JSON_SEP[!!i]), PROTOCORE_VJSON(p->label), - PROTOCORE_VJSON(PartitionMonitorV.text), PROTOCORE_VU32((uint32_t)p->type), - PROTOCORE_VU32((uint32_t)p->subtype), PROTOCORE_VU32((uint32_t)p->address), - PROTOCORE_VU32((uint32_t)p->size), PROTOCORE_VSTR(p->running ? "true" : "false")}, - 8) == 0) + if (EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = PART_ENTRY, + .vals = + (const mmgr_fval[]){MMGR_VSTR(PROTOCORE_JSON_SEP[!!i]), MMGR_VJSON(p->label), + MMGR_VJSON(PartitionMonitorV.text), MMGR_VU32((uint32_t)p->type), + MMGR_VU32((uint32_t)p->subtype), MMGR_VU32((uint32_t)p->address), + MMGR_VU32((uint32_t)p->size), MMGR_VSTR(p->running ? "true" : "false")}, + .nvals = 8) == 0) { out[0] = '\0'; PartitionMonitorV.n = 0; return; } } - size_t n = frame.append(out, cap, PART_CLOSE, NULL, 0); + size_t n = + EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = PART_CLOSE, .vals = NULL, .nvals = 0); if (n == 0) { out[0] = '\0'; @@ -194,7 +195,7 @@ void protocore_partition_monitor_collect(uint8_t *work) for (uint8_t i = 0; i < n; i++) { protocore_partition_info *d = &out[i]; - (void)str.copy(d->label, tbl[i].label, sizeof(d->label)); + (void)EMBED_CALL(cellul.copy, CatenaFinitaCfg, .dst = d->label, .src = tbl[i].label, .cap = sizeof(d->label)); d->label[sizeof(d->label) - 1] = '\0'; d->type = tbl[i].type; d->subtype = tbl[i].subtype; diff --git a/src/server/web/dashboard/CMakeLists.txt b/src/server/web/dashboard/CMakeLists.txt index 7af3fec98..d7b3f932a 100644 --- a/src/server/web/dashboard/CMakeLists.txt +++ b/src/server/web/dashboard/CMakeLists.txt @@ -5,10 +5,8 @@ protocore_add_module(server/web/dashboard GATE PROTOCORE_ENABLE_DASHBOARD SOURCES dashboard.c PRIVATE_DEPS - mmgr/membuild - mmgr/protoframe - mmgr/protostr - mmgr/secure + mmgr + server/core/worker ) add_subdirectory(dashboard_routes) diff --git a/src/server/web/dashboard/dashboard.c b/src/server/web/dashboard/dashboard.c index 80305a017..668358abe 100644 --- a/src/server/web/dashboard/dashboard.c +++ b/src/server/web/dashboard/dashboard.c @@ -14,19 +14,18 @@ #if PROTOCORE_ENABLE_DASHBOARD -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/web/dashboard/dashboard.h" -#include "mmgr/membuild/membuild.h" // Sb: the route paths begin() composes -#include "mmgr/protoframe/protoframe.h" -#include "mmgr/protostr/protostr.h" -#include "protocore.h" // on_http / on_sse / on_ws: the tables the begin entry installs on +#include "cellularum_laboro/cellularum_laboro.h" +#include "numeros_scribo/numeros_scribo.h" +#include "protocore.h" // on_http / on_sse / on_ws: the tables the begin entry installs on +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS // A message key as it appears in the JSON: quoted, so it cannot match a widget key containing it. -static const protocore_field QUOTED_KEY[] = { - {PROTOCORE_FK_LIT, 0, 1, "\""}, PROTOCORE_STR, {PROTOCORE_FK_LIT, 0, 1, "\""}, PROTOCORE_END}; +static const mmgr_field QUOTED_KEY[] = {{MMGR_FK_LIT, 0, 1, "\""}, MMGR_STR, {MMGR_FK_LIT, 0, 1, "\""}, MMGR_END}; // All dashboard state, owned by one instance (internal linkage): the widget table, the // per-widget value array, and the inbound-control callback, grouped so it is one named owner, @@ -54,8 +53,8 @@ static_assert(DASHBOARD_OFF_CTX + sizeof(DashboardCtx) <= PROTOCORE_DASHBOARD_BO "PROTOCORE_DASHBOARD_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert( @@ -106,7 +105,7 @@ uint8_t *protocore_dashboard_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_DASHBOARD_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_DASHBOARD_BORROW); } return s_own.span; } @@ -141,7 +140,8 @@ void protocore_dashboard_set(uint8_t *work) for (uint8_t i = 0; i < DASHBOARD_CTX(work)->count; i++) { if (DASHBOARD_CTX(work)->widgets[i].key && - str.eq(DASHBOARD_CTX(work)->widgets[i].key, key, MAX_KEY_LEN, PROTO_FALSE)) + EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = DASHBOARD_CTX(work)->widgets[i].key, .other = key, + .cap = MAX_KEY_LEN, .ci = PROTO_FALSE)) { DASHBOARD_CTX(work)->values[i] = value; DashboardV.ok = PROTO_TRUE; @@ -157,34 +157,34 @@ void protocore_dashboard_set(uint8_t *work) // The item index selects it; !!i is 0 or 1, so the separator is a load rather than a branch. static const char *const PROTOCORE_JSON_SEP[2] = {"", ","}; -static const protocore_field DASH_ARRAY_OPEN[] = {{PROTOCORE_FK_LIT, 0, 1, "["}, PROTOCORE_END}; -static const protocore_field DASH_ARRAY_CLOSE[] = {{PROTOCORE_FK_LIT, 0, 1, "]"}, PROTOCORE_END}; -static const protocore_field DASH_WIDGET[] = { - PROTOCORE_STR, // "," from the second widget on - {PROTOCORE_FK_LIT, 0, 8, "{\"type\":"}, // - PROTOCORE_JSON, // type name - {PROTOCORE_FK_LIT, 0, 9, ",\"label\":"}, // - PROTOCORE_JSON, // - {PROTOCORE_FK_LIT, 0, 7, ",\"key\":"}, // - PROTOCORE_JSON, // - {PROTOCORE_FK_LIT, 0, 7, ",\"min\":"}, // - {PROTOCORE_FK_G, 0, 0, NULL}, // width 0 == 6 significant digits, the %g default - {PROTOCORE_FK_LIT, 0, 7, ",\"max\":"}, // - {PROTOCORE_FK_G, 0, 0, NULL}, // - {PROTOCORE_FK_LIT, 0, 8, ",\"unit\":"}, // - PROTOCORE_JSON, // - {PROTOCORE_FK_LIT, 0, 1, "}"}, // - PROTOCORE_END, +static const mmgr_field DASH_ARRAY_OPEN[] = {{MMGR_FK_LIT, 0, 1, "["}, MMGR_END}; +static const mmgr_field DASH_ARRAY_CLOSE[] = {{MMGR_FK_LIT, 0, 1, "]"}, MMGR_END}; +static const mmgr_field DASH_WIDGET[] = { + MMGR_STR, // "," from the second widget on + {MMGR_FK_LIT, 0, 8, "{\"type\":"}, // + MMGR_JSON, // type name + {MMGR_FK_LIT, 0, 9, ",\"label\":"}, // + MMGR_JSON, // + {MMGR_FK_LIT, 0, 7, ",\"key\":"}, // + MMGR_JSON, // + {MMGR_FK_LIT, 0, 7, ",\"min\":"}, // + {MMGR_FK_G, 0, 0, NULL}, // width 0 == 6 significant digits, the %g default + {MMGR_FK_LIT, 0, 7, ",\"max\":"}, // + {MMGR_FK_G, 0, 0, NULL}, // + {MMGR_FK_LIT, 0, 8, ",\"unit\":"}, // + MMGR_JSON, // + {MMGR_FK_LIT, 0, 1, "}"}, // + MMGR_END, }; -static const protocore_field DASH_OBJECT_OPEN[] = {{PROTOCORE_FK_LIT, 0, 1, "{"}, PROTOCORE_END}; -static const protocore_field DASH_OBJECT_CLOSE[] = {{PROTOCORE_FK_LIT, 0, 1, "}"}, PROTOCORE_END}; -static const protocore_field DASH_VALUE[] = { - PROTOCORE_STR, // "," from the second pair on - PROTOCORE_JSON, // key - {PROTOCORE_FK_LIT, 0, 1, ":"}, // - {PROTOCORE_FK_G, 0, 0, NULL}, // the reading - PROTOCORE_END, +static const mmgr_field DASH_OBJECT_OPEN[] = {{MMGR_FK_LIT, 0, 1, "{"}, MMGR_END}; +static const mmgr_field DASH_OBJECT_CLOSE[] = {{MMGR_FK_LIT, 0, 1, "}"}, MMGR_END}; +static const mmgr_field DASH_VALUE[] = { + MMGR_STR, // "," from the second pair on + MMGR_JSON, // key + {MMGR_FK_LIT, 0, 1, ":"}, // + {MMGR_FK_G, 0, 0, NULL}, // the reading + MMGR_END, }; void protocore_dashboard_layout_json(uint8_t *work) @@ -205,7 +205,8 @@ void protocore_dashboard_layout_json(uint8_t *work) } // Each arm empties the buffer before reporting 0: a frame that did not fit leaves the document // open, and a caller measuring the buffer instead of reading the count would ship the fragment. - if (frame.append(out, cap, DASH_ARRAY_OPEN, NULL, 0) == 0) + if (EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = DASH_ARRAY_OPEN, .vals = NULL, + .nvals = 0) == 0) { out[0] = '\0'; DashboardV.value = 0; @@ -214,19 +215,20 @@ void protocore_dashboard_layout_json(uint8_t *work) for (uint8_t i = 0; i < DASHBOARD_CTX(work)->count; i++) { const protocore_widget *w = &DASHBOARD_CTX(work)->widgets[i]; - if (frame.append(out, cap, DASH_WIDGET, - (const protocore_fval[]){PROTOCORE_VSTR(PROTOCORE_JSON_SEP[!!i]), - PROTOCORE_VJSON(widget_type_name(w->type)), PROTOCORE_VJSON(w->label), - PROTOCORE_VJSON(w->key), PROTOCORE_VG((double)w->min), - PROTOCORE_VG((double)w->max), PROTOCORE_VJSON(w->unit)}, - 7) == 0) + if (EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = DASH_WIDGET, + .vals = (const mmgr_fval[]){MMGR_VSTR(PROTOCORE_JSON_SEP[!!i]), + MMGR_VJSON(widget_type_name(w->type)), MMGR_VJSON(w->label), + MMGR_VJSON(w->key), MMGR_VG((double)w->min), MMGR_VG((double)w->max), + MMGR_VJSON(w->unit)}, + .nvals = 7) == 0) { out[0] = '\0'; DashboardV.value = 0; return; } } - size_t n = frame.append(out, cap, DASH_ARRAY_CLOSE, NULL, 0); + size_t n = EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = DASH_ARRAY_CLOSE, .vals = NULL, + .nvals = 0); if (n == 0) { out[0] = '\0'; @@ -250,7 +252,8 @@ void protocore_dashboard_values_json(uint8_t *work) DashboardV.value = 0; return; } - if (frame.append(out, cap, DASH_OBJECT_OPEN, NULL, 0) == 0) + if (EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = DASH_OBJECT_OPEN, .vals = NULL, + .nvals = 0) == 0) { out[0] = '\0'; DashboardV.value = 0; @@ -258,18 +261,19 @@ void protocore_dashboard_values_json(uint8_t *work) } for (uint8_t i = 0; i < DASHBOARD_CTX(work)->count; i++) { - if (frame.append(out, cap, DASH_VALUE, - (const protocore_fval[]){PROTOCORE_VSTR(PROTOCORE_JSON_SEP[!!i]), - PROTOCORE_VJSON(DASHBOARD_CTX(work)->widgets[i].key), - PROTOCORE_VG((double)DASHBOARD_CTX(work)->values[i])}, - 3) == 0) + if (EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = DASH_VALUE, + .vals = (const mmgr_fval[]){MMGR_VSTR(PROTOCORE_JSON_SEP[!!i]), + MMGR_VJSON(DASHBOARD_CTX(work)->widgets[i].key), + MMGR_VG((double)DASHBOARD_CTX(work)->values[i])}, + .nvals = 3) == 0) { out[0] = '\0'; DashboardV.value = 0; return; } } - size_t n = frame.append(out, cap, DASH_OBJECT_CLOSE, NULL, 0); + size_t n = EMBED_CALL(numer.append, NumerosCfg, .out = out, .cap = cap, .spec = DASH_OBJECT_CLOSE, .vals = NULL, + .nvals = 0); if (n == 0) { out[0] = '\0'; @@ -295,13 +299,17 @@ static const char *control_value_ptr(const char *s, const char *key) { char pat[8]; // A key too long for the buffer leaves pat empty, and strstr then finds nothing - fail closed. - frame.build(pat, sizeof(pat), QUOTED_KEY, (const protocore_fval[]){PROTOCORE_VSTR(key)}, 1); - const char *p = str.find(s, str.len(s, 0xFFFF) + 1u, pat, str.len(pat, sizeof(pat)) + 1u, PROTO_FALSE); + EMBED_CALL(numer.build, NumerosCfg, .out = pat, .cap = sizeof(pat), .spec = QUOTED_KEY, + .vals = (const mmgr_fval[]){MMGR_VSTR(key)}, .nvals = 1); + const size_t s_len = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = 0xFFFF); + const size_t pat_len = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = pat, .cap = sizeof(pat)); + const char *p = EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = s, .cap = s_len + 1u, .other = pat, + .other_cap = pat_len + 1u, .ci = PROTO_FALSE); if (!p) { return NULL; } - p += str.len(pat, sizeof(pat)); + p += pat_len; while (*p == ' ' || *p == '\t') { p++; @@ -353,7 +361,7 @@ void protocore_dashboard_parse_control(uint8_t *work) } key_out[i] = '\0'; const char *end = NULL; - float v = str.to_float(vp, &end); + float v = EMBED_CALL(cellul.to_float, TransfiguroCfg, .src = vp, .end = &end); if (end == vp) { DashboardV.ok = PROTO_FALSE; @@ -419,18 +427,25 @@ void protocore_dashboard_begin(uint8_t *work) } char layout_path[MAX_PATH_LEN]; - protocore_sb sb_layout_path = {layout_path, sizeof(layout_path), 0, PROTO_TRUE}; - Sb.put(&sb_layout_path, path); - Sb.put(&sb_layout_path, "/layout"); - if (Sb.finish(&sb_layout_path) == 0) + size_t sb_layout_path = 0; + sb_layout_path = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = layout_path, .cap = sizeof(layout_path), + .at = sb_layout_path, .text = path); + sb_layout_path = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = layout_path, .cap = sizeof(layout_path), + .at = sb_layout_path, .text = "/layout"); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = layout_path, .cap = sizeof(layout_path), + .at = sb_layout_path) == 0) { layout_path[0] = '\0'; } - protocore_sb sb_stream_path = {DASHBOARD_CTX(work)->stream_path, sizeof(DASHBOARD_CTX(work)->stream_path), 0, - PROTO_TRUE}; - Sb.put(&sb_stream_path, path); - Sb.put(&sb_stream_path, "/stream"); - if (Sb.finish(&sb_stream_path) == 0) + char *const sb_stream_path_buf = DASHBOARD_CTX(work)->stream_path; + const size_t sb_stream_path_cap = sizeof(DASHBOARD_CTX(work)->stream_path); + size_t sb_stream_path = 0; + sb_stream_path = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = sb_stream_path_buf, .cap = sb_stream_path_cap, + .at = sb_stream_path, .text = path); + sb_stream_path = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = sb_stream_path_buf, .cap = sb_stream_path_cap, + .at = sb_stream_path, .text = "/stream"); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = sb_stream_path_buf, .cap = sb_stream_path_cap, + .at = sb_stream_path) == 0) { DASHBOARD_CTX(work)->stream_path[0] = '\0'; } @@ -439,10 +454,15 @@ void protocore_dashboard_begin(uint8_t *work) on_http(layout_path, HTTP_GET, dash_layout_handler); on_sse(DASHBOARD_CTX(work)->stream_path, dash_sse_connect); #if PROTOCORE_ENABLE_WEBSOCKET - protocore_sb sb_ws_path = {DASHBOARD_CTX(work)->ws_path, sizeof(DASHBOARD_CTX(work)->ws_path), 0, PROTO_TRUE}; - Sb.put(&sb_ws_path, path); - Sb.put(&sb_ws_path, "/ws"); - if (Sb.finish(&sb_ws_path) == 0) + char *const sb_ws_path_buf = DASHBOARD_CTX(work)->ws_path; + const size_t sb_ws_path_cap = sizeof(DASHBOARD_CTX(work)->ws_path); + size_t sb_ws_path = 0; + sb_ws_path = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = sb_ws_path_buf, .cap = sb_ws_path_cap, + .at = sb_ws_path, .text = path); + sb_ws_path = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = sb_ws_path_buf, .cap = sb_ws_path_cap, + .at = sb_ws_path, .text = "/ws"); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = sb_ws_path_buf, .cap = sb_ws_path_cap, .at = sb_ws_path) == + 0) { DASHBOARD_CTX(work)->ws_path[0] = '\0'; } diff --git a/src/server/web/spa_router/CMakeLists.txt b/src/server/web/spa_router/CMakeLists.txt index 67ca1dac1..6f4094729 100644 --- a/src/server/web/spa_router/CMakeLists.txt +++ b/src/server/web/spa_router/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(server/web/spa_router GATE PROTOCORE_ENABLE_SPA_ROUTER SOURCES spa_router.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/server/web/spa_router/spa_router.c b/src/server/web/spa_router/spa_router.c index 03bfb0ba7..a176a5ad2 100644 --- a/src/server/web/spa_router/spa_router.c +++ b/src/server/web/spa_router/spa_router.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_SPA_ROUTER -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "server/web/spa_router/spa_router.h" PROTOCORE_BEGIN_DECLS @@ -38,11 +38,12 @@ void protocore_spa_router_has_extension(uint8_t *work) // The last '/' opens the final segment, the last '.' inside it marks the extension. find runs // forward, so each search resumes past its hit and the last one to return is the rightmost; a // path is bounded by MAX_PATH_LEN, so the resumed walks cover it once. - const size_t n = str.len(path, MAX_PATH_LEN + 1); + const size_t n = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = path, .cap = MAX_PATH_LEN + 1); const char *seg = path; for (size_t i = 0; i < n; ++i) // each hit advances seg by at least one, so n bounds the trips { - const char *slash = str.find(seg, n - (size_t)(seg - path), "/", sizeof("/"), PROTO_FALSE); + const char *slash = EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = seg, .cap = n - (size_t)(seg - path), + .other = "/", .other_cap = sizeof("/"), .ci = PROTO_FALSE); if (!slash) { break; @@ -53,7 +54,8 @@ void protocore_spa_router_has_extension(uint8_t *work) const char *q = seg; for (size_t i = 0; i < n; ++i) { - const char *hit = str.find(q, n - (size_t)(q - path), ".", sizeof("."), PROTO_FALSE); + const char *hit = EMBED_CALL(cellul.find, CatenaFinitaCfg, .src = q, .cap = n - (size_t)(q - path), + .other = ".", .other_cap = sizeof("."), .ci = PROTO_FALSE); if (!hit) { break; @@ -78,8 +80,8 @@ void protocore_spa_router_route(uint8_t *work) if (api_prefix && api_prefix[0]) { - size_t pl = str.len(api_prefix, MAX_PATH_LEN + 1); - if (str.starts(path, api_prefix, pl, PROTO_FALSE)) + size_t pl = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = api_prefix, .cap = MAX_PATH_LEN + 1); + if (EMBED_CALL(cellul.starts, CatenaFinitaCfg, .src = path, .other = api_prefix, .cap = pl, .ci = PROTO_FALSE)) { SpaRouterV.action = PROTOCORE_SPA_PASSTHROUGH; return; // "/api/..." -> handlers @@ -181,7 +183,7 @@ void protocore_spa_router_ui_stream_next(uint8_t *work) { n++; } - mem.cpy(out + written, src, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + written, .src = src, .bytes = n); written += n; s->off += n; if (src[n] == '\0') // this fragment is fully emitted diff --git a/src/server/web/web_terminal/CMakeLists.txt b/src/server/web/web_terminal/CMakeLists.txt index 57b46855d..d396c4a53 100644 --- a/src/server/web/web_terminal/CMakeLists.txt +++ b/src/server/web/web_terminal/CMakeLists.txt @@ -5,8 +5,8 @@ protocore_add_module(server/web/web_terminal GATE PROTOCORE_ENABLE_WEB_TERMINAL SOURCES web_terminal.c PRIVATE_DEPS - mmgr/membuild - mmgr/secure + mmgr + server/core/worker network_drivers/application/web_assets shared/mime ) diff --git a/src/server/web/web_terminal/web_terminal.c b/src/server/web/web_terminal/web_terminal.c index 74ea7f8c7..919444c32 100644 --- a/src/server/web/web_terminal/web_terminal.c +++ b/src/server/web/web_terminal/web_terminal.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_WEB_TERMINAL -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/secure/secure.h" // the persistent end this module's state is taken from -#include "protocore.h" // MAX_PATH_LEN, MAX_WS_CONNS, HttpReq, send_text +#include "protocore.h" // MAX_PATH_LEN, MAX_WS_CONNS, HttpReq, send_text +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "server/web/web_terminal/web_terminal.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -46,8 +46,8 @@ static_assert(WEB_TERMINAL_OFF_CTX + sizeof(WebTerminalCtx) <= PROTOCORE_WEB_TER "PROTOCORE_WEB_TERMINAL_BORROW is short of the module context - raise it in protocore_config.h, which\n" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert( @@ -127,7 +127,7 @@ uint8_t *protocore_web_terminal_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_secure_persist_span(PROTOCORE_WEB_TERMINAL_BORROW).buf; + s_own.span = (uint8_t *)protocore_secure_persist(PROTOCORE_WEB_TERMINAL_BORROW); } return s_own.span; } @@ -146,10 +146,15 @@ void protocore_web_terminal_begin(uint8_t *work) { path = "/terminal"; } - protocore_sb sb_ws_path = {WEB_TERMINAL_CTX(work)->ws_path, sizeof(WEB_TERMINAL_CTX(work)->ws_path), 0, PROTO_TRUE}; - Sb.put(&sb_ws_path, path); - Sb.put(&sb_ws_path, "/ws"); - if (Sb.finish(&sb_ws_path) == 0) + char *const sb_ws_path_buf = WEB_TERMINAL_CTX(work)->ws_path; + const size_t sb_ws_path_cap = sizeof(WEB_TERMINAL_CTX(work)->ws_path); + size_t sb_ws_path = 0; + sb_ws_path = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = sb_ws_path_buf, .cap = sb_ws_path_cap, + .at = sb_ws_path, .text = path); + sb_ws_path = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = sb_ws_path_buf, .cap = sb_ws_path_cap, + .at = sb_ws_path, .text = "/ws"); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = sb_ws_path_buf, .cap = sb_ws_path_cap, .at = sb_ws_path) == + 0) { WEB_TERMINAL_CTX(work)->ws_path[0] = '\0'; } @@ -195,12 +200,13 @@ void protocore_web_terminal_println(uint8_t *work) const char *s = WebTerminalV.println_args.s; char buf[TERM_TX_BUF_SIZE]; - protocore_sb sb_buf = {buf, sizeof(buf), 0, PROTO_TRUE}; - Sb.put(&sb_buf, s ? s : ""); - Sb.put(&sb_buf, "\n"); + size_t sb_buf = 0; + sb_buf = + EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = sizeof(buf), .at = sb_buf, .text = s ? s : ""); + sb_buf = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = sizeof(buf), .at = sb_buf, .text = "\n"); WebTerminalV.print_args.s = buf; protocore_web_terminal_print(work); - if (Sb.finish(&sb_buf) == 0) + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = buf, .cap = sizeof(buf), .at = sb_buf) == 0) { buf[0] = '\0'; } diff --git a/src/server/web/web_terminal/web_terminal.h b/src/server/web/web_terminal/web_terminal.h index 73abe8e0a..03c8bb869 100644 --- a/src/server/web/web_terminal/web_terminal.h +++ b/src/server/web/web_terminal/web_terminal.h @@ -13,15 +13,15 @@ * auto-selects ws:// or wss:// from the page's own scheme. * * A line is built with the frame engine and handed over as text, so the shape is a - * `static const protocore_field[]` in rodata rather than a format string parsed per call. + * `static const mmgr_field[]` in rodata rather than a format string parsed per call. * * @code - * static const protocore_field SAID[] = {{PROTOCORE_FK_LIT, 0, 10, "you said: "}, PROTOCORE_STR, - * {PROTOCORE_FK_LIT, 0, 1, "\n"}, PROTOCORE_END}; + * static const mmgr_field SAID[] = {{MMGR_FK_LIT, 0, 10, "you said: "}, MMGR_STR, + * {MMGR_FK_LIT, 0, 1, "\n"}, MMGR_END}; * void on_cmd(const char *line, uint8_t client) { * char out[64]; - * frame.build(out, sizeof(out), SAID, (const protocore_fval[]){PROTOCORE_VSTR(line)}, 1); - * protocore_web_terminal_print(out); + * EMBED_CALL(numer.build, NumerosCfg, .out = out, .cap = sizeof(out), .spec = SAID, .vals = (const + * mmgr_fval[]){MMGR_VSTR(line)}, .nvals = 1); protocore_web_terminal_print(out); * } * void setup() { * // ... wifi + on_http(...) ... diff --git a/src/services/energy/c37118/CMakeLists.txt b/src/services/energy/c37118/CMakeLists.txt index 68ec2af9e..e4b85a456 100644 --- a/src/services/energy/c37118/CMakeLists.txt +++ b/src/services/energy/c37118/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(services/energy/c37118 GATE PROTOCORE_ENABLE_C37118 SOURCES c37118.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr shared/crc ) diff --git a/src/services/energy/c37118/c37118.c b/src/services/energy/c37118/c37118.c index 5c3729a8c..58115c748 100644 --- a/src/services/energy/c37118/c37118.c +++ b/src/services/energy/c37118/c37118.c @@ -7,13 +7,13 @@ */ #include "services/energy/c37118/c37118.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #if PROTOCORE_ENABLE_C37118 static uint8_t crc_work[16]; // the borrow an entry takes; Crc never reads it -#include "mmgr/endian/endian.h" +#include "endian/endian.h" #include "shared/crc/crc.h" // PROTOCORE_CRC16_IBM_3740 PROTOCORE_BEGIN_DECLS @@ -43,17 +43,17 @@ size_t protocore_c37118_build_frame(uint8_t *buf, size_t cap, uint8_t type, uint size_t p = 0; buf[p++] = C37118_SYNC_LEADER; buf[p++] = (uint8_t)(((type & C37118_TYPE_MASK) << C37118_TYPE_SHIFT) | (version & C37118_VERSION_MASK)); - p += endian.wr16be(buf + p, (uint16_t)total); - p += endian.wr16be(buf + p, idcode); - p += endian.wr32be(buf + p, soc); - p += endian.wr32be(buf + p, fracsec); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = (uint16_t)total, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = idcode, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = soc, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = fracsec, .width = MMGR_ENDIAN_32); if (payload_len) { - mem.cpy(buf + p, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = payload, .bytes = payload_len); p += payload_len; } uint16_t crc = protocore_c37118_crc(buf, p); // over everything before CHK - p += endian.wr16be(buf + p, crc); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = crc, .width = MMGR_ENDIAN_16); return p; } @@ -61,7 +61,7 @@ size_t protocore_c37118_build_command(uint8_t *buf, size_t cap, uint16_t idcode, uint16_t cmd) { uint8_t payload[2]; - endian.wr16be(payload, cmd); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = payload, .val = cmd, .width = MMGR_ENDIAN_16); return protocore_c37118_build_frame(buf, cap, C37118_TYPE_CMD, C37118_VERSION_2011, idcode, soc, fracsec, payload, 2); } @@ -76,13 +76,14 @@ proto_bool protocore_c37118_parse_frame(const uint8_t *buf, size_t len, C37118Fr { return PROTO_FALSE; } - uint16_t framesize = endian.rd16be(buf + 2); + uint16_t framesize = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 2, .width = MMGR_ENDIAN_16); if (framesize < C37118_MIN_FRAME || framesize > len) { return PROTO_FALSE; // out of range / not fully buffered } uint16_t want = protocore_c37118_crc(buf, (size_t)framesize - 2); - uint16_t got = endian.rd16be(buf + framesize - 2); + uint16_t got = + (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + framesize - 2, .width = MMGR_ENDIAN_16); if (want != got) { return PROTO_FALSE; // CHK mismatch @@ -90,9 +91,9 @@ proto_bool protocore_c37118_parse_frame(const uint8_t *buf, size_t len, C37118Fr out->type = (uint8_t)((buf[1] >> C37118_TYPE_SHIFT) & C37118_TYPE_MASK); out->version = (uint8_t)(buf[1] & C37118_VERSION_MASK); out->framesize = framesize; - out->idcode = endian.rd16be(buf + 4); - out->soc = endian.rd32be(buf + 6); - out->fracsec = endian.rd32be(buf + 10); + out->idcode = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 4, .width = MMGR_ENDIAN_16); + out->soc = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 6, .width = MMGR_ENDIAN_32); + out->fracsec = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 10, .width = MMGR_ENDIAN_32); out->data = buf + 14; out->data_len = (size_t)framesize - C37118_MIN_FRAME; return PROTO_TRUE; @@ -106,7 +107,7 @@ proto_bool protocore_c37118_parse_command(const C37118Frame *f, uint16_t *cmd) } if (cmd) { - *cmd = endian.rd16be(f->data); + *cmd = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = f->data, .width = MMGR_ENDIAN_16); } return PROTO_TRUE; } @@ -117,7 +118,8 @@ proto_bool protocore_c37118_decode_stat(const C37118Frame *f, C37118Stat *out) { return PROTO_FALSE; } - uint16_t s = endian.rd16be(f->data); // STAT is the first word of the data payload, big-endian + // STAT is the first word of the data payload, big-endian + uint16_t s = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = f->data, .width = MMGR_ENDIAN_16); out->raw = s; out->data_valid = (s & 0x8000u) == 0; // bit 15: 0 = valid out->pmu_error = (s & 0x4000u) != 0; // bit 14 diff --git a/src/services/energy/dnp3/CMakeLists.txt b/src/services/energy/dnp3/CMakeLists.txt index 66b20384f..3dd0043a1 100644 --- a/src/services/energy/dnp3/CMakeLists.txt +++ b/src/services/energy/dnp3/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(services/energy/dnp3 GATE PROTOCORE_ENABLE_DNP3 SOURCES dnp3.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr shared/crc ) diff --git a/src/services/energy/dnp3/dnp3.c b/src/services/energy/dnp3/dnp3.c index c5d00accd..1d722d483 100644 --- a/src/services/energy/dnp3/dnp3.c +++ b/src/services/energy/dnp3/dnp3.c @@ -7,8 +7,8 @@ */ #include "services/energy/dnp3/dnp3.h" -#include "mmgr/endian/endian.h" // endian.rd16le / endian.rd32le -#include "mmgr/protomem/protomem.h" +#include "endian/endian.h" // parva_extremitas.rd / parva_extremitas.rd +#include "memoria_operor/memoria_operor.h" #include "shared/crc/crc.h" // PROTOCORE_CRC16_DNP #if PROTOCORE_ENABLE_DNP3 @@ -70,7 +70,7 @@ size_t protocore_dnp3_build_frame(uint8_t *buf, size_t cap, uint8_t control, uin { blk = DNP3_BLOCK_LEN; } - mem.cpy(buf + p, user_data + off, blk); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = user_data + off, .bytes = blk); put_crc(buf + p + blk, buf + p, blk); // CRC over this block's data p += blk + DNP3_CRC_LEN; off += blk; @@ -138,7 +138,7 @@ proto_bool protocore_dnp3_parse_frame(const uint8_t *buf, size_t len, Dnp3Frame { return PROTO_FALSE; // block CRC mismatch } - mem.cpy(out_user + off, buf + p, blk); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out_user + off, .src = buf + p, .bytes = blk); p += blk + DNP3_CRC_LEN; off += blk; } @@ -175,7 +175,7 @@ size_t protocore_dnp3_build_transport_segment(uint8_t *out, size_t cap, proto_bo out[0] = protocore_dnp3_transport_header(fir, fin, seq); if (app_len) { - mem.cpy(out + 1, app_data, app_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 1, .src = app_data, .bytes = app_len); } return 1 + app_len; } @@ -234,7 +234,7 @@ int protocore_dnp3_transport_feed(Dnp3TransportRx *r, const uint8_t *user, size_ } if (app_len) { - mem.cpy(r->buf + r->len, app, app_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = r->buf + r->len, .src = app, .bytes = app_len); } r->len += app_len; r->expect_seq = (uint8_t)((r->expect_seq + 1) & DNP3_TR_SEQ_MASK); @@ -264,7 +264,7 @@ size_t protocore_dnp3_build_app_request(uint8_t *out, size_t cap, uint8_t app_co out[1] = fc; if (obj_len) { - mem.cpy(out + 2, objects, obj_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 2, .src = objects, .bytes = obj_len); } return 2 + obj_len; } @@ -282,7 +282,7 @@ size_t protocore_dnp3_build_app_response(uint8_t *out, size_t cap, uint8_t app_c out[3] = (uint8_t)(iin >> 8); // IIN2 if (obj_len) { - mem.cpy(out + 4, objects, obj_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 4, .src = objects, .bytes = obj_len); } return 4 + obj_len; } @@ -354,13 +354,13 @@ size_t protocore_dnp3_build_object_header_range(uint8_t *buf, size_t cap, uint8_ } else if (range_code == DNP3_RANGE_START_STOP_2) { - endian.wr16le(buf + 3, (uint16_t)start); - endian.wr16le(buf + 5, (uint16_t)stop); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 3, .val = (uint16_t)start, .width = MMGR_ENDIAN_16); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 5, .val = (uint16_t)stop, .width = MMGR_ENDIAN_16); } else { - endian.wr32le(buf + 3, start); - endian.wr32le(buf + 7, stop); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 3, .val = start, .width = MMGR_ENDIAN_32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 7, .val = stop, .width = MMGR_ENDIAN_32); } return total; } @@ -387,8 +387,8 @@ size_t protocore_dnp3_build_crob(uint8_t *buf, size_t cap, uint8_t op_type, uint // Control code: op-type (bits 0-3) | clear (bit 5) | trip-close (bits 6-7). The queue bit (0x10) is obsolete. buf[0] = (uint8_t)((op_type & 0x0Fu) | (clear ? 0x20u : 0x00u) | (uint8_t)((tcc & 0x03u) << 6)); buf[1] = count; - endian.wr32le(buf + 2, on_time_ms); - endian.wr32le(buf + 6, off_time_ms); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 2, .val = on_time_ms, .width = MMGR_ENDIAN_32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + 6, .val = off_time_ms, .width = MMGR_ENDIAN_32); buf[10] = 0x00; // status: 0 in a request (the outstation reports the result in its response) return DNP3_CROB_LEN; } @@ -399,8 +399,9 @@ size_t protocore_dnp3_build_aob32(uint8_t *buf, size_t cap, int32_t value) { return 0; } - endian.wr32le(buf, (uint32_t)value); // 32-bit signed setpoint, little-endian (two's complement) - buf[4] = 0x00; // control status: 0 in a request (the outstation reports the result) + // 32-bit signed setpoint, little-endian (two's complement) + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf, .val = (uint32_t)value, .width = MMGR_ENDIAN_32); + buf[4] = 0x00; // control status: 0 in a request (the outstation reports the result) return DNP3_AOB_LEN; } @@ -411,8 +412,9 @@ size_t protocore_dnp3_build_aob_float(uint8_t *buf, size_t cap, float value) return 0; } uint32_t bits; - mem.cpy(&bits, &value, 4); // the IEEE-754 bit pattern, written little-endian (endian-safe) - endian.wr32le(buf, bits); + // the IEEE-754 bit pattern, written little-endian (endian-safe) + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &bits, .src = &value, .bytes = 4); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf, .val = bits, .width = MMGR_ENDIAN_32); buf[4] = 0x00; // control status: 0 in a request return DNP3_AOB_LEN; } @@ -446,8 +448,8 @@ proto_bool protocore_dnp3_parse_object_header(const uint8_t *buf, size_t len, Dn { return PROTO_FALSE; } - start = endian.rd16le(buf + p); - stop = endian.rd16le(buf + p + 2); + start = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = buf + p, .width = MMGR_ENDIAN_16); + stop = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = buf + p + 2, .width = MMGR_ENDIAN_16); p += 4; count = stop - start + 1; break; @@ -456,8 +458,8 @@ proto_bool protocore_dnp3_parse_object_header(const uint8_t *buf, size_t len, Dn { return PROTO_FALSE; } - start = endian.rd32le(buf + p); - stop = endian.rd32le(buf + p + 4); + start = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = buf + p, .width = MMGR_ENDIAN_32); + stop = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = buf + p + 4, .width = MMGR_ENDIAN_32); p += 8; count = stop - start + 1; break; @@ -477,7 +479,7 @@ proto_bool protocore_dnp3_parse_object_header(const uint8_t *buf, size_t len, Dn { return PROTO_FALSE; } - count = endian.rd16le(buf + p); + count = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = buf + p, .width = MMGR_ENDIAN_16); p += 2; is_count = PROTO_TRUE; break; @@ -486,7 +488,7 @@ proto_bool protocore_dnp3_parse_object_header(const uint8_t *buf, size_t len, Dn { return PROTO_FALSE; } - count = endian.rd32le(buf + p); + count = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = buf + p, .width = MMGR_ENDIAN_32); p += 4; is_count = PROTO_TRUE; break; diff --git a/src/services/energy/goose/CMakeLists.txt b/src/services/energy/goose/CMakeLists.txt index ed7d406fe..dc5371572 100644 --- a/src/services/energy/goose/CMakeLists.txt +++ b/src/services/energy/goose/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/energy/goose GATE PROTOCORE_ENABLE_GOOSE SOURCES goose.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/energy/goose/goose.c b/src/services/energy/goose/goose.c index db7c9e4ab..5c70cfc5d 100644 --- a/src/services/energy/goose/goose.c +++ b/src/services/energy/goose/goose.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_GOOSE -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "services/energy/goose/goose.h" PROTOCORE_BEGIN_DECLS @@ -64,7 +64,7 @@ static proto_bool tlv(uint8_t *out, size_t cap, size_t *n, uint8_t tag, const ui *n += write_len(out + *n, val_len); if (val_len) { - mem.cpy(out + *n, val, val_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + *n, .src = val, .bytes = val_len); *n += val_len; } return PROTO_TRUE; @@ -102,7 +102,8 @@ static proto_bool protocore_ber_int(uint8_t *out, size_t cap, size_t *n, uint8_t static proto_bool protocore_ber_str(uint8_t *out, size_t cap, size_t *n, uint8_t tag, const char *s) { - return tlv(out, cap, n, tag, (const uint8_t *)(s ? s : ""), s ? str.len(s, cap + 1) : 0); + return tlv(out, cap, n, tag, (const uint8_t *)(s ? s : ""), + s ? EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = cap + 1) : 0); } static proto_bool protocore_ber_bool(uint8_t *out, size_t cap, size_t *n, uint8_t tag, proto_bool v) @@ -187,7 +188,7 @@ size_t protocore_goose_pdu(const protocore_goose *g, uint8_t *out, size_t cap) size_t content_len = n - RESERVE; size_t hdr = 1 + len_octets(content_len); // Move the content down so the 0x61 tag + length sit immediately before it (no gap). - mem.move(out + hdr, out + RESERVE, content_len); + EMBED_CALL(memor.move_down, MemoriaCfg, .dst = out + hdr, .src = out + RESERVE, .bytes = content_len); out[0] = 0x61; write_len(out + 1, content_len); return hdr + content_len; @@ -201,8 +202,8 @@ size_t protocore_goose_frame(const uint8_t *dst, const uint8_t *src, uint16_t ap return 0; } // Ethernet II header (ethertype 0x88B8 = GOOSE). - mem.cpy(out, dst, 6); - mem.cpy(out + 6, src, 6); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = dst, .bytes = 6); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 6, .src = src, .bytes = 6); out[12] = 0x88; out[13] = 0xB8; // GOOSE header: APPID(2), length(2, filled below), reserved1(2), reserved2(2). @@ -234,7 +235,7 @@ proto_bool protocore_goose_parse_frame(const uint8_t *buf, size_t len, protocore { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); out->appid = (uint16_t)((buf[14] << 8) | buf[15]); const uint8_t *end = buf + len; diff --git a/src/services/energy/iccp/CMakeLists.txt b/src/services/energy/iccp/CMakeLists.txt index 496f199b7..0a99f3e95 100644 --- a/src/services/energy/iccp/CMakeLists.txt +++ b/src/services/energy/iccp/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/energy/iccp GATE PROTOCORE_ENABLE_ICCP SOURCES iccp.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/energy/iccp/iccp.c b/src/services/energy/iccp/iccp.c index 57bf71d3b..005e1ec6d 100644 --- a/src/services/energy/iccp/iccp.c +++ b/src/services/energy/iccp/iccp.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_ICCP -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/energy/iccp/iccp.h" PROTOCORE_BEGIN_DECLS @@ -27,7 +27,8 @@ static size_t tlv(uint8_t tag, const uint8_t *val, size_t val_len, uint8_t *out, out[1] = (uint8_t)val_len; if (val_len) { - mem.cpy(out + 2, val, val_len); // 1/4-byte field, int_content's >=1 result, or n built from those). + // 1/4-byte field, int_content's >=1 result, or n built from those). + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 2, .src = val, .bytes = val_len); } return 2 + val_len; } diff --git a/src/services/energy/iec60870/CMakeLists.txt b/src/services/energy/iec60870/CMakeLists.txt index e637ba579..5fac0f76b 100644 --- a/src/services/energy/iec60870/CMakeLists.txt +++ b/src/services/energy/iec60870/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/energy/iec60870 GATE PROTOCORE_ENABLE_IEC60870 SOURCES iec60870.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/energy/iec60870/iec60870.c b/src/services/energy/iec60870/iec60870.c index d54430536..07baea636 100644 --- a/src/services/energy/iec60870/iec60870.c +++ b/src/services/energy/iec60870/iec60870.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_IEC60870 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/energy/iec60870/iec60870.h" // --- -104 APCI --- @@ -37,7 +37,7 @@ size_t protocore_iec104_build_i(uint8_t *buf, size_t cap, uint16_t ns, uint16_t buf[5] = (uint8_t)((nr >> 7) & 0xFFu); if (asdu_len) { - mem.cpy(buf + 6, asdu, asdu_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 6, .src = asdu, .bytes = asdu_len); } return total; } @@ -215,7 +215,8 @@ size_t protocore_iec_io_build_float(uint8_t *buf, size_t cap, uint32_t ioa, floa } protocore_iec_put_ioa(buf, cap, ioa); uint32_t bits; - mem.cpy(&bits, &value, 4); // the IEEE-754 bit pattern, written little-endian (endian-safe) + // the IEEE-754 bit pattern, written little-endian (endian-safe) + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &bits, .src = &value, .bytes = 4); buf[3] = (uint8_t)bits; buf[4] = (uint8_t)(bits >> 8); buf[5] = (uint8_t)(bits >> 16); @@ -238,7 +239,7 @@ proto_bool protocore_iec_io_parse_float(const uint8_t *buf, size_t len, uint32_t { uint32_t bits = (uint32_t)buf[3] | ((uint32_t)buf[4] << 8) | ((uint32_t)buf[5] << 16) | ((uint32_t)buf[6] << 24); - mem.cpy(value, &bits, 4); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = value, .src = &bits, .bytes = 4); } if (qds) { @@ -514,7 +515,7 @@ size_t protocore_iec101_build_variable(uint8_t *buf, size_t cap, uint8_t control buf[5] = addr; if (asdu_len) { - mem.cpy(buf + 6, asdu, asdu_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 6, .src = asdu, .bytes = asdu_len); } buf[4 + L] = sum8(buf + 4, L); // checksum over control..end of ASDU buf[5 + L] = IEC_STOP; diff --git a/src/services/energy/mms/CMakeLists.txt b/src/services/energy/mms/CMakeLists.txt index b9b9bbf45..f276a26b0 100644 --- a/src/services/energy/mms/CMakeLists.txt +++ b/src/services/energy/mms/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/energy/mms GATE PROTOCORE_ENABLE_MMS SOURCES mms.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/energy/mms/mms.c b/src/services/energy/mms/mms.c index 4a2aaaa28..4887abaed 100644 --- a/src/services/energy/mms/mms.c +++ b/src/services/energy/mms/mms.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_MMS -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "services/energy/mms/mms.h" PROTOCORE_BEGIN_DECLS @@ -75,7 +75,8 @@ static size_t tlv(uint8_t tag, const uint8_t *val, size_t val_len, uint8_t *out, // path (it assumes val_len >= cap - k, e.g. 5 >= 254) that the n <= cap guard rules out. if (n > k) { - mem.cpy(out + k, val, n - k); // NOSONAR - see above: bound proven, analyzer follows an infeasible path + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + k, .src = val, + .bytes = n - k); // NOSONAR - see above: bound proven, analyzer follows an infeasible path } return n; } @@ -146,7 +147,7 @@ size_t protocore_mms_read_request(uint32_t invoke_id, const char *item_name, uin { return 0; } - size_t name_len = str.len(item_name, 128 + 1); + size_t name_len = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = item_name, .cap = 128 + 1); if (name_len > 128) { return 0; @@ -202,7 +203,7 @@ size_t protocore_mms_read_request(uint32_t invoke_id, const char *item_name, uin { return 0; } - mem.cpy(body + bn, a0, n); // append the A4 read + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = body + bn, .src = a0, .bytes = n); // append the A4 read bn += n; return tlv(MMS_PDU_CONFIRMED_REQUEST, body, bn, out, cap); } @@ -239,7 +240,7 @@ size_t protocore_mms_read_response(uint32_t invoke_id, const uint8_t *data, size { return 0; } - mem.cpy(body + bn, svc, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = body + bn, .src = svc, .bytes = n); bn += n; return tlv(MMS_PDU_CONFIRMED_RESPONSE, body, bn, out, cap); } diff --git a/src/services/energy/openadr/CMakeLists.txt b/src/services/energy/openadr/CMakeLists.txt index 2fd595cdf..1ab23e182 100644 --- a/src/services/energy/openadr/CMakeLists.txt +++ b/src/services/energy/openadr/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/energy/openadr GATE PROTOCORE_ENABLE_OPENADR SOURCES openadr.c PRIVATE_DEPS - mmgr/membuild + mmgr ) diff --git a/src/services/energy/openadr/openadr.c b/src/services/energy/openadr/openadr.c index 4be14e2ce..c3decccec 100644 --- a/src/services/energy/openadr/openadr.c +++ b/src/services/energy/openadr/openadr.c @@ -10,12 +10,12 @@ #if PROTOCORE_ENABLE_OPENADR -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder #include "services/energy/openadr/openadr.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS -static void put_u64(protocore_sb *b, uint64_t v) +static size_t put_u64(char *out, size_t cap, size_t at, uint64_t v) { char tmp[21]; int n = 0; @@ -24,32 +24,32 @@ static void put_u64(protocore_sb *b, uint64_t v) tmp[n++] = (char)('0' + (int)(v % 10)); v /= 10; } while (v); - char out[22]; + char digits[22]; for (int i = 0; i < n; i++) { - out[i] = tmp[n - 1 - i]; + digits[i] = tmp[n - 1 - i]; } - out[n] = '\0'; - Sb.put(b, out); + digits[n] = '\0'; + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = digits); } // Format a double with 3 decimal places (no stdlib). Rounds to milli-units; handles the sign. -static void put_double(protocore_sb *b, double v) +static size_t put_double(char *out, size_t cap, size_t at, double v) { if (v < 0) { - Sb.put(b, "-"); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "-"); v = -v; } // scale by 1000 and round. uint64_t scaled = (uint64_t)(v * 1000.0 + 0.5); uint64_t whole = scaled / 1000; uint32_t frac = (uint32_t)(scaled % 1000); - put_u64(b, whole); - Sb.put(b, "."); + at = put_u64(out, cap, at, whole); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "."); // three digits, zero-padded. char f[4] = {(char)('0' + (frac / 100) % 10), (char)('0' + (frac / 10) % 10), (char)('0' + frac % 10), '\0'}; - Sb.put(b, f); + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = f); } size_t protocore_openadr_event(const char *program_id, const char *event_name, const OpenAdrInterval *intervals, @@ -59,32 +59,35 @@ size_t protocore_openadr_event(const char *program_id, const char *event_name, c { return 0; } - protocore_sb b = {out, cap, 0, cap > 0}; - Sb.put(&b, "{\"objectType\":\"EVENT\",\"programID\":"); - Sb.json(&b, program_id); - Sb.put(&b, ",\"eventName\":"); - Sb.json(&b, event_name); - Sb.put(&b, ",\"intervals\":["); + size_t b = 0; + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, + .text = "{\"objectType\":\"EVENT\",\"programID\":"); + b = EMBED_CALL(verba_textus.json, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = program_id); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"eventName\":"); + b = EMBED_CALL(verba_textus.json, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = event_name); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"intervals\":["); for (size_t i = 0; i < count; i++) { if (i) { - Sb.put(&b, ","); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ","); } - Sb.put(&b, "{\"id\":"); - put_u64(&b, i); - Sb.put(&b, ",\"interval\":{\"start\":"); - put_u64(&b, intervals[i].start); - Sb.put(&b, ",\"duration\":"); - put_u64(&b, intervals[i].duration); - Sb.put(&b, "},\"payloads\":[{\"type\":"); - Sb.json(&b, intervals[i].type); - Sb.put(&b, ",\"values\":["); - put_double(&b, intervals[i].value); - Sb.put(&b, "]}]}"); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "{\"id\":"); + b = put_u64(out, cap, b, i); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, + .text = ",\"interval\":{\"start\":"); + b = put_u64(out, cap, b, intervals[i].start); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"duration\":"); + b = put_u64(out, cap, b, intervals[i].duration); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, + .text = "},\"payloads\":[{\"type\":"); + b = EMBED_CALL(verba_textus.json, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = intervals[i].type); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"values\":["); + b = put_double(out, cap, b, intervals[i].value); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "]}]}"); } - Sb.put(&b, "]}"); - return Sb.finish(&b); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "]}"); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = b); } size_t protocore_openadr_report(const char *program_id, const char *event_id, const char *resource_name, double value, @@ -94,19 +97,23 @@ size_t protocore_openadr_report(const char *program_id, const char *event_id, co { return 0; } - protocore_sb b2 = {out, cap, 0, cap > 0}; - Sb.put(&b2, "{\"objectType\":\"REPORT\",\"programID\":"); - Sb.json(&b2, program_id); - Sb.put(&b2, ",\"eventID\":"); - Sb.json(&b2, event_id); - Sb.put(&b2, ",\"resources\":[{\"resourceName\":"); - Sb.json(&b2, resource_name); - Sb.put(&b2, ",\"intervals\":[{\"interval\":{\"start\":"); - put_u64(&b2, timestamp); - Sb.put(&b2, "},\"payloads\":[{\"type\":\"READING\",\"values\":["); - put_double(&b2, value); - Sb.put(&b2, "]}]}]}]}"); - return Sb.finish(&b2); + size_t b2 = 0; + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, + .text = "{\"objectType\":\"REPORT\",\"programID\":"); + b2 = EMBED_CALL(verba_textus.json, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = program_id); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = ",\"eventID\":"); + b2 = EMBED_CALL(verba_textus.json, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = event_id); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, + .text = ",\"resources\":[{\"resourceName\":"); + b2 = EMBED_CALL(verba_textus.json, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = resource_name); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, + .text = ",\"intervals\":[{\"interval\":{\"start\":"); + b2 = put_u64(out, cap, b2, timestamp); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, + .text = "},\"payloads\":[{\"type\":\"READING\",\"values\":["); + b2 = put_double(out, cap, b2, value); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = "]}]}]}]}"); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = b2); } PROTOCORE_END_DECLS diff --git a/src/services/energy/sep2/CMakeLists.txt b/src/services/energy/sep2/CMakeLists.txt index 7a4b45330..4d151bc31 100644 --- a/src/services/energy/sep2/CMakeLists.txt +++ b/src/services/energy/sep2/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/energy/sep2 GATE PROTOCORE_ENABLE_SEP2 SOURCES sep2.c PRIVATE_DEPS - mmgr/membuild + mmgr ) diff --git a/src/services/energy/sep2/sep2.c b/src/services/energy/sep2/sep2.c index c30b174f5..b4a7efafe 100644 --- a/src/services/energy/sep2/sep2.c +++ b/src/services/energy/sep2/sep2.c @@ -10,16 +10,16 @@ #if PROTOCORE_ENABLE_SEP2 -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder #include "services/energy/sep2/sep2.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS -static void put_i64(protocore_sb *b, int64_t v) +static size_t put_i64(char *out, size_t cap, size_t at, int64_t v) { - if (!b->ok) + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = at)) { - return; + return at; } char tmp[21]; int n = 0; @@ -30,18 +30,18 @@ static void put_i64(protocore_sb *b, int64_t v) tmp[n++] = (char)('0' + (int)(u % 10)); u /= 10; } while (u); - char out[22]; + char digits[22]; int k = 0; if (neg) { - out[k++] = '-'; + digits[k++] = '-'; } for (int i = 0; i < n; i++) { - out[k++] = tmp[n - 1 - i]; + digits[k++] = tmp[n - 1 - i]; } - out[k] = '\0'; - Sb.put(b, out); + digits[k] = '\0'; + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = digits); } static const char *NS = " xmlns=\"urn:ieee:std:2030.5:ns\""; @@ -50,56 +50,73 @@ static const char *DECL = ""; size_t protocore_sep2_device_capability(uint32_t poll_rate, const char *edev_list_href, const char *derp_list_href, char *out, size_t cap) { - protocore_sb b = {out, cap, 0, out != NULL && cap > 0}; - Sb.put(&b, DECL); - Sb.put(&b, ""); - Sb.put(&b, ""); - Sb.put(&b, ""); - Sb.put(&b, ""); - return Sb.finish(&b); + if (!out || cap == 0) + { + return 0; + } + size_t b = 0; + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = DECL); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ""); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, + .text = ""); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, + .text = ""); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ""); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = b); } size_t protocore_sep2_end_device(uint64_t sfdi, const char *lfdi, const char *href, char *out, size_t cap) { - protocore_sb b2 = {out, cap, 0, out != NULL && cap > 0}; - Sb.put(&b2, DECL); - Sb.put(&b2, ""); - put_i64(&b2, (int64_t)sfdi); - Sb.put(&b2, ""); - Sb.xml(&b2, lfdi); - Sb.put(&b2, ""); - return Sb.finish(&b2); + if (!out || cap == 0) + { + return 0; + } + size_t b2 = 0; + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = DECL); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = ""); + b2 = put_i64(out, cap, b2, (int64_t)sfdi); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = ""); + b2 = EMBED_CALL(verba_textus.xml, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = lfdi); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = ""); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = b2); } size_t protocore_sep2_der_control(const char *mrid, uint32_t start, uint32_t duration, int32_t opmod_target_w, char *out, size_t cap) { - protocore_sb b3 = {out, cap, 0, out != NULL && cap > 0}; - Sb.put(&b3, DECL); - Sb.put(&b3, ""); - Sb.xml(&b3, mrid); - Sb.put(&b3, ""); - put_i64(&b3, start); - Sb.put(&b3, ""); - put_i64(&b3, duration); - Sb.put(&b3, ""); - put_i64(&b3, opmod_target_w); - Sb.put(&b3, ""); - return Sb.finish(&b3); + if (!out || cap == 0) + { + return 0; + } + size_t b3 = 0; + b3 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b3, .text = DECL); + b3 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b3, .text = "error = PROTO_TRUE; return PROTO_FALSE; } - mem.cpy(w->buf + w->pos, p, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = w->buf + w->pos, .src = p, .bytes = n); w->pos += n; return PROTO_TRUE; } @@ -186,7 +186,7 @@ proto_bool protocore_sunspec_write_string(SunSpecWriter *w, const char *s, size_ w->error = PROTO_TRUE; return PROTO_FALSE; } - size_t slen = str.len(s, field); + size_t slen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = field); for (size_t i = 0; i < field; i++) { w->buf[w->pos + i] = (i < slen) ? (uint8_t)s[i] : 0; // NUL-pad the remainder diff --git a/src/services/fieldbus/ads/CMakeLists.txt b/src/services/fieldbus/ads/CMakeLists.txt index 9f26042a1..18cb40e44 100644 --- a/src/services/fieldbus/ads/CMakeLists.txt +++ b/src/services/fieldbus/ads/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/fieldbus/ads GATE PROTOCORE_ENABLE_ADS SOURCES ads.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/ads/ads.c b/src/services/fieldbus/ads/ads.c index c4056ab71..1b560323f 100644 --- a/src/services/fieldbus/ads/ads.c +++ b/src/services/fieldbus/ads/ads.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_ADS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/ads/ads.h" -#include "mmgr/endian/endian.h" +#include "endian/endian.h" PROTOCORE_BEGIN_DECLS @@ -29,19 +29,23 @@ static size_t write_header(uint8_t *buf, size_t cap, const AdsRequest *r, AdsCom // AMS/TCP header: reserved(2) + length(4). length covers the AMS header + payload. buf[p++] = 0x00; buf[p++] = 0x00; - p += endian.wr32le(buf + p, (uint32_t)ADS_AMS_HDR_LEN + payload_len); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = (uint32_t)ADS_AMS_HDR_LEN + payload_len, + .width = MMGR_ENDIAN_32); // AMS header. - mem.cpy(buf + p, r->target.net_id, ADS_NET_ID_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = r->target.net_id, .bytes = ADS_NET_ID_LEN); p += ADS_NET_ID_LEN; - p += endian.wr16le(buf + p, r->target.port); - mem.cpy(buf + p, r->source.net_id, ADS_NET_ID_LEN); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->target.port, .width = MMGR_ENDIAN_16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = r->source.net_id, .bytes = ADS_NET_ID_LEN); p += ADS_NET_ID_LEN; - p += endian.wr16le(buf + p, r->source.port); - p += endian.wr16le(buf + p, (uint16_t)cmd); // wire byte in - p += endian.wr16le(buf + p, ADS_STATE_REQUEST); - p += endian.wr32le(buf + p, payload_len); // cbData - p += endian.wr32le(buf + p, 0); // error code (0 on a request) - p += endian.wr32le(buf + p, r->invoke_id); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->source.port, .width = MMGR_ENDIAN_16); + // wire byte in + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = (uint16_t)cmd, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = ADS_STATE_REQUEST, .width = MMGR_ENDIAN_16); + // cbData + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = payload_len, .width = MMGR_ENDIAN_32); + // error code (0 on a request) + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = 0, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->invoke_id, .width = MMGR_ENDIAN_32); return p; // == ADS_HDR_LEN } @@ -86,9 +90,9 @@ void protocore_ads_build_read(uint8_t *work) AdsV.n = 0; return; } - p += endian.wr32le(buf + p, index_group); - p += endian.wr32le(buf + p, index_offset); - p += endian.wr32le(buf + p, read_len); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = index_group, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = index_offset, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = read_len, .width = MMGR_ENDIAN_32); AdsV.n = p; } @@ -114,12 +118,12 @@ void protocore_ads_build_write(uint8_t *work) AdsV.n = 0; return; } - p += endian.wr32le(buf + p, index_group); - p += endian.wr32le(buf + p, index_offset); - p += endian.wr32le(buf + p, len); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = index_group, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = index_offset, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = len, .width = MMGR_ENDIAN_32); if (len) { - mem.cpy(buf + p, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = data, .bytes = len); p += len; } AdsV.n = p; @@ -148,13 +152,13 @@ void protocore_ads_build_read_write(uint8_t *work) AdsV.n = 0; return; } - p += endian.wr32le(buf + p, index_group); - p += endian.wr32le(buf + p, index_offset); - p += endian.wr32le(buf + p, read_len); - p += endian.wr32le(buf + p, write_len); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = index_group, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = index_offset, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = read_len, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = write_len, .width = MMGR_ENDIAN_32); if (write_len) { - mem.cpy(buf + p, write_data, write_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = write_data, .bytes = write_len); p += write_len; } AdsV.n = p; @@ -182,12 +186,13 @@ void protocore_ads_build_write_control(uint8_t *work) AdsV.n = 0; return; } - p += endian.wr16le(buf + p, protocore_ads_state); - p += endian.wr16le(buf + p, device_state); - p += endian.wr32le(buf + p, len); + p += + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = protocore_ads_state, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = device_state, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = len, .width = MMGR_ENDIAN_32); if (len) { - mem.cpy(buf + p, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = data, .bytes = len); p += len; } AdsV.n = p; @@ -213,13 +218,14 @@ void protocore_ads_build_add_notification(uint8_t *work) AdsV.n = 0; return; } - p += endian.wr32le(buf + p, index_group); - p += endian.wr32le(buf + p, index_offset); - p += endian.wr32le(buf + p, length); - p += endian.wr32le(buf + p, (uint32_t)mode); // wire byte in - p += endian.wr32le(buf + p, max_delay); - p += endian.wr32le(buf + p, cycle_time); - mem.set(buf + p, 0, 16); // reserved + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = index_group, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = index_offset, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = length, .width = MMGR_ENDIAN_32); + // wire byte in + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = (uint32_t)mode, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = max_delay, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = cycle_time, .width = MMGR_ENDIAN_32); + EMBED_CALL(memor.set, MemoriaCfg, .dst = buf + p, .val = 0, .bytes = 16); // reserved p += 16; AdsV.n = p; } @@ -238,7 +244,8 @@ void protocore_ads_build_del_notification(uint8_t *work) AdsV.n = 0; return; } - p += endian.wr32le(buf + p, notification_handle); + p += + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = notification_handle, .width = MMGR_ENDIAN_32); AdsV.n = p; } @@ -259,7 +266,8 @@ void protocore_ads_parse_ams_header(uint8_t *work) AdsV.ok = PROTO_FALSE; return; } - uint32_t frame_len = endian.rd32le(buf + 2); // AMS header + payload + // AMS header + payload + uint32_t frame_len = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = buf + 2, .width = MMGR_ENDIAN_32); if (frame_len < (uint32_t)ADS_AMS_HDR_LEN) { AdsV.ok = PROTO_FALSE; @@ -271,15 +279,16 @@ void protocore_ads_parse_ams_header(uint8_t *work) return; } const uint8_t *a = buf + ADS_AMSTCP_HDR_LEN; - mem.cpy(out->target.net_id, a, ADS_NET_ID_LEN); - out->target.port = endian.rd16le(a + 6); - mem.cpy(out->source.net_id, a + 8, ADS_NET_ID_LEN); - out->source.port = endian.rd16le(a + 14); - out->cmd = (AdsCommand)endian.rd16le(a + 16); // wire byte out - out->state_flags = endian.rd16le(a + 18); - out->data_len = endian.rd32le(a + 20); - out->error_code = endian.rd32le(a + 24); - out->invoke_id = endian.rd32le(a + 28); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->target.net_id, .src = a, .bytes = ADS_NET_ID_LEN); + out->target.port = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = a + 6, .width = MMGR_ENDIAN_16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->source.net_id, .src = a + 8, .bytes = ADS_NET_ID_LEN); + out->source.port = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = a + 14, .width = MMGR_ENDIAN_16); + // wire byte out + out->cmd = (AdsCommand)(uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = a + 16, .width = MMGR_ENDIAN_16); + out->state_flags = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = a + 18, .width = MMGR_ENDIAN_16); + out->data_len = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = a + 20, .width = MMGR_ENDIAN_32); + out->error_code = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = a + 24, .width = MMGR_ENDIAN_32); + out->invoke_id = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = a + 28, .width = MMGR_ENDIAN_32); // cbData must fit inside the frame the AMS/TCP length promised. if ((uint32_t)ADS_AMS_HDR_LEN + out->data_len > frame_len) { @@ -302,8 +311,8 @@ void protocore_ads_parse_read(uint8_t *work) AdsV.ok = PROTO_FALSE; return; } - out->result = endian.rd32le(data); - out->len = endian.rd32le(data + 4); + out->result = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data, .width = MMGR_ENDIAN_32); + out->len = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + 4, .width = MMGR_ENDIAN_32); if (8 + (size_t)out->len > data_len) { AdsV.ok = PROTO_FALSE; @@ -325,7 +334,7 @@ void protocore_ads_parse_result(uint8_t *work) AdsV.ok = PROTO_FALSE; return; } - *result = endian.rd32le(data); + *result = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data, .width = MMGR_ENDIAN_32); AdsV.ok = PROTO_TRUE; } @@ -341,9 +350,10 @@ void protocore_ads_parse_read_state(uint8_t *work) AdsV.ok = PROTO_FALSE; return; } - out->result = endian.rd32le(data); - out->protocore_ads_state = endian.rd16le(data + 4); - out->device_state = endian.rd16le(data + 6); + out->result = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data, .width = MMGR_ENDIAN_32); + out->protocore_ads_state = + (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + 4, .width = MMGR_ENDIAN_16); + out->device_state = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + 6, .width = MMGR_ENDIAN_16); AdsV.ok = PROTO_TRUE; } @@ -359,11 +369,11 @@ void protocore_ads_parse_read_device_info(uint8_t *work) AdsV.ok = PROTO_FALSE; return; } - out->result = endian.rd32le(data); + out->result = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data, .width = MMGR_ENDIAN_32); out->version_major = data[4]; out->version_minor = data[5]; - out->version_build = endian.rd16le(data + 6); - mem.cpy(out->device_name, data + 8, ADS_DEVICE_NAME_LEN); + out->version_build = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + 6, .width = MMGR_ENDIAN_16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->device_name, .src = data + 8, .bytes = ADS_DEVICE_NAME_LEN); out->device_name[ADS_DEVICE_NAME_LEN] = '\0'; // the field is not guaranteed NUL-terminated AdsV.ok = PROTO_TRUE; } @@ -381,8 +391,8 @@ void protocore_ads_parse_add_notification(uint8_t *work) AdsV.ok = PROTO_FALSE; return; } - *result = endian.rd32le(data); - *handle = endian.rd32le(data + 4); + *result = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data, .width = MMGR_ENDIAN_32); + *handle = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + 4, .width = MMGR_ENDIAN_32); AdsV.ok = PROTO_TRUE; } @@ -400,8 +410,9 @@ void protocore_ads_parse_notification(uint8_t *work) AdsV.ok = PROTO_FALSE; return; } - uint32_t length = endian.rd32le(data); // octets after this field - uint32_t stamps = endian.rd32le(data + 4); + // octets after this field + uint32_t length = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data, .width = MMGR_ENDIAN_32); + uint32_t stamps = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + 4, .width = MMGR_ENDIAN_32); if (4 + (size_t)length > data_len) { AdsV.ok = PROTO_FALSE; @@ -415,8 +426,9 @@ void protocore_ads_parse_notification(uint8_t *work) AdsV.ok = PROTO_FALSE; return; } - uint64_t timestamp = endian.rd64le(data + p); - uint32_t samples = endian.rd32le(data + p + 8); + uint64_t timestamp = EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + p, .width = MMGR_ENDIAN_64); + uint32_t samples = + (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + p + 8, .width = MMGR_ENDIAN_32); p += 12; for (uint32_t i = 0; i < samples; i++) { @@ -425,8 +437,10 @@ void protocore_ads_parse_notification(uint8_t *work) AdsV.ok = PROTO_FALSE; return; } - uint32_t handle = endian.rd32le(data + p); - uint32_t size = endian.rd32le(data + p + 4); + uint32_t handle = + (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + p, .width = MMGR_ENDIAN_32); + uint32_t size = + (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = data + p + 4, .width = MMGR_ENDIAN_32); p += 8; if (p + (size_t)size > data_len) { diff --git a/src/services/fieldbus/bacnet/CMakeLists.txt b/src/services/fieldbus/bacnet/CMakeLists.txt index d601ac498..9d1dbc83a 100644 --- a/src/services/fieldbus/bacnet/CMakeLists.txt +++ b/src/services/fieldbus/bacnet/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/bacnet GATE PROTOCORE_ENABLE_BACNET SOURCES bacnet.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/bacnet/bacnet.c b/src/services/fieldbus/bacnet/bacnet.c index d535e425e..7f39e15b0 100644 --- a/src/services/fieldbus/bacnet/bacnet.c +++ b/src/services/fieldbus/bacnet/bacnet.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_BACNET -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/bacnet/bacnet.h" PROTOCORE_BEGIN_DECLS @@ -46,7 +46,7 @@ void protocore_bacnet_bvlc_build(uint8_t *work) buf[3] = (uint8_t)(total & 0xFF); if (npdu_len) { - mem.cpy(buf + BVLC_HEADER_SIZE, npdu, npdu_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + BVLC_HEADER_SIZE, .src = npdu, .bytes = npdu_len); } BacnetV.n = total; } @@ -136,14 +136,14 @@ void protocore_bacnet_npdu_build(uint8_t *work) buf[p++] = dadr_len; if (dadr_len) { - mem.cpy(buf + p, dadr, dadr_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = dadr, .bytes = dadr_len); p += dadr_len; } buf[p++] = hop_count; // follows the (absent) source fields when a destination is present } if (apdu_len) { - mem.cpy(buf + p, apdu, apdu_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = apdu, .bytes = apdu_len); p += apdu_len; } BacnetV.n = p; @@ -283,7 +283,7 @@ void protocore_bacnet_apdu_build_who_is(uint8_t *work) BacnetV.n = 0; return; } - mem.cpy(buf, tmp, p); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf, .src = tmp, .bytes = p); BacnetV.n = p; } @@ -322,7 +322,7 @@ void protocore_bacnet_apdu_build_i_am(uint8_t *work) BacnetV.n = 0; return; } - mem.cpy(buf, tmp, p); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf, .src = tmp, .bytes = p); BacnetV.n = p; } @@ -362,7 +362,7 @@ void protocore_bacnet_apdu_build_read_property(uint8_t *work) BacnetV.n = 0; return; } - mem.cpy(buf, tmp, p); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf, .src = tmp, .bytes = p); BacnetV.n = p; } @@ -434,7 +434,7 @@ void protocore_bacnet_apdu_parse(uint8_t *work) BacnetV.ok = PROTO_FALSE; return; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); out->pdu_type = (uint8_t)(apdu[0] >> 4); size_t p = 1; switch (out->pdu_type) diff --git a/src/services/fieldbus/canopen/CMakeLists.txt b/src/services/fieldbus/canopen/CMakeLists.txt index b88bdb72d..6d777e003 100644 --- a/src/services/fieldbus/canopen/CMakeLists.txt +++ b/src/services/fieldbus/canopen/CMakeLists.txt @@ -7,5 +7,5 @@ protocore_add_module(services/fieldbus/canopen DEPS shared/can PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/canopen/canopen.c b/src/services/fieldbus/canopen/canopen.c index 65982bf0c..9995a8738 100644 --- a/src/services/fieldbus/canopen/canopen.c +++ b/src/services/fieldbus/canopen/canopen.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_CANOPEN -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/canopen/canopen.h" #include "shared/can/can.h" @@ -23,7 +23,7 @@ static void std_frame(CanFrame *f, uint32_t id, uint8_t dlc) f->extended = PROTO_FALSE; f->rtr = PROTO_FALSE; f->dlc = dlc; - mem.set(f->data, 0, sizeof(f->data)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = f->data, .val = 0, .bytes = sizeof(f->data)); } static proto_bool valid_node(uint8_t node_id) @@ -128,7 +128,8 @@ void protocore_canopen_build_emcy(uint8_t *work) out->data[2] = error_reg; // object 0x1001 error register if (msef) { - mem.cpy(out->data + 3, msef, 5); // 5 manufacturer-specific error octets + // 5 manufacturer-specific error octets + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->data + 3, .src = msef, .bytes = 5); } CanopenV.ok = PROTO_TRUE; } @@ -158,7 +159,7 @@ static proto_bool build_pdo(CanFrame *out, uint8_t pdo_num, proto_bool transmit, std_frame(out, base + node_id, len); if (len) { - mem.cpy(out->data, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->data, .src = data, .bytes = len); } return PROTO_TRUE; } @@ -233,7 +234,7 @@ void protocore_canopen_build_sdo_write(uint8_t *work) // download initiate, expedited (e=1), size indicated (s=1); n = unused octets in data[4..7]. out->data[0] = (uint8_t)((CANOPEN_SDO_CCS_DOWNLOAD << 5) | (((4u - len) & 3u) << 2) | 0x03u); sdo_set_object(out, index, sub); - mem.cpy(out->data + 4, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->data + 4, .src = data, .bytes = len); CanopenV.ok = PROTO_TRUE; } @@ -406,7 +407,7 @@ void protocore_canopen_parse_emcy(uint8_t *work) } if (msef) { - mem.cpy(msef, f->data + 3, 5); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = msef, .src = f->data + 3, .bytes = 5); } CanopenV.ok = PROTO_TRUE; } @@ -491,7 +492,7 @@ void protocore_canopen_parse_sdo_response(uint8_t *work) out->is_upload = PROTO_FALSE; out->expedited = PROTO_FALSE; out->len = 0; - mem.set(out->data, 0, sizeof(out->data)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out->data, .val = 0, .bytes = sizeof(out->data)); if (scs == CANOPEN_SDO_ABORT) { @@ -510,7 +511,7 @@ void protocore_canopen_parse_sdo_response(uint8_t *work) { out->expedited = PROTO_TRUE; out->len = s ? (uint8_t)(4u - ((cmd >> 2) & 0x03u)) : 4u; - mem.cpy(out->data, f->data + 4, out->len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->data, .src = f->data + 4, .bytes = out->len); } CanopenV.ok = PROTO_TRUE; // a non-expedited (segmented) response is reported with len 0 return; @@ -569,7 +570,7 @@ void protocore_canopen_build_sdo_download_segment(uint8_t *work) // segment: ccs=0, t=toggle (bit 4), n=unused octets (bits 1..3), c=last (bit 0). uint8_t n = (uint8_t)(CANOPEN_SDO_SEG_DATA - len); out->data[0] = (uint8_t)((toggle ? 0x10u : 0u) | ((n & 0x07u) << 1) | (last ? 0x01u : 0u)); - mem.cpy(out->data + 1, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->data + 1, .src = data, .bytes = len); CanopenV.ok = PROTO_TRUE; } @@ -621,7 +622,7 @@ void protocore_canopen_parse_sdo_segment(uint8_t *work) } if (data) { - mem.cpy(data, f->data + 1, seg_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = data, .src = f->data + 1, .bytes = seg_len); } CanopenV.ok = PROTO_TRUE; } @@ -670,7 +671,7 @@ void protocore_canopen_sdo_reasm_feed(uint8_t *work) } if (len) { - mem.cpy(r->buf + r->len, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = r->buf + r->len, .src = data, .bytes = len); } r->len += len; r->expect_toggle = !r->expect_toggle; diff --git a/src/services/fieldbus/cclink/CMakeLists.txt b/src/services/fieldbus/cclink/CMakeLists.txt index aecd77dc7..e6c65b810 100644 --- a/src/services/fieldbus/cclink/CMakeLists.txt +++ b/src/services/fieldbus/cclink/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/cclink GATE PROTOCORE_ENABLE_CCLINK SOURCES cclink.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/cclink/cclink.c b/src/services/fieldbus/cclink/cclink.c index 634bbed18..4fdb47e03 100644 --- a/src/services/fieldbus/cclink/cclink.c +++ b/src/services/fieldbus/cclink/cclink.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_CCLINK -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/cclink/cclink.h" PROTOCORE_BEGIN_DECLS @@ -64,12 +64,12 @@ void protocore_cclink_build(uint8_t *work) out[i++] = command; if (bit_len) { - mem.cpy(out + i, bits, bit_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + i, .src = bits, .bytes = bit_len); i += bit_len; } if (word_len) { - mem.cpy(out + i, words, word_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + i, .src = words, .bytes = word_len); i += word_len; } CclinkV.sum_args.bytes = out; diff --git a/src/services/fieldbus/cip/CMakeLists.txt b/src/services/fieldbus/cip/CMakeLists.txt index af778e39d..7cfe896f5 100644 --- a/src/services/fieldbus/cip/CMakeLists.txt +++ b/src/services/fieldbus/cip/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/cip GATE PROTOCORE_ENABLE_CIP SOURCES cip.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/cip/cip.c b/src/services/fieldbus/cip/cip.c index 3a4e73af7..f5945f450 100644 --- a/src/services/fieldbus/cip/cip.c +++ b/src/services/fieldbus/cip/cip.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_CIP -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/cip/cip.h" PROTOCORE_BEGIN_DECLS @@ -119,11 +119,11 @@ void protocore_cip_build_request(uint8_t *work) size_t p = 0; buf[p++] = service; buf[p++] = (uint8_t)(epath_len / 2); // path size in words - mem.cpy(buf + p, epath, epath_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = epath, .bytes = epath_len); p += epath_len; if (data_len) { - mem.cpy(buf + p, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = data, .bytes = data_len); p += data_len; } CipV.n = p; diff --git a/src/services/fieldbus/cotp/CMakeLists.txt b/src/services/fieldbus/cotp/CMakeLists.txt index d07bb2714..b67cbbec6 100644 --- a/src/services/fieldbus/cotp/CMakeLists.txt +++ b/src/services/fieldbus/cotp/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/cotp GATE PROTOCORE_ENABLE_COTP SOURCES cotp.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/cotp/cotp.c b/src/services/fieldbus/cotp/cotp.c index 862222891..6b5f98692 100644 --- a/src/services/fieldbus/cotp/cotp.c +++ b/src/services/fieldbus/cotp/cotp.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_COTP -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/cotp/cotp.h" PROTOCORE_BEGIN_DECLS @@ -45,7 +45,7 @@ void protocore_cotp_tpkt_build(uint8_t *work) buf[3] = (uint8_t)(total & 0xFF); if (payload_len) { - mem.cpy(buf + TPKT_HEADER_SIZE, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + TPKT_HEADER_SIZE, .src = payload, .bytes = payload_len); } CotpV.n = total; } @@ -115,7 +115,7 @@ void protocore_cotp_build_dt(uint8_t *work) buf[2] = (uint8_t)(eot ? COTP_EOT : 0); // EOT flag | TPDU-NR (0 for class 0) if (data_len) { - mem.cpy(buf + COTP_DT_HEADER_LEN, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + COTP_DT_HEADER_LEN, .src = data, .bytes = data_len); } CotpV.n = total; } @@ -157,7 +157,7 @@ void protocore_cotp_build_cr(uint8_t *work) buf[p++] = tpdu_size_code; if (extra_len) { - mem.cpy(buf + p, extra_params, extra_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = extra_params, .bytes = extra_len); p += extra_len; } CotpV.n = p; @@ -201,7 +201,7 @@ void protocore_cotp_build_cc(uint8_t *work) buf[p++] = tpdu_size_code; if (extra_len) { - mem.cpy(buf + p, extra_params, extra_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = extra_params, .bytes = extra_len); p += extra_len; } CotpV.n = p; diff --git a/src/services/fieldbus/devicenet/CMakeLists.txt b/src/services/fieldbus/devicenet/CMakeLists.txt index 21492abed..604a07a77 100644 --- a/src/services/fieldbus/devicenet/CMakeLists.txt +++ b/src/services/fieldbus/devicenet/CMakeLists.txt @@ -7,5 +7,5 @@ protocore_add_module(services/fieldbus/devicenet DEPS shared/can PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/devicenet/devicenet.c b/src/services/fieldbus/devicenet/devicenet.c index e3c929fdb..7d04a21b4 100644 --- a/src/services/fieldbus/devicenet/devicenet.c +++ b/src/services/fieldbus/devicenet/devicenet.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_DEVICENET -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/devicenet/devicenet.h" #include "shared/can/can.h" @@ -180,7 +180,7 @@ void protocore_devicenet_build_explicit(uint8_t *work) out->extended = PROTO_FALSE; out->rtr = PROTO_FALSE; out->dlc = (uint8_t)(1 + body_len); - mem.set(out->data, 0, sizeof(out->data)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out->data, .val = 0, .bytes = sizeof(out->data)); DevicenetV.msg_header_args.frag = PROTO_FALSE; DevicenetV.msg_header_args.xid = PROTO_FALSE; DevicenetV.msg_header_args.mac_id = mac_id; @@ -188,7 +188,7 @@ void protocore_devicenet_build_explicit(uint8_t *work) out->data[0] = DevicenetV.value; // not fragmented if (body_len) { - mem.cpy(out->data + 1, body, body_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->data + 1, .src = body, .bytes = body_len); } DevicenetV.ok = PROTO_TRUE; } @@ -227,7 +227,7 @@ void protocore_devicenet_build_fragment(uint8_t *work) out->extended = PROTO_FALSE; out->rtr = PROTO_FALSE; out->dlc = (uint8_t)(2 + data_len); - mem.set(out->data, 0, sizeof(out->data)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out->data, .val = 0, .bytes = sizeof(out->data)); DevicenetV.msg_header_args.frag = PROTO_TRUE; DevicenetV.msg_header_args.xid = xid; DevicenetV.msg_header_args.mac_id = mac_id; @@ -239,7 +239,7 @@ void protocore_devicenet_build_fragment(uint8_t *work) out->data[1] = DevicenetV.value; if (data_len) { - mem.cpy(out->data + 2, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->data + 2, .src = data, .bytes = data_len); } DevicenetV.ok = PROTO_TRUE; } @@ -251,7 +251,7 @@ void protocore_devicenet_frag_reset(uint8_t *work) if (rx) { - mem.set(rx, 0, sizeof(*rx)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = rx, .val = 0, .bytes = sizeof(*rx)); } } @@ -271,7 +271,7 @@ static proto_bool frag_append(DeviceNetFragRx *rx, const uint8_t *p, uint8_t n) { return PROTO_FALSE; } - mem.cpy(rx->buf + rx->len, p, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = rx->buf + rx->len, .src = p, .bytes = n); rx->len = (uint16_t)(rx->len + n); return PROTO_TRUE; } diff --git a/src/services/fieldbus/directnet/CMakeLists.txt b/src/services/fieldbus/directnet/CMakeLists.txt index 754a849c5..cc4c27fa1 100644 --- a/src/services/fieldbus/directnet/CMakeLists.txt +++ b/src/services/fieldbus/directnet/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/directnet GATE PROTOCORE_ENABLE_DIRECTNET SOURCES directnet.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/directnet/directnet.c b/src/services/fieldbus/directnet/directnet.c index 92fcceb5b..fb1a50751 100644 --- a/src/services/fieldbus/directnet/directnet.c +++ b/src/services/fieldbus/directnet/directnet.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_DIRECTNET -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/directnet/directnet.h" PROTOCORE_BEGIN_DECLS @@ -108,7 +108,7 @@ void protocore_directnet_data(uint8_t *work) out[i++] = DNET_STX; if (data_len) { - mem.cpy(out + i, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + i, .src = data, .bytes = data_len); i += data_len; } out[i++] = DNET_ETX; diff --git a/src/services/fieldbus/enip/CMakeLists.txt b/src/services/fieldbus/enip/CMakeLists.txt index 75e977ad9..3a0e67ca8 100644 --- a/src/services/fieldbus/enip/CMakeLists.txt +++ b/src/services/fieldbus/enip/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/enip GATE PROTOCORE_ENABLE_ENIP SOURCES enip.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/enip/enip.c b/src/services/fieldbus/enip/enip.c index 9b8b16860..1b56d2d1e 100644 --- a/src/services/fieldbus/enip/enip.c +++ b/src/services/fieldbus/enip/enip.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_ENIP -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/enip/enip.h" PROTOCORE_BEGIN_DECLS @@ -75,12 +75,12 @@ void protocore_enip_build(uint8_t *work) p += put16(buf + p, (uint16_t)data_len); // length covers the command data only p += put32(buf + p, h->session_handle); p += put32(buf + p, h->status); - mem.cpy(buf + p, h->sender_context, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = h->sender_context, .bytes = 8); p += 8; p += put32(buf + p, h->options); if (data_len) { - mem.cpy(buf + p, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = data, .bytes = data_len); p += data_len; } EnipV.n = p; @@ -104,7 +104,7 @@ void protocore_enip_parse(uint8_t *work) out->length = get16(buf + 2); out->session_handle = get32(buf + 4); out->status = get32(buf + 8); - mem.cpy(out->sender_context, buf + 12, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->sender_context, .src = buf + 12, .bytes = 8); out->options = get32(buf + 20); if ((size_t)EIP_HEADER_SIZE + out->length > len) // declared data not fully buffered { @@ -129,11 +129,11 @@ void protocore_enip_build_register_session(uint8_t *work) const uint8_t *sender_context = EnipV.build_register_session_args.sender_context; EipHeader h; - mem.set(&h, 0, sizeof(h)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &h, .val = 0, .bytes = sizeof(h)); h.command = EIP_CMD_REGISTER_SESSION; if (sender_context) { - mem.cpy(h.sender_context, sender_context, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = h.sender_context, .src = sender_context, .bytes = 8); } uint8_t data[4]; put16(data, 1); // protocol version @@ -154,12 +154,12 @@ void protocore_enip_build_unregister_session(uint8_t *work) const uint8_t *sender_context = EnipV.build_unregister_session_args.sender_context; EipHeader h; - mem.set(&h, 0, sizeof(h)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &h, .val = 0, .bytes = sizeof(h)); h.command = EIP_CMD_UNREGISTER_SESSION; h.session_handle = session_handle; // the session to close if (sender_context) { - mem.cpy(h.sender_context, sender_context, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = h.sender_context, .src = sender_context, .bytes = 8); } EnipV.build_args.buf = buf; EnipV.build_args.cap = cap; @@ -196,12 +196,12 @@ void protocore_enip_build_send_rr_data(uint8_t *work) // Write the header (length = the command-data length) then the command data straight into // buf - no temp buffer, so a large CIP payload never lands on the stack. EipHeader h; - mem.set(&h, 0, sizeof(h)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &h, .val = 0, .bytes = sizeof(h)); h.command = EIP_CMD_SEND_RR_DATA; h.session_handle = session_handle; if (sender_context) { - mem.cpy(h.sender_context, sender_context, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = h.sender_context, .src = sender_context, .bytes = 8); } EnipV.build_args.buf = buf; EnipV.build_args.cap = cap; @@ -227,7 +227,7 @@ void protocore_enip_build_send_rr_data(uint8_t *work) p += put16(buf + p, (uint16_t)cip_len); if (cip_len) { - mem.cpy(buf + p, cip, cip_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = cip, .bytes = cip_len); p += cip_len; } EnipV.n = p; @@ -240,11 +240,11 @@ void protocore_enip_build_list_identity(uint8_t *work) const uint8_t *sender_context = EnipV.build_list_identity_args.sender_context; EipHeader h; - mem.set(&h, 0, sizeof(h)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &h, .val = 0, .bytes = sizeof(h)); h.command = EIP_CMD_LIST_IDENTITY; if (sender_context) { - mem.cpy(h.sender_context, sender_context, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = h.sender_context, .src = sender_context, .bytes = 8); } EnipV.build_args.buf = buf; EnipV.build_args.cap = cap; diff --git a/src/services/fieldbus/fins/CMakeLists.txt b/src/services/fieldbus/fins/CMakeLists.txt index 3d9ebdc84..740364d23 100644 --- a/src/services/fieldbus/fins/CMakeLists.txt +++ b/src/services/fieldbus/fins/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/fins GATE PROTOCORE_ENABLE_FINS SOURCES fins.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/fins/fins.c b/src/services/fieldbus/fins/fins.c index 9372a6dfa..70b2c5cb9 100644 --- a/src/services/fieldbus/fins/fins.c +++ b/src/services/fieldbus/fins/fins.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_FINS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/fins/fins.h" PROTOCORE_BEGIN_DECLS @@ -79,7 +79,7 @@ void protocore_fins_build_command(uint8_t *work) buf[p++] = src; if (params_len) { - mem.cpy(buf + p, params, params_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = params, .bytes = params_len); p += params_len; } FinsV.n = p; @@ -158,7 +158,7 @@ void protocore_fins_build_memory_area_write(uint8_t *work) FinsV.n = 0; // the write data does not fit return; } - mem.cpy(buf + n, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + n, .src = data, .bytes = data_len); } FinsV.n = n + data_len; } diff --git a/src/services/fieldbus/hart/CMakeLists.txt b/src/services/fieldbus/hart/CMakeLists.txt index 7fb13b69d..21392d9e1 100644 --- a/src/services/fieldbus/hart/CMakeLists.txt +++ b/src/services/fieldbus/hart/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/hart GATE PROTOCORE_ENABLE_HART SOURCES hart.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/hart/hart.c b/src/services/fieldbus/hart/hart.c index a221dd0ca..1b3371144 100644 --- a/src/services/fieldbus/hart/hart.c +++ b/src/services/fieldbus/hart/hart.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_HART -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/hart/hart.h" PROTOCORE_BEGIN_DECLS @@ -68,13 +68,13 @@ void protocore_hart_build(uint8_t *work) size_t i = 0; out[i++] = delimiter; - mem.cpy(out + i, addr, addr_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + i, .src = addr, .bytes = addr_len); i += addr_len; out[i++] = command; out[i++] = (uint8_t)data_len; // byte count if (data_len) { - mem.cpy(out + i, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + i, .src = data, .bytes = data_len); i += data_len; } HartV.checksum_args.bytes = out; diff --git a/src/services/fieldbus/hostlink/CMakeLists.txt b/src/services/fieldbus/hostlink/CMakeLists.txt index cf7ff524e..9063ed7b4 100644 --- a/src/services/fieldbus/hostlink/CMakeLists.txt +++ b/src/services/fieldbus/hostlink/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/hostlink GATE PROTOCORE_ENABLE_HOSTLINK SOURCES hostlink.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/hostlink/hostlink.c b/src/services/fieldbus/hostlink/hostlink.c index 8c1ed689e..8de7b0d6e 100644 --- a/src/services/fieldbus/hostlink/hostlink.c +++ b/src/services/fieldbus/hostlink/hostlink.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_HOSTLINK -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/hostlink/hostlink.h" PROTOCORE_BEGIN_DECLS @@ -95,7 +95,7 @@ void protocore_hostlink_build(uint8_t *work) buf[p++] = header_code[1]; if (text_len) { - mem.cpy(buf + p, text, text_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = text, .bytes = text_len); p += text_len; } HostlinkV.fcs_args.data = buf; diff --git a/src/services/fieldbus/j1939/CMakeLists.txt b/src/services/fieldbus/j1939/CMakeLists.txt index c3c71968f..03e6b51e1 100644 --- a/src/services/fieldbus/j1939/CMakeLists.txt +++ b/src/services/fieldbus/j1939/CMakeLists.txt @@ -7,6 +7,6 @@ protocore_add_module(services/fieldbus/j1939 DEPS shared/can PRIVATE_DEPS - mmgr/plaintext - mmgr/protomem + mmgr + server/core/worker ) diff --git a/src/services/fieldbus/j1939/j1939.c b/src/services/fieldbus/j1939/j1939.c index 6e34032ab..bf03345ac 100644 --- a/src/services/fieldbus/j1939/j1939.c +++ b/src/services/fieldbus/j1939/j1939.c @@ -7,8 +7,8 @@ */ #include "services/fieldbus/j1939/j1939.h" -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "shared/can/can.h" #include "protocore_config.h" // the entry point: the enable gate below, and the widths @@ -34,7 +34,7 @@ uint8_t *protocore_j1939_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_J1939_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_J1939_BORROW); } return s_own.span; } @@ -118,8 +118,8 @@ static_assert(J1939_OFF_CTX + sizeof(J1939Ctx) <= PROTOCORE_J1939_BORROW, "PROTOCORE_J1939_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(J1939_OFF_CTX % _Alignof(J1939Ctx) == 0, @@ -147,8 +147,9 @@ static proto_bool ext_frame(uint8_t *work) J1939_CTX(work)->f->extended = PROTO_TRUE; J1939_CTX(work)->f->rtr = PROTO_FALSE; J1939_CTX(work)->f->dlc = J1939_CTX(work)->dlc; - mem.set(J1939_CTX(work)->f->data, 0xFF, - sizeof(J1939_CTX(work)->f->data)); // J1939 pads unused octets with 0xFF (not available) + // J1939 pads unused octets with 0xFF (not available) + EMBED_CALL(memor.set, MemoriaCfg, .dst = J1939_CTX(work)->f->data, .val = 0xFF, + .bytes = sizeof(J1939_CTX(work)->f->data)); return PROTO_TRUE; } @@ -180,7 +181,7 @@ void protocore_j1939_build_message(uint8_t *work) } if (len) { - mem.cpy(out->data, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->data, .src = data, .bytes = len); } J1939V.ok = PROTO_TRUE; } @@ -349,8 +350,9 @@ void protocore_j1939_build_tp_dt(uint8_t *work) return; // can't fail } - out->data[0] = seq; // sequence number, 1-based - mem.cpy(out->data + 1, chunk, chunk_len); // remaining octets stay 0xFF padding + out->data[0] = seq; // sequence number, 1-based + // remaining octets stay 0xFF padding + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->data + 1, .src = chunk, .bytes = chunk_len); J1939V.ok = PROTO_TRUE; } @@ -361,7 +363,7 @@ void protocore_j1939_tp_reset(uint8_t *work) if (rx) { - mem.set(rx, 0, sizeof(*rx)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = rx, .val = 0, .bytes = sizeof(*rx)); } } @@ -440,7 +442,7 @@ void protocore_j1939_tp_feed(uint8_t *work) } uint16_t remaining = (uint16_t)(rx->total_size - rx->received); uint8_t take = remaining < J1939_TP_DT_LEN ? (uint8_t)remaining : (uint8_t)J1939_TP_DT_LEN; - mem.cpy(rx->buf + rx->received, f->data + 1, take); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = rx->buf + rx->received, .src = f->data + 1, .bytes = take); rx->received = (uint16_t)(rx->received + take); rx->next_seq++; if (rx->received >= rx->total_size) diff --git a/src/services/fieldbus/lonworks/CMakeLists.txt b/src/services/fieldbus/lonworks/CMakeLists.txt index 3fdb4af61..24bd2ced9 100644 --- a/src/services/fieldbus/lonworks/CMakeLists.txt +++ b/src/services/fieldbus/lonworks/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/lonworks GATE PROTOCORE_ENABLE_LONWORKS SOURCES lonworks.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/lonworks/lonworks.c b/src/services/fieldbus/lonworks/lonworks.c index 8a8cfc2c5..636d217c9 100644 --- a/src/services/fieldbus/lonworks/lonworks.c +++ b/src/services/fieldbus/lonworks/lonworks.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_LONWORKS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/lonworks/lonworks.h" PROTOCORE_BEGIN_DECLS @@ -47,7 +47,7 @@ void protocore_lonworks_build_nv(uint8_t *work) out[1] = (uint8_t)selector; if (value_len) { - mem.cpy(out + LON_NV_HDR_LEN, value, value_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + LON_NV_HDR_LEN, .src = value, .bytes = value_len); } LonworksV.n = n; } diff --git a/src/services/fieldbus/mbplus/CMakeLists.txt b/src/services/fieldbus/mbplus/CMakeLists.txt index e410e6e6f..ae87b5396 100644 --- a/src/services/fieldbus/mbplus/CMakeLists.txt +++ b/src/services/fieldbus/mbplus/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(services/fieldbus/mbplus GATE PROTOCORE_ENABLE_MBPLUS SOURCES mbplus.c PRIVATE_DEPS - mmgr/protomem + mmgr shared/crc ) diff --git a/src/services/fieldbus/mbplus/mbplus.c b/src/services/fieldbus/mbplus/mbplus.c index 222556aff..b5c0605b3 100644 --- a/src/services/fieldbus/mbplus/mbplus.c +++ b/src/services/fieldbus/mbplus/mbplus.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_MBPLUS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/mbplus/mbplus.h" #include "shared/crc/crc.h" // PROTOCORE_CRC16_X25 @@ -65,7 +65,7 @@ void protocore_mbplus_build(uint8_t *work) out[i++] = control; if (payload_len) { - mem.cpy(out + i, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + i, .src = payload, .bytes = payload_len); i += payload_len; } MbplusV.crc_args.bytes = out + body; diff --git a/src/services/fieldbus/mbus/CMakeLists.txt b/src/services/fieldbus/mbus/CMakeLists.txt index 8f48e3242..990eb03c8 100644 --- a/src/services/fieldbus/mbus/CMakeLists.txt +++ b/src/services/fieldbus/mbus/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/mbus GATE PROTOCORE_ENABLE_MBUS SOURCES mbus.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/mbus/mbus.c b/src/services/fieldbus/mbus/mbus.c index d455dfa53..982577f90 100644 --- a/src/services/fieldbus/mbus/mbus.c +++ b/src/services/fieldbus/mbus/mbus.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_MBUS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/mbus/mbus.h" PROTOCORE_BEGIN_DECLS @@ -103,7 +103,7 @@ void protocore_mbus_build_long(uint8_t *work) buf[6] = ci; if (data_len) { - mem.cpy(buf + 7, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 7, .src = data, .bytes = data_len); } buf[4 + L] = checksum(buf + 4, L); // sum of C..end of user data buf[5 + L] = MBUS_STOP; @@ -492,7 +492,7 @@ void protocore_mbus_record_value_real(uint8_t *work) } uint32_t bits = (uint32_t)r->data[0] | ((uint32_t)r->data[1] << 8) | ((uint32_t)r->data[2] << 16) | ((uint32_t)r->data[3] << 24); - mem.cpy(out, &bits, 4); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = &bits, .bytes = 4); MbusV.ok = PROTO_TRUE; } diff --git a/src/services/fieldbus/melsec/CMakeLists.txt b/src/services/fieldbus/melsec/CMakeLists.txt index c53cb6d2b..68ee44c11 100644 --- a/src/services/fieldbus/melsec/CMakeLists.txt +++ b/src/services/fieldbus/melsec/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/fieldbus/melsec GATE PROTOCORE_ENABLE_MELSEC SOURCES melsec.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/melsec/melsec.c b/src/services/fieldbus/melsec/melsec.c index 55e28512a..833db5dcb 100644 --- a/src/services/fieldbus/melsec/melsec.c +++ b/src/services/fieldbus/melsec/melsec.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_MELSEC -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/melsec/melsec.h" -#include "mmgr/endian/endian.h" +#include "endian/endian.h" PROTOCORE_BEGIN_DECLS @@ -42,19 +42,22 @@ void protocore_melsec_build_read(uint8_t *work) buf[p++] = MELSEC_3E_REQ_SUBHEADER1; buf[p++] = MELSEC_NETWORK_DEFAULT; buf[p++] = MELSEC_PROTOCORE_DEFAULT; - p += endian.wr16le(buf + p, MELSEC_DEST_IO_DEFAULT); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = MELSEC_DEST_IO_DEFAULT, + .width = MMGR_ENDIAN_16); buf[p++] = MELSEC_DEST_MULTIDROP_DEFAULT; // request data length = the octets from the monitoring timer onward: // timer(2) + command(2) + subcommand(2) + head device(3) + device code(1) + points(2) = 12 - p += endian.wr16le(buf + p, MELSEC_3E_READ_REQ_DATA_LEN); - p += endian.wr16le(buf + p, monitoring_timer); - p += endian.wr16le(buf + p, MELSEC_CMD_BATCH_READ); - p += endian.wr16le(buf + p, MELSEC_SUBCMD_WORD); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = MELSEC_3E_READ_REQ_DATA_LEN, + .width = MMGR_ENDIAN_16); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = monitoring_timer, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = MELSEC_CMD_BATCH_READ, + .width = MMGR_ENDIAN_16); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = MELSEC_SUBCMD_WORD, .width = MMGR_ENDIAN_16); buf[p++] = (uint8_t)(head_device & 0xFF); // head device number, 3 octets little-endian buf[p++] = (uint8_t)((head_device >> 8) & 0xFF); buf[p++] = (uint8_t)((head_device >> 16) & 0xFF); buf[p++] = device_code; - p += endian.wr16le(buf + p, points); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = points, .width = MMGR_ENDIAN_16); MelsecV.n = p; // == MELSEC_3E_READ_REQ_LEN } @@ -90,21 +93,24 @@ void protocore_melsec_build_write(uint8_t *work) buf[p++] = MELSEC_3E_REQ_SUBHEADER1; buf[p++] = MELSEC_NETWORK_DEFAULT; buf[p++] = MELSEC_PROTOCORE_DEFAULT; - p += endian.wr16le(buf + p, MELSEC_DEST_IO_DEFAULT); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = MELSEC_DEST_IO_DEFAULT, + .width = MMGR_ENDIAN_16); buf[p++] = MELSEC_DEST_MULTIDROP_DEFAULT; // request data length = the fixed 12 (timer..points) plus the write data octets. - p += endian.wr16le(buf + p, (uint16_t)(MELSEC_3E_READ_REQ_DATA_LEN + data_len)); - p += endian.wr16le(buf + p, monitoring_timer); - p += endian.wr16le(buf + p, MELSEC_CMD_BATCH_WRITE); - p += endian.wr16le(buf + p, MELSEC_SUBCMD_WORD); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, + .val = (uint16_t)(MELSEC_3E_READ_REQ_DATA_LEN + data_len), .width = MMGR_ENDIAN_16); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = monitoring_timer, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = MELSEC_CMD_BATCH_WRITE, + .width = MMGR_ENDIAN_16); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = MELSEC_SUBCMD_WORD, .width = MMGR_ENDIAN_16); buf[p++] = (uint8_t)(head_device & 0xFF); // head device number, 3 octets little-endian buf[p++] = (uint8_t)((head_device >> 8) & 0xFF); buf[p++] = (uint8_t)((head_device >> 16) & 0xFF); buf[p++] = device_code; - p += endian.wr16le(buf + p, points); + p += EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = buf + p, .val = points, .width = MMGR_ENDIAN_16); if (data_len) { - mem.cpy(buf + p, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = data, .bytes = data_len); p += data_len; } MelsecV.n = p; // == MELSEC_3E_READ_REQ_LEN + data_len @@ -128,7 +134,9 @@ void protocore_melsec_parse_response(uint8_t *work) MelsecV.ok = PROTO_FALSE; return; } - uint16_t data_length = endian.rd16le(buf + MELSEC_3E_RES_LEN_OFFSET); // covers the end code + the response data + // covers the end code + the response data + uint16_t data_length = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = buf + MELSEC_3E_RES_LEN_OFFSET, + .width = MMGR_ENDIAN_16); if (data_length < MELSEC_ENDCODE_LEN) { MelsecV.ok = PROTO_FALSE; @@ -139,7 +147,8 @@ void protocore_melsec_parse_response(uint8_t *work) MelsecV.ok = PROTO_FALSE; return; } - out->end_code = endian.rd16le(buf + MELSEC_3E_RES_DATALEN_BASE); + out->end_code = (uint16_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = buf + MELSEC_3E_RES_DATALEN_BASE, + .width = MMGR_ENDIAN_16); out->data = buf + MELSEC_3E_RES_DATA_OFFSET; out->data_len = (size_t)data_length - MELSEC_ENDCODE_LEN; // minus the 2-octet end code MelsecV.ok = PROTO_TRUE; diff --git a/src/services/fieldbus/powerlink/CMakeLists.txt b/src/services/fieldbus/powerlink/CMakeLists.txt index 136335ce4..bb154a72d 100644 --- a/src/services/fieldbus/powerlink/CMakeLists.txt +++ b/src/services/fieldbus/powerlink/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/powerlink GATE PROTOCORE_ENABLE_POWERLINK SOURCES powerlink.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/powerlink/powerlink.c b/src/services/fieldbus/powerlink/powerlink.c index 0421bcd29..3b5bcfd9f 100644 --- a/src/services/fieldbus/powerlink/powerlink.c +++ b/src/services/fieldbus/powerlink/powerlink.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_POWERLINK -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/powerlink/powerlink.h" PROTOCORE_BEGIN_DECLS @@ -50,7 +50,7 @@ void protocore_powerlink_build(uint8_t *work) out[2] = source; if (payload_len) { - mem.cpy(out + 3, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 3, .src = payload, .bytes = payload_len); } PowerlinkV.n = n; } diff --git a/src/services/fieldbus/profibus/CMakeLists.txt b/src/services/fieldbus/profibus/CMakeLists.txt index dd3d49c3d..1edee3775 100644 --- a/src/services/fieldbus/profibus/CMakeLists.txt +++ b/src/services/fieldbus/profibus/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/profibus GATE PROTOCORE_ENABLE_PROFIBUS SOURCES profibus.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/profibus/profibus.c b/src/services/fieldbus/profibus/profibus.c index 6894697c3..59a6164a7 100644 --- a/src/services/fieldbus/profibus/profibus.c +++ b/src/services/fieldbus/profibus/profibus.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_PROFIBUS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/profibus/profibus.h" PROTOCORE_BEGIN_DECLS @@ -98,7 +98,7 @@ void protocore_profibus_build_sd2(uint8_t *work) out[i++] = fc; if (data_len) { - mem.cpy(out + i, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + i, .src = data, .bytes = data_len); i += data_len; } // FCS over DA+SA+FC+data (out[4 .. 4+le-1]). @@ -128,7 +128,7 @@ void protocore_profibus_build_sd3(uint8_t *work) out[1] = da; out[2] = sa; out[3] = fc; - mem.cpy(out + 4, data, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 4, .src = data, .bytes = 8); ProfibusV.fcs_args.bytes = out + 1; ProfibusV.fcs_args.len = 11; protocore_profibus_fcs(work); diff --git a/src/services/fieldbus/profinet/CMakeLists.txt b/src/services/fieldbus/profinet/CMakeLists.txt index 0a6a5a41e..01fcd3f74 100644 --- a/src/services/fieldbus/profinet/CMakeLists.txt +++ b/src/services/fieldbus/profinet/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/profinet GATE PROTOCORE_ENABLE_PROFINET SOURCES profinet.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/profinet/profinet.c b/src/services/fieldbus/profinet/profinet.c index f64a514da..d8eb09101 100644 --- a/src/services/fieldbus/profinet/profinet.c +++ b/src/services/fieldbus/profinet/profinet.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_PROFINET -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/profinet/profinet.h" PROTOCORE_BEGIN_DECLS @@ -80,7 +80,7 @@ void protocore_profinet_dcp_block(uint8_t *work) out[3] = (uint8_t)value_len; if (value_len) { - mem.cpy(out + 4, value, value_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 4, .src = value, .bytes = value_len); } if (pad) { diff --git a/src/services/fieldbus/rawl2/CMakeLists.txt b/src/services/fieldbus/rawl2/CMakeLists.txt index 8f0e1f483..51062a82d 100644 --- a/src/services/fieldbus/rawl2/CMakeLists.txt +++ b/src/services/fieldbus/rawl2/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(services/fieldbus/rawl2 GATE PROTOCORE_ENABLE_RAWL2 SOURCES rawl2.c PRIVATE_DEPS - mmgr/protomem + mmgr shared/crc ) diff --git a/src/services/fieldbus/rawl2/rawl2.c b/src/services/fieldbus/rawl2/rawl2.c index 5e1127c0f..39a743692 100644 --- a/src/services/fieldbus/rawl2/rawl2.c +++ b/src/services/fieldbus/rawl2/rawl2.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_RAWL2 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/rawl2/rawl2.h" #include "shared/crc/crc.h" // PROTOCORE_CRC32_ISO_HDLC @@ -43,13 +43,13 @@ void protocore_rawl2_build(uint8_t *work) Rawl2V.n = 0; return; } - mem.cpy(out, dst, ETH_ALEN); - mem.cpy(out + ETH_ALEN, src, ETH_ALEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = dst, .bytes = ETH_ALEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + ETH_ALEN, .src = src, .bytes = ETH_ALEN); out[12] = (uint8_t)(ethertype >> 8); out[13] = (uint8_t)ethertype; if (payload_len) { - mem.cpy(out + ETH_HDR_LEN, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + ETH_HDR_LEN, .src = payload, .bytes = payload_len); } Rawl2V.n = n; } @@ -79,8 +79,8 @@ void protocore_rawl2_build_vlan(uint8_t *work) Rawl2V.n = 0; return; } - mem.cpy(out, dst, ETH_ALEN); - mem.cpy(out + ETH_ALEN, src, ETH_ALEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = dst, .bytes = ETH_ALEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + ETH_ALEN, .src = src, .bytes = ETH_ALEN); out[12] = (uint8_t)(ETH_TPID_8021Q >> 8); out[13] = (uint8_t)ETH_TPID_8021Q; uint16_t tci = (uint16_t)(((pcp & 0x7) << 13) | ((dei ? 1 : 0) << 12) | (vid & 0x0FFF)); @@ -90,7 +90,7 @@ void protocore_rawl2_build_vlan(uint8_t *work) out[17] = (uint8_t)ethertype; if (payload_len) { - mem.cpy(out + ETH_VLAN_HDR_LEN, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + ETH_VLAN_HDR_LEN, .src = payload, .bytes = payload_len); } Rawl2V.n = n; } diff --git a/src/services/fieldbus/s7comm/CMakeLists.txt b/src/services/fieldbus/s7comm/CMakeLists.txt index b99387c59..c46176cf9 100644 --- a/src/services/fieldbus/s7comm/CMakeLists.txt +++ b/src/services/fieldbus/s7comm/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/s7comm GATE PROTOCORE_ENABLE_S7COMM SOURCES s7comm.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/s7comm/s7comm.c b/src/services/fieldbus/s7comm/s7comm.c index 96b8f5e9d..64e002e55 100644 --- a/src/services/fieldbus/s7comm/s7comm.c +++ b/src/services/fieldbus/s7comm/s7comm.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_S7COMM -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/s7comm/s7comm.h" PROTOCORE_BEGIN_DECLS @@ -198,7 +198,7 @@ void protocore_s7comm_build_write_request(uint8_t *work) p += put16(buf + p, s7_data_wire_len(it->data_transport_size, it->data_len)); if (it->data_len) { - mem.cpy(buf + p, it->data, it->data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = it->data, .bytes = it->data_len); p += it->data_len; } if (i + 1 < n && (it->data_len & 1)) // even-pad all but the last diff --git a/src/services/fieldbus/sercos/CMakeLists.txt b/src/services/fieldbus/sercos/CMakeLists.txt index 57e064bfa..322b5e11d 100644 --- a/src/services/fieldbus/sercos/CMakeLists.txt +++ b/src/services/fieldbus/sercos/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/sercos GATE PROTOCORE_ENABLE_SERCOS SOURCES sercos.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/sercos/sercos.c b/src/services/fieldbus/sercos/sercos.c index c8f5e6f4c..4eba6039e 100644 --- a/src/services/fieldbus/sercos/sercos.c +++ b/src/services/fieldbus/sercos/sercos.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_SERCOS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/sercos/sercos.h" PROTOCORE_BEGIN_DECLS @@ -81,7 +81,7 @@ void protocore_sercos_build(uint8_t *work) out[3] = (uint8_t)(cycle >> 8); if (data_len) { - mem.cpy(out + SERCOS_HDR_LEN, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + SERCOS_HDR_LEN, .src = data, .bytes = data_len); } SercosV.n = n; } diff --git a/src/services/fieldbus/simatic/CMakeLists.txt b/src/services/fieldbus/simatic/CMakeLists.txt index 2b63525e7..a183ff47a 100644 --- a/src/services/fieldbus/simatic/CMakeLists.txt +++ b/src/services/fieldbus/simatic/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(services/fieldbus/simatic GATE PROTOCORE_ENABLE_SIMATIC SOURCES simatic.c PRIVATE_DEPS - mmgr/plaintext - mmgr/protomem + mmgr + server/core/worker ) diff --git a/src/services/fieldbus/simatic/simatic.c b/src/services/fieldbus/simatic/simatic.c index ff147a0dd..929233da0 100644 --- a/src/services/fieldbus/simatic/simatic.c +++ b/src/services/fieldbus/simatic/simatic.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_SIMATIC -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "services/fieldbus/simatic/simatic.h" PROTOCORE_BEGIN_DECLS @@ -52,7 +52,7 @@ uint8_t *protocore_simatic_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_SIMATIC_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_SIMATIC_BORROW); } return s_own.span; } @@ -159,8 +159,8 @@ static_assert(SIMATIC_OFF_CTX + sizeof(SimaticCtx) <= PROTOCORE_SIMATIC_BORROW, "PROTOCORE_SIMATIC_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(SIMATIC_OFF_CTX % _Alignof(SimaticCtx) == 0, @@ -304,7 +304,7 @@ void protocore_simatic_init_3964r(uint8_t *work) Simatic3964RxFn rx = SimaticV.init_3964r_args.rx; void *user = SimaticV.init_3964r_args.user; - mem.set(ctx, 0, sizeof(*ctx)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = ctx, .val = 0, .bytes = sizeof(*ctx)); ctx->state = SIMATIC3964_STATE_IDLE; ctx->high_priority = high_priority; ctx->with_bcc = with_bcc; diff --git a/src/services/fieldbus/snp/CMakeLists.txt b/src/services/fieldbus/snp/CMakeLists.txt index 379a2ba30..b7752625c 100644 --- a/src/services/fieldbus/snp/CMakeLists.txt +++ b/src/services/fieldbus/snp/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/fieldbus/snp GATE PROTOCORE_ENABLE_SNP SOURCES snp.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/fieldbus/snp/snp.c b/src/services/fieldbus/snp/snp.c index 846cac6ec..cbcafa734 100644 --- a/src/services/fieldbus/snp/snp.c +++ b/src/services/fieldbus/snp/snp.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_SNP -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/fieldbus/snp/snp.h" PROTOCORE_BEGIN_DECLS @@ -63,7 +63,7 @@ void protocore_snp_build(uint8_t *work) out[1] = (uint8_t)data_len; if (data_len) { - mem.cpy(out + 2, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 2, .src = data, .bytes = data_len); } SnpV.bcc_args.bytes = out; SnpV.bcc_args.len = 2 + data_len; diff --git a/src/services/file_transfer/ftp/ftp/CMakeLists.txt b/src/services/file_transfer/ftp/ftp/CMakeLists.txt index 071eb6b41..d74dcba3e 100644 --- a/src/services/file_transfer/ftp/ftp/CMakeLists.txt +++ b/src/services/file_transfer/ftp/ftp/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/file_transfer/ftp/ftp GATE PROTOCORE_ENABLE_FTP SOURCES ftp.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/file_transfer/ftp/ftp/ftp.c b/src/services/file_transfer/ftp/ftp/ftp.c index d37570529..b003e301c 100644 --- a/src/services/file_transfer/ftp/ftp/ftp.c +++ b/src/services/file_transfer/ftp/ftp/ftp.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_FTP -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "services/file_transfer/ftp/ftp/ftp.h" PROTOCORE_BEGIN_DECLS @@ -31,7 +31,8 @@ static size_t protocore_ftp_emit(char *buf, size_t cap, size_t n, const char *s, } // The guard above proves n + slen <= cap, so this write stays inside buf[0, cap). S3519 can't link // buf's size to the separate cap parameter and follows an infeasible path (same FP as mms.cpp). - mem.cpy(buf + n, s, slen); // NOSONAR - bound proven above; analyzer follows an infeasible path + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + n, .src = s, + .bytes = slen); // NOSONAR - bound proven above; analyzer follows an infeasible path return n + slen; } @@ -97,11 +98,11 @@ void protocore_ftp_build_command(uint8_t *work) return; } size_t n = 0; - n = protocore_ftp_emit(buf, cap, n, verb, str.len(verb, cap)); + n = protocore_ftp_emit(buf, cap, n, verb, EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = verb, .cap = cap)); if (arg && arg[0]) { n = protocore_ftp_emit(buf, cap, n, " ", 1); - n = protocore_ftp_emit(buf, cap, n, arg, str.len(arg, cap)); + n = protocore_ftp_emit(buf, cap, n, arg, EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = arg, .cap = cap)); } n = protocore_ftp_emit(buf, cap, n, "\r\n", 2); FtpV.n = protocore_ftp_finish(buf, cap, n); @@ -152,7 +153,7 @@ void protocore_ftp_build_eprt(uint8_t *work) n = protocore_ftp_emit(buf, cap, n, "EPRT |", 6); n = protocore_ftp_emit(buf, cap, n, ipv6 ? "2" : "1", 1); n = protocore_ftp_emit(buf, cap, n, "|", 1); - n = protocore_ftp_emit(buf, cap, n, ip_str, str.len(ip_str, cap)); + n = protocore_ftp_emit(buf, cap, n, ip_str, EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = ip_str, .cap = cap)); n = protocore_ftp_emit(buf, cap, n, "|", 1); n = protocore_ftp_emit_uint(buf, cap, n, port); n = protocore_ftp_emit(buf, cap, n, "|\r\n", 3); diff --git a/src/services/file_transfer/http_delivery/CMakeLists.txt b/src/services/file_transfer/http_delivery/CMakeLists.txt index 1631ccacf..aa411e735 100644 --- a/src/services/file_transfer/http_delivery/CMakeLists.txt +++ b/src/services/file_transfer/http_delivery/CMakeLists.txt @@ -5,7 +5,7 @@ protocore_add_module(services/file_transfer/http_delivery GATE PROTOCORE_ENABLE_HTTP_DELIVERY SOURCES http_delivery.c PRIVATE_DEPS - mmgr/membuild + mmgr ) add_subdirectory(http_delivery_routes) diff --git a/src/services/file_transfer/http_delivery/http_delivery.c b/src/services/file_transfer/http_delivery/http_delivery.c index 217d07fb9..ec417111c 100644 --- a/src/services/file_transfer/http_delivery/http_delivery.c +++ b/src/services/file_transfer/http_delivery/http_delivery.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_HTTP_DELIVERY -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder #include "services/file_transfer/http_delivery/http_delivery.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -54,21 +54,22 @@ void protocore_http_delivery_cache_control(uint8_t *work) HttpDeliveryV.n = 0; return; } - protocore_sb b = {out, cap, 0, PROTO_TRUE}; - Sb.put(&b, "public, max-age="); - Sb.u32(&b, max_age_s); + size_t b = 0; + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "public, max-age="); + b = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = b, .val = max_age_s); if (swr_s) { - Sb.put(&b, ", stale-while-revalidate="); - Sb.u32(&b, swr_s); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, + .text = ", stale-while-revalidate="); + b = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = b, .val = swr_s); } - if (!b.ok) + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = b)) { HttpDeliveryV.n = 0; return; } - out[b.len] = '\0'; - HttpDeliveryV.n = b.len; + out[b] = '\0'; + HttpDeliveryV.n = b; } void protocore_http_delivery_sw_manifest(uint8_t *work) @@ -85,26 +86,27 @@ void protocore_http_delivery_sw_manifest(uint8_t *work) HttpDeliveryV.n = 0; return; } - protocore_sb b2 = {out, cap, 0, PROTO_TRUE}; - Sb.put(&b2, "{\"version\":"); - Sb.json(&b2, version ? version : ""); - Sb.put(&b2, ",\"precache\":["); + size_t b2 = 0; + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = "{\"version\":"); + b2 = + EMBED_CALL(verba_textus.json, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = version ? version : ""); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = ",\"precache\":["); for (size_t i = 0; i < n; i++) { if (i) { - Sb.put(&b2, ","); + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = ","); } - Sb.json(&b2, paths[i]); + b2 = EMBED_CALL(verba_textus.json, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = paths[i]); } - Sb.put(&b2, "]}"); - if (!b2.ok) + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, .text = "]}"); + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = b2)) { HttpDeliveryV.n = 0; return; } - out[b2.len] = '\0'; - HttpDeliveryV.n = b2.len; + out[b2] = '\0'; + HttpDeliveryV.n = b2; } // The route installer lives in http_delivery_routes.c, the arm that has an HTTP surface to install diff --git a/src/services/instrumentation/gpib/CMakeLists.txt b/src/services/instrumentation/gpib/CMakeLists.txt index fa1c16489..b9e0bf403 100644 --- a/src/services/instrumentation/gpib/CMakeLists.txt +++ b/src/services/instrumentation/gpib/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/instrumentation/gpib GATE PROTOCORE_ENABLE_GPIB SOURCES gpib.c PRIVATE_DEPS - mmgr/membuild - mmgr/protomem + mmgr ) diff --git a/src/services/instrumentation/gpib/gpib.c b/src/services/instrumentation/gpib/gpib.c index d2b76cdb7..8cc347d18 100644 --- a/src/services/instrumentation/gpib/gpib.c +++ b/src/services/instrumentation/gpib/gpib.c @@ -10,9 +10,9 @@ #if PROTOCORE_ENABLE_GPIB -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/instrumentation/gpib/gpib.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -22,11 +22,13 @@ size_t protocore_gpib_command(char *buf, size_t cap, const char *cmd) { return 0; } - protocore_sb sb_cmd = {buf, cap, 0, PROTO_TRUE}; - protocore_sb_lit(&sb_cmd, "++"); - Sb.put(&sb_cmd, cmd); - protocore_sb_lit(&sb_cmd, "\n"); - return Sb.finish(&sb_cmd); + size_t sb_cmd = 0; + sb_cmd = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_cmd, .text = "++", + .text_len = sizeof("++") - 1); + sb_cmd = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_cmd, .text = cmd); + sb_cmd = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_cmd, .text = "\n", + .text_len = sizeof("\n") - 1); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = buf, .cap = cap, .at = sb_cmd); } size_t protocore_gpib_addr(char *buf, size_t cap, uint8_t pad, int sad) @@ -35,16 +37,18 @@ size_t protocore_gpib_addr(char *buf, size_t cap, uint8_t pad, int sad) { return 0; } - protocore_sb sb_addr = {buf, cap, 0, PROTO_TRUE}; - protocore_sb_lit(&sb_addr, "++addr "); - Sb.u32(&sb_addr, pad); + size_t sb_addr = 0; + sb_addr = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_addr, .text = "++addr ", + .text_len = sizeof("++addr ") - 1); + sb_addr = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_addr, .val = pad); if (sad >= 0) { - Sb.ch(&sb_addr, ' '); - Sb.i64(&sb_addr, sad); + sb_addr = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = buf, .cap = cap, .at = sb_addr, .ch = ' '); + sb_addr = EMBED_CALL(verba_numerus.i64, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_addr, .sval = sad); } - protocore_sb_lit(&sb_addr, "\n"); - return Sb.finish(&sb_addr); + sb_addr = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_addr, .text = "\n", + .text_len = sizeof("\n") - 1); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = buf, .cap = cap, .at = sb_addr); } size_t protocore_gpib_read(char *buf, size_t cap, GpibRead mode, uint8_t ch) @@ -53,23 +57,27 @@ size_t protocore_gpib_read(char *buf, size_t cap, GpibRead mode, uint8_t ch) { return 0; } - protocore_sb sb_read = {buf, cap, 0, PROTO_TRUE}; + size_t sb_read = 0; switch (mode) { case UNTIL_EOI: - protocore_sb_lit(&sb_read, "++read eoi\n"); + sb_read = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_read, + .text = "++read eoi\n", .text_len = sizeof("++read eoi\n") - 1); break; case UNTIL_CHAR: - protocore_sb_lit(&sb_read, "++read "); - Sb.u32(&sb_read, ch); - protocore_sb_lit(&sb_read, "\n"); + sb_read = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_read, + .text = "++read ", .text_len = sizeof("++read ") - 1); + sb_read = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_read, .val = ch); + sb_read = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_read, .text = "\n", + .text_len = sizeof("\n") - 1); break; case UNTIL_TIMEOUT: default: - protocore_sb_lit(&sb_read, "++read\n"); + sb_read = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_read, + .text = "++read\n", .text_len = sizeof("++read\n") - 1); break; } - return Sb.finish(&sb_read); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = buf, .cap = cap, .at = sb_read); } size_t protocore_gpib_spoll(char *buf, size_t cap, int pad, int sad) @@ -78,20 +86,23 @@ size_t protocore_gpib_spoll(char *buf, size_t cap, int pad, int sad) { return 0; } - protocore_sb sb_spoll = {buf, cap, 0, PROTO_TRUE}; - protocore_sb_lit(&sb_spoll, "++spoll"); + size_t sb_spoll = 0; + sb_spoll = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_spoll, .text = "++spoll", + .text_len = sizeof("++spoll") - 1); if (pad >= 0) { - Sb.ch(&sb_spoll, ' '); - Sb.i64(&sb_spoll, pad); + sb_spoll = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = buf, .cap = cap, .at = sb_spoll, .ch = ' '); + sb_spoll = EMBED_CALL(verba_numerus.i64, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_spoll, .sval = pad); if (sad >= 0) { - Sb.ch(&sb_spoll, ' '); - Sb.i64(&sb_spoll, sad); + sb_spoll = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = buf, .cap = cap, .at = sb_spoll, .ch = ' '); + sb_spoll = + EMBED_CALL(verba_numerus.i64, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_spoll, .sval = sad); } } - protocore_sb_lit(&sb_spoll, "\n"); - return Sb.finish(&sb_spoll); + sb_spoll = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_spoll, .text = "\n", + .text_len = sizeof("\n") - 1); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = buf, .cap = cap, .at = sb_spoll); } size_t protocore_gpib_eos(char *buf, size_t cap, GpibEos eos) @@ -100,11 +111,14 @@ size_t protocore_gpib_eos(char *buf, size_t cap, GpibEos eos) { return 0; } - protocore_sb sb_eos = {buf, cap, 0, PROTO_TRUE}; - protocore_sb_lit(&sb_eos, "++eos "); - Sb.i64(&sb_eos, (int64_t)eos); // the wire field IS the enumerator's decimal value - protocore_sb_lit(&sb_eos, "\n"); - return Sb.finish(&sb_eos); + size_t sb_eos = 0; + sb_eos = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_eos, .text = "++eos ", + .text_len = sizeof("++eos ") - 1); + // the wire field IS the enumerator's decimal value + sb_eos = EMBED_CALL(verba_numerus.i64, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_eos, .sval = (int64_t)eos); + sb_eos = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_eos, .text = "\n", + .text_len = sizeof("\n") - 1); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = buf, .cap = cap, .at = sb_eos); } size_t protocore_gpib_build_data(uint8_t *buf, size_t cap, const uint8_t *src, size_t len) @@ -259,7 +273,7 @@ proto_bool protocore_gpib_parse_version(const char *s, size_t len, const char ** } for (size_t i = 0; i + klen <= len; i++) { - if (mem.cmp(s + i, key, klen) == 0) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = s + i, .other = key, .bytes = klen) == 0) { const char *v = s + i + klen; size_t vlen = len - i - klen; diff --git a/src/services/instrumentation/hislip/CMakeLists.txt b/src/services/instrumentation/hislip/CMakeLists.txt index 456ea2341..aa3f9ccb5 100644 --- a/src/services/instrumentation/hislip/CMakeLists.txt +++ b/src/services/instrumentation/hislip/CMakeLists.txt @@ -5,7 +5,5 @@ protocore_add_module(services/instrumentation/hislip GATE PROTOCORE_ENABLE_HISLIP SOURCES hislip.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/instrumentation/hislip/hislip.c b/src/services/instrumentation/hislip/hislip.c index e05eea31e..88626fda6 100644 --- a/src/services/instrumentation/hislip/hislip.c +++ b/src/services/instrumentation/hislip/hislip.c @@ -10,11 +10,11 @@ #if PROTOCORE_ENABLE_HISLIP -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "services/instrumentation/hislip/hislip.h" -#include "mmgr/endian/endian.h" +#include "endian/endian.h" PROTOCORE_BEGIN_DECLS @@ -29,8 +29,8 @@ size_t protocore_hislip_build_header(uint8_t *buf, size_t cap, HislipMsg type, u buf[1] = 'S'; buf[2] = (uint8_t)(type); buf[3] = control; - endian.wr32be(buf + 4, parameter); - endian.wr64be(buf + 8, payload_len); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 4, .val = parameter, .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 8, .val = payload_len, .width = MMGR_ENDIAN_64); return PROTOCORE_HISLIP_HEADER_LEN; } @@ -42,8 +42,8 @@ proto_bool protocore_hislip_parse_header(const uint8_t *buf, size_t len, HislipH } out->type = (HislipMsg)(buf[2]); out->control = buf[3]; - out->parameter = endian.rd32be(buf + 4); - out->payload_len = endian.rd64be(buf + 8); + out->parameter = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 4, .width = MMGR_ENDIAN_32); + out->payload_len = EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 8, .width = MMGR_ENDIAN_64); return PROTO_TRUE; } @@ -63,7 +63,8 @@ static size_t build_with_payload(uint8_t *buf, size_t cap, HislipMsg type, uint8 protocore_hislip_build_header(buf, cap, type, control, parameter, payload_len); if (payload_len) { - mem.cpy(buf + PROTOCORE_HISLIP_HEADER_LEN, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + PROTOCORE_HISLIP_HEADER_LEN, .src = payload, + .bytes = payload_len); } return total; } @@ -71,7 +72,7 @@ static size_t build_with_payload(uint8_t *buf, size_t cap, HislipMsg type, uint8 size_t protocore_hislip_build_initialize(uint8_t *buf, size_t cap, uint16_t protocol_version, uint16_t vendor_id, const char *sub_address) { - size_t sub_len = sub_address ? str.len(sub_address, cap) : 0; + size_t sub_len = sub_address ? EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = sub_address, .cap = cap) : 0; uint32_t parameter = ((uint32_t)protocol_version << 16) | vendor_id; return build_with_payload(buf, cap, HISLIP_MSG_INITIALIZE, 0, parameter, (const uint8_t *)sub_address, sub_len); } diff --git a/src/services/instrumentation/scpi/CMakeLists.txt b/src/services/instrumentation/scpi/CMakeLists.txt index 64a96155d..5467d156b 100644 --- a/src/services/instrumentation/scpi/CMakeLists.txt +++ b/src/services/instrumentation/scpi/CMakeLists.txt @@ -5,7 +5,5 @@ protocore_add_module(services/instrumentation/scpi GATE PROTOCORE_ENABLE_SCPI SOURCES scpi.c PRIVATE_DEPS - mmgr/protoframe - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/instrumentation/scpi/scpi.c b/src/services/instrumentation/scpi/scpi.c index 656270bf3..ff09889b6 100644 --- a/src/services/instrumentation/scpi/scpi.c +++ b/src/services/instrumentation/scpi/scpi.c @@ -10,15 +10,15 @@ #if PROTOCORE_ENABLE_SCPI -#include "mmgr/protoframe/protoframe.h" // the one frame engine -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" +#include "numeros_scribo/numeros_scribo.h" // the one frame engine #include "services/instrumentation/scpi/scpi.h" PROTOCORE_BEGIN_DECLS // A response value is one number. 10 significant digits is the SCPI NR2/NR3 rendering. -static const protocore_field SCPI_REAL[] = {{PROTOCORE_FK_G, 10, 0, NULL}, PROTOCORE_END}; +static const mmgr_field SCPI_REAL[] = {{MMGR_FK_G, 10, 0, NULL}, MMGR_END}; // ── small helpers ────────────────────────────────────────────────────────────────────────────── @@ -98,14 +98,14 @@ size_t protocore_scpi_build(char *buf, size_t cap, const char *header, const cha { return 0; } - size_t hlen = str.len(header, cap); + size_t hlen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = header, .cap = cap); if (hlen == 0 || hlen >= cap) { return 0; } size_t p = 0; - mem.cpy(buf, header, hlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf, .src = header, .bytes = hlen); p = hlen; for (size_t i = 0; i < argc; i++) { @@ -114,13 +114,13 @@ size_t protocore_scpi_build(char *buf, size_t cap, const char *header, const cha return 0; } char sep = (i == 0) ? ' ' : ','; - size_t alen = str.len(args[i], cap); + size_t alen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = args[i], .cap = cap); if (p + 1 + alen + 1 >= cap) // sep + arg + the trailing '\n' + NUL { return 0; } buf[p++] = sep; - mem.cpy(buf + p, args[i], alen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = args[i], .bytes = alen); p += alen; } if (p + 1 >= cap) // room for '\n' + NUL @@ -140,7 +140,8 @@ size_t protocore_scpi_fmt_real(char *buf, size_t cap, double v) } // %g renders NR2 (fixed) or NR3 (scientific) and trims trailing zeros - exactly the SCPI forms. // The frame's own contract is this function's contract: bytes written, or 0 with buf emptied. - return frame.build(buf, cap, SCPI_REAL, (const protocore_fval[]){PROTOCORE_VG(v)}, 1); + return EMBED_CALL(numer.build, NumerosCfg, .out = buf, .cap = cap, .spec = SCPI_REAL, + .vals = (const mmgr_fval[]){MMGR_VG(v)}, .nvals = 1); } // ── response parsers ─────────────────────────────────────────────────────────────────────────── @@ -441,7 +442,7 @@ void protocore_scpi_status_init(ScpiStatus *s) { return; } - mem.set(s, 0, sizeof(*s)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = s, .val = 0, .bytes = sizeof(*s)); } void protocore_scpi_event(ScpiStatus *s, uint8_t esr_bits) @@ -653,7 +654,7 @@ proto_bool protocore_scpi_match(const char *input, size_t input_len, const char // common command: match the whole token case-insensitively if (pattern[0] == '*') { - return ieq(ip, irem, pattern, str.len(pattern, 64)); + return ieq(ip, irem, pattern, EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = pattern, .cap = 64)); } // a leading ':' on the input is an absolute-root anchor - skip it @@ -663,7 +664,7 @@ proto_bool protocore_scpi_match(const char *input, size_t input_len, const char irem--; } - size_t prem = str.len(pattern, 256); + size_t prem = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = pattern, .cap = 256); const char *pp = pattern; // reconcile the query '?' suffix: both must have it or neither diff --git a/src/services/instrumentation/vxi11/CMakeLists.txt b/src/services/instrumentation/vxi11/CMakeLists.txt index 58c8e3999..8bdca5e85 100644 --- a/src/services/instrumentation/vxi11/CMakeLists.txt +++ b/src/services/instrumentation/vxi11/CMakeLists.txt @@ -5,7 +5,5 @@ protocore_add_module(services/instrumentation/vxi11 GATE PROTOCORE_ENABLE_VXI11 SOURCES vxi11.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/instrumentation/vxi11/vxi11.c b/src/services/instrumentation/vxi11/vxi11.c index 053045cdd..202ebd63c 100644 --- a/src/services/instrumentation/vxi11/vxi11.c +++ b/src/services/instrumentation/vxi11/vxi11.c @@ -10,11 +10,11 @@ #if PROTOCORE_ENABLE_VXI11 -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "services/instrumentation/vxi11/vxi11.h" -#include "mmgr/endian/endian.h" +#include "endian/endian.h" PROTOCORE_BEGIN_DECLS @@ -38,7 +38,7 @@ static void xw_u32(XdrW *w, uint32_t v) w->ok = PROTO_FALSE; return; } - endian.wr32be(w->p + w->off, v); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = w->p + w->off, .val = v, .width = MMGR_ENDIAN_32); w->off += 4; } @@ -51,11 +51,11 @@ static void xw_bytes(XdrW *w, const uint8_t *d, size_t n) w->ok = PROTO_FALSE; return; } - endian.wr32be(w->p + w->off, (uint32_t)n); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = w->p + w->off, .val = (uint32_t)n, .width = MMGR_ENDIAN_32); w->off += 4; if (n) { - mem.cpy(w->p + w->off, d, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = w->p + w->off, .src = d, .bytes = n); w->off += n; } for (size_t i = 0; i < pad; i++) @@ -79,7 +79,7 @@ static uint32_t xr_u32(XdrR *r) r->ok = PROTO_FALSE; return 0; } - uint32_t v = endian.rd32be(r->p + r->off); + uint32_t v = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = r->p + r->off, .width = MMGR_ENDIAN_32); r->off += 4; return v; } @@ -118,7 +118,8 @@ size_t protocore_rpc_record_mark(uint8_t *buf, size_t cap, uint32_t payload_len) { return 0; } - endian.wr32be(buf, 0x80000000u | payload_len); // last-fragment flag set + // last-fragment flag set + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf, .val = 0x80000000u | payload_len, .width = MMGR_ENDIAN_32); return 4; } @@ -128,7 +129,7 @@ proto_bool protocore_rpc_parse_record_mark(const uint8_t *buf, size_t len, proto { return PROTO_FALSE; } - uint32_t rm = endian.rd32be(buf); + uint32_t rm = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf, .width = MMGR_ENDIAN_32); if (last) { *last = (rm & 0x80000000u) != 0; @@ -259,7 +260,7 @@ size_t protocore_vxi11_build_create_link(uint8_t *buf, size_t cap, uint32_t xid, xw_u32(&w, (uint32_t)client_id); xw_u32(&w, lock_device ? 1 : 0); xw_u32(&w, lock_timeout); - size_t dlen = device ? str.len(device, cap) : 0; + size_t dlen = device ? EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = device, .cap = cap) : 0; xw_bytes(&w, (const uint8_t *)device, dlen); return finish_call(&w); } diff --git a/src/services/iot/amqp/CMakeLists.txt b/src/services/iot/amqp/CMakeLists.txt index ea695eae7..1e99391dc 100644 --- a/src/services/iot/amqp/CMakeLists.txt +++ b/src/services/iot/amqp/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/iot/amqp GATE PROTOCORE_ENABLE_AMQP SOURCES amqp.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/services/iot/amqp/amqp.c b/src/services/iot/amqp/amqp.c index ef7cc7a48..fc84517e9 100644 --- a/src/services/iot/amqp/amqp.c +++ b/src/services/iot/amqp/amqp.c @@ -16,8 +16,8 @@ #include "services/iot/amqp/amqp.h" -#include "mmgr/endian/endian.h" // endian.wr16be / rd32be: the network byte order of sec 4.2.5.1 -#include "mmgr/protomem/protomem.h" // mem.cpy: the payload spans a frame carries +#include "endian/endian.h" // magna_extremitas.wr / rd32be: the network byte order of sec 4.2.5.1 +#include "memoria_operor/memoria_operor.h" // memor.cpy: the payload spans a frame carries PROTOCORE_BEGIN_DECLS @@ -26,8 +26,8 @@ static size_t write_frame_header(uint8_t *buf, uint8_t type, uint16_t channel, u { size_t p = 0; buf[p++] = type; - p += endian.wr16be(buf + p, channel); - p += endian.wr32be(buf + p, size); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = channel, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = size, .width = MMGR_ENDIAN_32); return p; } @@ -42,7 +42,7 @@ void protocore_amqp_protocol_header(uint8_t *work) { return; } - mem.cpy(AmqpV.out.buf, hdr, sizeof(hdr)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = AmqpV.out.buf, .src = hdr, .bytes = sizeof(hdr)); AmqpV.n = sizeof(hdr); AmqpV.ok = PROTO_TRUE; } @@ -68,7 +68,7 @@ void protocore_amqp_build_frame(uint8_t *work) size_t p = write_frame_header(buf, AmqpV.frame.type, AmqpV.frame.channel, (uint32_t)payload_len); if (payload_len) { - mem.cpy(buf + p, AmqpV.payload.data, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = AmqpV.payload.data, .bytes = payload_len); p += payload_len; } buf[p++] = AMQP_FRAME_END; @@ -96,11 +96,13 @@ void protocore_amqp_build_method(uint8_t *work) return; } size_t p = write_frame_header(buf, AMQP_FRAME_METHOD, AmqpV.frame.channel, (uint32_t)payload_len); - p += endian.wr16be(buf + p, AmqpV.method.class_id); - p += endian.wr16be(buf + p, AmqpV.method.method_id); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = AmqpV.method.class_id, + .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = AmqpV.method.method_id, + .width = MMGR_ENDIAN_16); if (args_len) { - mem.cpy(buf + p, AmqpV.method.args, args_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = AmqpV.method.args, .bytes = args_len); p += args_len; } buf[p++] = AMQP_FRAME_END; @@ -128,13 +130,16 @@ void protocore_amqp_build_content_header(uint8_t *work) return; } size_t p = write_frame_header(buf, AMQP_FRAME_HEADER, AmqpV.frame.channel, (uint32_t)payload_len); - p += endian.wr16be(buf + p, AmqpV.content.class_id); - p += endian.wr16be(buf + p, 0); - p += endian.wr64be(buf + p, AmqpV.content.body_size); - p += endian.wr16be(buf + p, AmqpV.content.property_flags); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = AmqpV.content.class_id, + .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = 0, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = AmqpV.content.body_size, + .width = MMGR_ENDIAN_64); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = AmqpV.content.property_flags, + .width = MMGR_ENDIAN_16); if (list_len) { - mem.cpy(buf + p, AmqpV.content.property_list, list_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = AmqpV.content.property_list, .bytes = list_len); p += list_len; } buf[p++] = AMQP_FRAME_END; @@ -172,7 +177,7 @@ void protocore_amqp_parse_frame(uint8_t *work) { return; } - uint32_t size = endian.rd32be(buf + 3); + uint32_t size = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 3, .width = MMGR_ENDIAN_32); // Compared against the remaining capacity without adding, so a 32-bit size_t cannot wrap // computing 8 + size and let a peer-controlled size past the bound. if (size > len - AMQP_FRAME_OVERHEAD) @@ -184,7 +189,7 @@ void protocore_amqp_parse_frame(uint8_t *work) return; // missing or corrupt frame-end } AmqpV.frame.type = buf[0]; - AmqpV.frame.channel = endian.rd16be(buf + 1); + AmqpV.frame.channel = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 1, .width = MMGR_ENDIAN_16); AmqpV.payload.data = buf + 7; AmqpV.payload.len = size; AmqpV.consumed = AMQP_FRAME_OVERHEAD + (size_t)size; @@ -202,8 +207,10 @@ void protocore_amqp_parse_method(uint8_t *work) { return; } - AmqpV.method.class_id = endian.rd16be(payload); - AmqpV.method.method_id = endian.rd16be(payload + 2); + AmqpV.method.class_id = + (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = payload, .width = MMGR_ENDIAN_16); + AmqpV.method.method_id = + (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = payload + 2, .width = MMGR_ENDIAN_16); AmqpV.method.args = payload + 4; AmqpV.method.args_len = payload_len - 4; AmqpV.ok = PROTO_TRUE; diff --git a/src/services/iot/dds/CMakeLists.txt b/src/services/iot/dds/CMakeLists.txt index 99d5b6f0f..374357f91 100644 --- a/src/services/iot/dds/CMakeLists.txt +++ b/src/services/iot/dds/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/iot/dds GATE PROTOCORE_ENABLE_DDS SOURCES dds.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/iot/dds/dds.c b/src/services/iot/dds/dds.c index 3f2602a2a..e7615745f 100644 --- a/src/services/iot/dds/dds.c +++ b/src/services/iot/dds/dds.c @@ -16,7 +16,7 @@ #include "services/iot/dds/dds.h" -#include "mmgr/protomem/protomem.h" // mem.cpy: the guidPrefix and the Submessage contents +#include "memoria_operor/memoria_operor.h" // memor.cpy: the guidPrefix and the Submessage contents PROTOCORE_BEGIN_DECLS @@ -44,7 +44,7 @@ void protocore_rtps_header(uint8_t *work) out[5] = RTPS_VERSION[1]; out[6] = RtpsV.hdr.vendor_id[0]; out[7] = RtpsV.hdr.vendor_id[1]; - mem.cpy(out + 8, RtpsV.hdr.guid_prefix, RTPS_GUIDPREFIX_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 8, .src = RtpsV.hdr.guid_prefix, .bytes = RTPS_GUIDPREFIX_LEN); RtpsV.n = RTPS_HEADER_LEN; } @@ -80,7 +80,8 @@ void protocore_rtps_submessage(uint8_t *work) } if (contents_len) { - mem.cpy(out + RTPS_SUBMESSAGE_HEADER_LEN, RtpsV.sub.contents, contents_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + RTPS_SUBMESSAGE_HEADER_LEN, .src = RtpsV.sub.contents, + .bytes = contents_len); } RtpsV.n = total; } diff --git a/src/services/iot/graphql/CMakeLists.txt b/src/services/iot/graphql/CMakeLists.txt index 2ad5050c2..18e0031c7 100644 --- a/src/services/iot/graphql/CMakeLists.txt +++ b/src/services/iot/graphql/CMakeLists.txt @@ -5,8 +5,6 @@ protocore_add_module(services/iot/graphql GATE PROTOCORE_ENABLE_GRAPHQL SOURCES graphql.c PRIVATE_DEPS - mmgr/membuild - mmgr/plaintext - mmgr/protomem - mmgr/protostr + mmgr + server/core/worker ) diff --git a/src/services/iot/graphql/graphql.c b/src/services/iot/graphql/graphql.c index 47f73f0a0..f5c92ebb9 100644 --- a/src/services/iot/graphql/graphql.c +++ b/src/services/iot/graphql/graphql.c @@ -19,12 +19,12 @@ #if PROTOCORE_ENABLE_GRAPHQL -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "services/iot/graphql/graphql.h" -#include "mmgr/membuild/membuild.h" // Sb: the Int, Float and \uXXXX renderings -#include "mmgr/protomem/protomem.h" // mem.cpy: the spans a name and a decoded String move with -#include "mmgr/protostr/protostr.h" // str.eq / str.len: the bounded compares and measures +#include "cellularum_laboro/cellularum_laboro.h" // cellul.eq / cellul.len: the bounded compares and measures +#include "memoria_operor/memoria_operor.h" // memor.cpy: the spans a name and a decoded String move with +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -234,7 +234,7 @@ static const char *intern(uint8_t *work, const char *s, int len) return NULL; } char *dst = doc->strings + doc->str_len; - mem.cpy(dst, s, (size_t)len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = dst, .src = s, .bytes = (size_t)len); dst[len] = '\0'; doc->str_len += len + 1; return dst; @@ -392,19 +392,22 @@ static proto_bool parse_value(uint8_t *work, GqlLexer *lx, protocore_gql_value * char kw[8]; if (parse_name(work, lx, kw, sizeof(kw))) { - if (str.eq(kw, "true", sizeof("true"), PROTO_FALSE)) + if (EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = kw, .other = "true", .cap = sizeof("true"), + .ci = PROTO_FALSE)) { v->type = PROTOCORE_GQL_BOOL; v->b = PROTO_TRUE; return PROTO_TRUE; } - if (str.eq(kw, "false", sizeof("false"), PROTO_FALSE)) + if (EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = kw, .other = "false", .cap = sizeof("false"), + .ci = PROTO_FALSE)) { v->type = PROTOCORE_GQL_BOOL; v->b = PROTO_FALSE; return PROTO_TRUE; } - if (str.eq(kw, "null", sizeof("null"), PROTO_FALSE)) + if (EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = kw, .other = "null", .cap = sizeof("null"), + .ci = PROTO_FALSE)) { v->type = PROTOCORE_GQL_NULL; return PROTO_TRUE; @@ -531,7 +534,9 @@ static proto_bool parse_document(uint8_t *work, GqlLexer *lx) if (c != '{') { char kw[PROTOCORE_GQL_NAME_MAX]; - if (!parse_name(work, lx, kw, sizeof(kw)) || !str.eq(kw, "query", sizeof("query"), PROTO_FALSE)) + if (!parse_name(work, lx, kw, sizeof(kw)) || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = kw, .other = "query", .cap = sizeof("query"), + .ci = PROTO_FALSE)) { doc->err = PROTOCORE_GQL_ERR_PARSE; // only the query OperationType return PROTO_FALSE; @@ -572,13 +577,13 @@ static void w_raw(GqlWriter *w, const char *s, size_t len) w->ovf = PROTO_TRUE; return; } - mem.cpy(w->o + w->n, s, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = w->o + w->n, .src = s, .bytes = len); w->n += len; } static void w_str(GqlWriter *w, const char *s) { - w_raw(w, s, str.len(s, w->cap + 1)); + w_raw(w, s, EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = w->cap + 1)); } // Append @p s as a JSON string: quoted, with `"` and `\` escaped, the named escapes for the three @@ -612,10 +617,11 @@ static void w_json_str(GqlWriter *w, const char *s) else if (ch < 0x20) { char u[7]; - protocore_sb sb_u = {u, sizeof(u), 0, PROTO_TRUE}; - Sb.put(&sb_u, "\\u"); - Sb.hex(&sb_u, (uint64_t)(ch), 4); - if (Sb.finish(&sb_u) == 0) + size_t sb_u = 0; + sb_u = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = u, .cap = sizeof(u), .at = sb_u, .text = "\\u"); + sb_u = EMBED_CALL(verba_numerus.hex, VerbaNumerusCfg, .out = u, .cap = sizeof(u), .at = sb_u, + .val = (uint64_t)(ch), .min = 4); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = u, .cap = sizeof(u), .at = sb_u) == 0) { u[0] = '\0'; } @@ -637,9 +643,10 @@ static void w_scalar(GqlWriter *w, const protocore_gql_value *v) switch (v->type) { case PROTOCORE_GQL_INT: { - protocore_sb sb_b = {b, sizeof(b), 0, PROTO_TRUE}; - Sb.i64(&sb_b, (int64_t)(v->i)); - if (Sb.finish(&sb_b) == 0) + size_t sb_b = 0; + sb_b = EMBED_CALL(verba_numerus.i64, VerbaNumerusCfg, .out = b, .cap = sizeof(b), .at = sb_b, + .sval = (int64_t)(v->i)); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = b, .cap = sizeof(b), .at = sb_b) == 0) { b[0] = '\0'; } @@ -647,9 +654,10 @@ static void w_scalar(GqlWriter *w, const protocore_gql_value *v) w_str(w, b); break; case PROTOCORE_GQL_FLOAT: { - protocore_sb sb_b2 = {b, sizeof(b), 0, PROTO_TRUE}; - Sb.g(&sb_b2, (double)(v->f), 6); - if (Sb.finish(&sb_b2) == 0) + size_t sb_b2 = 0; + sb_b2 = EMBED_CALL(verba_fractio.g, VerbaFractioCfg, .out = b, .cap = sizeof(b), .at = sb_b2, + .real = (double)(v->f), .sig = 6); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = b, .cap = sizeof(b), .at = sb_b2) == 0) { b[0] = '\0'; } @@ -691,13 +699,13 @@ static void execute_field(uint8_t *work, GqlWriter *w, int idx, int path_len) } ex->path[plen++] = '.'; } - int nl = (int)str.len(field->name, sizeof(field->name)); + int nl = (int)EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = field->name, .cap = sizeof(field->name)); if (plen + nl >= PROTOCORE_GQL_PATH_MAX) { w->ovf = PROTO_TRUE; return; } - mem.cpy(ex->path + plen, field->name, (size_t)nl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = ex->path + plen, .src = field->name, .bytes = (size_t)nl); plen += nl; ex->path[plen] = '\0'; @@ -774,7 +782,8 @@ static const GqlArgument *arg_lookup(uint8_t *work) for (int k = 0; k < view->count; k++) { const GqlArgument *a = &GRAPHQL_CTX(work)->doc.args[view->idx[k]]; - if (str.eq(a->name, GraphQLV.argument.name, sizeof(a->name), PROTO_FALSE)) + if (EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = a->name, .other = GraphQLV.argument.name, + .cap = sizeof(a->name), .ci = PROTO_FALSE)) { return a; } @@ -797,7 +806,7 @@ uint8_t *protocore_graphql_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_GRAPHQL_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_GRAPHQL_BORROW); } return s_own.span; } diff --git a/src/services/iot/grpcweb/CMakeLists.txt b/src/services/iot/grpcweb/CMakeLists.txt index 7d6215fcf..bb65d5695 100644 --- a/src/services/iot/grpcweb/CMakeLists.txt +++ b/src/services/iot/grpcweb/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/iot/grpcweb GATE PROTOCORE_ENABLE_GRPC_WEB SOURCES grpcweb.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/iot/grpcweb/grpcweb.c b/src/services/iot/grpcweb/grpcweb.c index 97608b121..52314ebec 100644 --- a/src/services/iot/grpcweb/grpcweb.c +++ b/src/services/iot/grpcweb/grpcweb.c @@ -19,8 +19,8 @@ #include "services/iot/grpcweb/grpcweb.h" -#include "mmgr/protomem/protomem.h" // mem.cpy / mem.cmp: the spans a frame is assembled from and matched on -#include "mmgr/protostr/protostr.h" // str.len: the bounded length of a field-line's text +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len: the bounded length of a field-line's text +#include "memoria_operor/memoria_operor.h" // memor.cpy / memor.cmp: the spans a frame is assembled from and matched on PROTOCORE_BEGIN_DECLS @@ -43,12 +43,12 @@ static uint32_t get_be32(const uint8_t *buf) // is read no further than cap, and *pos is past the prefix, so a longer string fails the test. static proto_bool put_str(uint8_t *buf, size_t cap, size_t *pos, const char *s) { - const size_t n = str.len(s, cap); + const size_t n = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = cap); if (*pos + n > cap) { return PROTO_FALSE; } - mem.cpy(buf + *pos, s, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + *pos, .src = s, .bytes = n); *pos += n; return PROTO_TRUE; } @@ -88,7 +88,8 @@ static proto_bool find_key(const uint8_t *body, size_t len, const char *key, siz { for (size_t i = 0; i + klen <= len; i++) { - if ((i == 0 || body[i - 1] == '\n') && mem.cmp(body + i, key, klen) == 0) + if ((i == 0 || body[i - 1] == '\n') && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = body + i, .other = key, .bytes = klen) == 0) { *value_at = i + klen; return PROTO_TRUE; @@ -119,7 +120,8 @@ void protocore_grpc_web_frame(uint8_t *work) put_be32(buf + 1, (uint32_t)body_len); if (body_len) { - mem.cpy(buf + PROTOCORE_GRPCWEB_PREFIX_LEN, GrpcWebV.msg.body, body_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + PROTOCORE_GRPCWEB_PREFIX_LEN, .src = GrpcWebV.msg.body, + .bytes = body_len); } GrpcWebV.n = total; GrpcWebV.ok = PROTO_TRUE; diff --git a/src/services/iot/lwm2m/lwm2m_tlv/CMakeLists.txt b/src/services/iot/lwm2m/lwm2m_tlv/CMakeLists.txt index 02d97738b..6b5b20750 100644 --- a/src/services/iot/lwm2m/lwm2m_tlv/CMakeLists.txt +++ b/src/services/iot/lwm2m/lwm2m_tlv/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(services/iot/lwm2m/lwm2m_tlv GATE PROTOCORE_ENABLE_LWM2M SOURCES lwm2m_tlv.c PRIVATE_DEPS - mmgr/plaintext - mmgr/protomem - mmgr/protostr + mmgr + server/core/worker ) diff --git a/src/services/iot/lwm2m/lwm2m_tlv/lwm2m_tlv.c b/src/services/iot/lwm2m/lwm2m_tlv/lwm2m_tlv.c index f48e72fd5..b7b31cfbb 100644 --- a/src/services/iot/lwm2m/lwm2m_tlv/lwm2m_tlv.c +++ b/src/services/iot/lwm2m/lwm2m_tlv/lwm2m_tlv.c @@ -14,11 +14,11 @@ #if PROTOCORE_ENABLE_LWM2M -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "services/iot/lwm2m/lwm2m_tlv/lwm2m_tlv.h" -#include "mmgr/protomem/protomem.h" // mem.cpy: the Value octets a write copies, and the Float bit pattern -#include "mmgr/protostr/protostr.h" // str.len: the bounded String measure +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len: the bounded String measure +#include "memoria_operor/memoria_operor.h" // memor.cpy: the Value octets a write copies, and the Float bit pattern PROTOCORE_BEGIN_DECLS @@ -105,7 +105,7 @@ uint8_t *protocore_lwm2m_tlv_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_LWM2M_TLV_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_LWM2M_TLV_BORROW); } return s_own.span; } @@ -184,7 +184,7 @@ void protocore_lwm2m_tlv_write(uint8_t *work) w->pos += lenbytes; if (value_len) { - mem.cpy(w->buf + w->pos, value, value_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = w->buf + w->pos, .src = value, .bytes = value_len); w->pos += value_len; } Lwm2mTlvV.ok = PROTO_TRUE; @@ -219,7 +219,8 @@ void protocore_lwm2m_tlv_write_string(uint8_t *work) return; } Lwm2mTlvV.val.opaque = (const uint8_t *)Lwm2mTlvV.val.string_value; - Lwm2mTlvV.val.len = str.len(Lwm2mTlvV.val.string_value, LWM2M_TLV_CTX(work)->w.cap); + Lwm2mTlvV.val.len = + EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = Lwm2mTlvV.val.string_value, .cap = LWM2M_TLV_CTX(work)->w.cap); protocore_lwm2m_tlv_write(work); } @@ -228,7 +229,7 @@ void protocore_lwm2m_tlv_write_float(uint8_t *work) { uint64_t bits; double v = Lwm2mTlvV.val.float_value; - mem.cpy(&bits, &v, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &bits, .src = &v, .bytes = 8); store_be(LWM2M_TLV_CTX(work)->w.scalar, bits, 8); Lwm2mTlvV.val.opaque = LWM2M_TLV_CTX(work)->w.scalar; Lwm2mTlvV.val.len = 8; diff --git a/src/services/iot/mqtt/mqtt_sn/CMakeLists.txt b/src/services/iot/mqtt/mqtt_sn/CMakeLists.txt index 7e474ec1b..c237a4e08 100644 --- a/src/services/iot/mqtt/mqtt_sn/CMakeLists.txt +++ b/src/services/iot/mqtt/mqtt_sn/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/iot/mqtt/mqtt_sn GATE PROTOCORE_ENABLE_MQTT_SN SOURCES mqtt_sn.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/iot/mqtt/mqtt_sn/mqtt_sn.c b/src/services/iot/mqtt/mqtt_sn/mqtt_sn.c index 681504e94..e85eb2a12 100644 --- a/src/services/iot/mqtt/mqtt_sn/mqtt_sn.c +++ b/src/services/iot/mqtt/mqtt_sn/mqtt_sn.c @@ -16,8 +16,8 @@ #include "services/iot/mqtt/mqtt_sn/mqtt_sn.h" -#include "mmgr/protomem/protomem.h" // mem.cpy: the ClientId, TopicName and Data spans -#include "mmgr/protostr/protostr.h" // str.len: their bounded lengths +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len: their bounded lengths +#include "memoria_operor/memoria_operor.h" // memor.cpy: the ClientId, TopicName and Data spans // --------------------------------------------------------------------------- // Literals @@ -138,7 +138,7 @@ void protocore_mqttsn_build_connect(uint8_t *work) { return; } - size_t idlen = str.len(MqttsnV.field.client_id, cap); + size_t idlen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = MqttsnV.field.client_id, .cap = cap); size_t total = 0; size_t p = frame_header(buf, cap, MQTTSN_CONNECT, 1 + 1 + MQTTSN_ID_OCTETS + idlen, &total); if (!p) @@ -149,7 +149,7 @@ void protocore_mqttsn_build_connect(uint8_t *work) buf[p++] = MQTTSN_PROTOCOL_ID; wr16(buf + p, MqttsnV.field.duration); p += MQTTSN_ID_OCTETS; - mem.cpy(buf + p, MqttsnV.field.client_id, idlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = MqttsnV.field.client_id, .bytes = idlen); MqttsnV.n = total; MqttsnV.ok = PROTO_TRUE; } @@ -166,7 +166,7 @@ void protocore_mqttsn_build_register(uint8_t *work) { return; } - size_t nlen = str.len(MqttsnV.topic.topic_name, cap); + size_t nlen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = MqttsnV.topic.topic_name, .cap = cap); size_t total = 0; size_t p = frame_header(buf, cap, MQTTSN_REGISTER, MQTTSN_ID_OCTETS + MQTTSN_ID_OCTETS + nlen, &total); if (!p) @@ -177,7 +177,7 @@ void protocore_mqttsn_build_register(uint8_t *work) p += MQTTSN_ID_OCTETS; wr16(buf + p, MqttsnV.field.msg_id); p += MQTTSN_ID_OCTETS; - mem.cpy(buf + p, MqttsnV.topic.topic_name, nlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = MqttsnV.topic.topic_name, .bytes = nlen); MqttsnV.n = total; MqttsnV.ok = PROTO_TRUE; } @@ -234,7 +234,7 @@ void protocore_mqttsn_build_publish(uint8_t *work) p += MQTTSN_ID_OCTETS; if (data_len) { - mem.cpy(buf + p, MqttsnV.data.data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = MqttsnV.data.data, .bytes = data_len); } MqttsnV.n = total; MqttsnV.ok = PROTO_TRUE; @@ -278,7 +278,7 @@ void protocore_mqttsn_build_subscribe_name(uint8_t *work) { return; } - size_t nlen = str.len(MqttsnV.topic.topic_name, cap); + size_t nlen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = MqttsnV.topic.topic_name, .cap = cap); size_t total = 0; size_t p = frame_header(buf, cap, MQTTSN_SUBSCRIBE, 1 + MQTTSN_ID_OCTETS + nlen, &total); if (!p) @@ -288,7 +288,7 @@ void protocore_mqttsn_build_subscribe_name(uint8_t *work) buf[p++] = MqttsnV.flags.octet; wr16(buf + p, MqttsnV.field.msg_id); p += MQTTSN_ID_OCTETS; - mem.cpy(buf + p, MqttsnV.topic.topic_name, nlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = MqttsnV.topic.topic_name, .bytes = nlen); MqttsnV.n = total; MqttsnV.ok = PROTO_TRUE; } @@ -330,7 +330,9 @@ void protocore_mqttsn_build_pingreq(uint8_t *work) { return; } - size_t idlen = MqttsnV.field.client_id ? str.len(MqttsnV.field.client_id, cap) : 0; + size_t idlen = MqttsnV.field.client_id + ? EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = MqttsnV.field.client_id, .cap = cap) + : 0; size_t total = 0; size_t p = frame_header(buf, cap, MQTTSN_PINGREQ, idlen, &total); if (!p) @@ -339,7 +341,7 @@ void protocore_mqttsn_build_pingreq(uint8_t *work) } if (idlen) { - mem.cpy(buf + p, MqttsnV.field.client_id, idlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = MqttsnV.field.client_id, .bytes = idlen); } MqttsnV.n = total; MqttsnV.ok = PROTO_TRUE; diff --git a/src/services/iot/nats/CMakeLists.txt b/src/services/iot/nats/CMakeLists.txt index 61e273ba2..8699cc6e0 100644 --- a/src/services/iot/nats/CMakeLists.txt +++ b/src/services/iot/nats/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/iot/nats GATE PROTOCORE_ENABLE_NATS SOURCES nats.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/iot/nats/nats.c b/src/services/iot/nats/nats.c index 7dfb84384..a0a1f3cb2 100644 --- a/src/services/iot/nats/nats.c +++ b/src/services/iot/nats/nats.c @@ -17,8 +17,8 @@ #include "services/iot/nats/nats.h" -#include "mmgr/protomem/protomem.h" // mem.cpy / mem.cmp: the spans an operation is laid from and matched against -#include "mmgr/protostr/protostr.h" // str.len: the bounded length of a caller's NUL-terminated field +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len: the bounded length of a caller's NUL-terminated field +#include "memoria_operor/memoria_operor.h" // memor.cpy / memor.cmp: the spans an operation is laid from and matched against PROTOCORE_BEGIN_DECLS @@ -61,13 +61,13 @@ static void put_str(Buf *b, const char *s) { return; } - size_t n = str.len(s, b->cap + 1); + size_t n = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = b->cap + 1); if (b->pos + n > b->cap) { b->ok = PROTO_FALSE; return; } - mem.cpy(b->p + b->pos, s, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = b->p + b->pos, .src = s, .bytes = n); b->pos += n; } @@ -85,7 +85,7 @@ static void put_bytes(Buf *b, const uint8_t *d, size_t n) } if (n) { - mem.cpy(b->p + b->pos, d, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = b->p + b->pos, .src = d, .bytes = n); } b->pos += n; } @@ -325,12 +325,12 @@ static proto_bool parse_uint(const char *s, size_t n, size_t *out) // True when the control line opens with the operation name op and ends there or at a delimiter. static proto_bool verb_is(const char *buf, size_t line_len, const char *op) { - size_t n = str.len(op, line_len + 1); + size_t n = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = op, .cap = line_len + 1); if (line_len < n) { return PROTO_FALSE; } - if (mem.cmp(buf, op, n) != 0) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = buf, .other = op, .bytes = n) != 0) { return PROTO_FALSE; } diff --git a/src/services/iot/protobuf/CMakeLists.txt b/src/services/iot/protobuf/CMakeLists.txt index e588cef5c..7e7862b8d 100644 --- a/src/services/iot/protobuf/CMakeLists.txt +++ b/src/services/iot/protobuf/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(services/iot/protobuf GATE PROTOCORE_ENABLE_PROTOBUF SOURCES protobuf.c PRIVATE_DEPS - mmgr/plaintext - mmgr/protomem - mmgr/protostr + mmgr + server/core/worker ) diff --git a/src/services/iot/protobuf/protobuf.c b/src/services/iot/protobuf/protobuf.c index aa89eb606..cecfec784 100644 --- a/src/services/iot/protobuf/protobuf.c +++ b/src/services/iot/protobuf/protobuf.c @@ -12,12 +12,12 @@ */ #include "services/iot/protobuf/protobuf.h" -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #if PROTOCORE_ENABLE_PROTOBUF -#include "mmgr/protomem/protomem.h" // mem.cpy: the payload octets and the float bit patterns -#include "mmgr/protostr/protostr.h" // str.len: the bounded length of a NUL-terminated LEN payload +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len: the bounded length of a NUL-terminated LEN payload +#include "memoria_operor/memoria_operor.h" // memor.cpy: the payload octets and the float bit patterns PROTOCORE_BEGIN_DECLS @@ -107,7 +107,7 @@ static proto_bool writer_varint(uint8_t *work, uint64_t v) w->error = PROTO_TRUE; return PROTO_FALSE; } - mem.cpy(w->buf + w->pos, tmp, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = w->buf + w->pos, .src = tmp, .bytes = n); w->pos += n; return PROTO_TRUE; } @@ -159,7 +159,7 @@ static proto_bool writer_len(uint8_t *work, const uint8_t *data, size_t len) w->error = PROTO_TRUE; return PROTO_FALSE; } - mem.cpy(w->buf + w->pos, data, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = w->buf + w->pos, .src = data, .bytes = len); w->pos += len; return PROTO_TRUE; } @@ -228,7 +228,7 @@ uint8_t *protocore_protobuf_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_PROTOBUF_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_PROTOBUF_BORROW); } return s_own.span; } @@ -305,7 +305,7 @@ void protocore_protobuf_write_float(uint8_t *work) { uint32_t bits = 0; const float v = ProtobufV.value.f32; - mem.cpy(&bits, &v, 4); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &bits, .src = &v, .bytes = 4); ProtobufV.ok = writer_tag(work, PROTOCORE_PROTOBUF_WT_I32) && writer_le(work, (uint64_t)bits, 4); } @@ -314,7 +314,7 @@ void protocore_protobuf_write_double(uint8_t *work) { uint64_t bits = 0; const double v = ProtobufV.value.f64; - mem.cpy(&bits, &v, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &bits, .src = &v, .bytes = 8); ProtobufV.ok = writer_tag(work, PROTOCORE_PROTOBUF_WT_I64) && writer_le(work, bits, 8); } @@ -339,7 +339,8 @@ void protocore_protobuf_write_string(uint8_t *work) w->error = PROTO_TRUE; return; } - ProtobufV.ok = writer_len(work, (const uint8_t *)s, str.len(s, w->cap + 1)); + ProtobufV.ok = + writer_len(work, (const uint8_t *)s, EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = w->cap + 1)); } // Report the encoded octet count in ns->n, or 0 when any append overflowed. @@ -472,7 +473,7 @@ void protocore_protobuf_float_bits(uint8_t *work) (void)work; const uint32_t bits = ProtobufV.value.u32; float f = 0.0f; - mem.cpy(&f, &bits, 4); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &f, .src = &bits, .bytes = 4); ProtobufV.f32 = f; ProtobufV.ok = PROTO_TRUE; } @@ -483,7 +484,7 @@ void protocore_protobuf_double_bits(uint8_t *work) (void)work; const uint64_t bits = ProtobufV.value.u64; double d = 0.0; - mem.cpy(&d, &bits, 8); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &d, .src = &bits, .bytes = 8); ProtobufV.f64 = d; ProtobufV.ok = PROTO_TRUE; } diff --git a/src/services/iot/redis_resp/CMakeLists.txt b/src/services/iot/redis_resp/CMakeLists.txt index 64ad15fb0..7692e3c82 100644 --- a/src/services/iot/redis_resp/CMakeLists.txt +++ b/src/services/iot/redis_resp/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/iot/redis_resp GATE PROTOCORE_ENABLE_REDIS SOURCES redis_resp.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/iot/redis_resp/redis_resp.c b/src/services/iot/redis_resp/redis_resp.c index ff7b4118f..f451c938c 100644 --- a/src/services/iot/redis_resp/redis_resp.c +++ b/src/services/iot/redis_resp/redis_resp.c @@ -16,8 +16,8 @@ #include "services/iot/redis_resp/redis_resp.h" -#include "mmgr/protomem/protomem.h" // mem.cpy: the argument octets an encode moves -#include "mmgr/protostr/protostr.h" // str.len: the bounded length of a NUL-terminated argument +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len: the bounded length of a NUL-terminated argument +#include "memoria_operor/memoria_operor.h" // memor.cpy: the argument octets an encode moves PROTOCORE_BEGIN_DECLS @@ -360,7 +360,8 @@ void protocore_resp_encode_command(uint8_t *work) { return; } - const size_t alen = argv_len ? argv_len[i] : str.len(argv[i], cap); + const size_t alen = + argv_len ? argv_len[i] : EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = argv[i], .cap = cap); if (!put_len_prefix(buf, cap, &pos, '$', alen)) { return; @@ -369,7 +370,7 @@ void protocore_resp_encode_command(uint8_t *work) { return; } - mem.cpy(buf + pos, argv[i], alen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + pos, .src = argv[i], .bytes = alen); pos += alen; buf[pos++] = '\r'; buf[pos++] = '\n'; diff --git a/src/services/iot/stomp/CMakeLists.txt b/src/services/iot/stomp/CMakeLists.txt index 984b68492..719382a7e 100644 --- a/src/services/iot/stomp/CMakeLists.txt +++ b/src/services/iot/stomp/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/iot/stomp GATE PROTOCORE_ENABLE_STOMP SOURCES stomp.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/iot/stomp/stomp.c b/src/services/iot/stomp/stomp.c index b9a178481..e55827d12 100644 --- a/src/services/iot/stomp/stomp.c +++ b/src/services/iot/stomp/stomp.c @@ -19,8 +19,8 @@ #include "services/iot/stomp/stomp.h" -#include "mmgr/protomem/protomem.h" // mem.cpy / mem.cmp: the spans a frame is assembled from and matched over -#include "mmgr/protostr/protostr.h" // str.len: the bounded length of a header-name needle +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len: the bounded length of a header-name needle +#include "memoria_operor/memoria_operor.h" // memor.cpy / memor.cmp: the spans a frame is assembled from and matched over PROTOCORE_BEGIN_DECLS @@ -187,7 +187,7 @@ void protocore_stomp_build(uint8_t *work) { return; } - mem.cpy(out + pos, a->body, a->body_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = a->body, .bytes = a->body_len); pos += a->body_len; } if (pos + 1 > cap) @@ -291,7 +291,8 @@ void protocore_stomp_parse(uint8_t *work) // The first content-length entry sizes the body (sec 4.3.1, sec 4.4). A value that is // not a count of digits, or one wider than size_t, fails the frame. if (!have_content_length && h->name_len == PROTOCORE_STOMP_CONTENT_LENGTH_LEN && - mem.cmp(h->name, PROTOCORE_STOMP_CONTENT_LENGTH, PROTOCORE_STOMP_CONTENT_LENGTH_LEN) == 0) + EMBED_CALL(memor.cmp, MemoriaCfg, .src = h->name, .other = PROTOCORE_STOMP_CONTENT_LENGTH, + .bytes = PROTOCORE_STOMP_CONTENT_LENGTH_LEN) == 0) { if (!parse_len(h->value, h->value_len, &content_length)) { @@ -353,10 +354,11 @@ void protocore_stomp_header(uint8_t *work) { return; } - const size_t nlen = str.len(name, PROTOCORE_STOMP_HEADER_NAME_MAX); + const size_t nlen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = name, .cap = PROTOCORE_STOMP_HEADER_NAME_MAX); for (size_t i = 0; i < f->header_count; i++) { - if (f->headers[i].name_len == nlen && mem.cmp(f->headers[i].name, name, nlen) == 0) + if (f->headers[i].name_len == nlen && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = f->headers[i].name, .other = name, .bytes = nlen) == 0) { StompV.value = f->headers[i].value; StompV.value_len = f->headers[i].value_len; diff --git a/src/services/iot/xmpp/CMakeLists.txt b/src/services/iot/xmpp/CMakeLists.txt index f41fe3975..89a76680c 100644 --- a/src/services/iot/xmpp/CMakeLists.txt +++ b/src/services/iot/xmpp/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/iot/xmpp GATE PROTOCORE_ENABLE_XMPP SOURCES xmpp.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/iot/xmpp/xmpp.c b/src/services/iot/xmpp/xmpp.c index c877ed46b..1af937de4 100644 --- a/src/services/iot/xmpp/xmpp.c +++ b/src/services/iot/xmpp/xmpp.c @@ -17,8 +17,8 @@ #include "services/iot/xmpp/xmpp.h" -#include "mmgr/protomem/protomem.h" // mem.cpy: a literal and an entity move whole -#include "mmgr/protostr/protostr.h" // str.len / str.starts: the bounded length and the attribute-name match +#include "cellularum_laboro/cellularum_laboro.h" // cellul.len / cellul.starts: the bounded length and the attribute-name match +#include "memoria_operor/memoria_operor.h" // memor.cpy: a literal and an entity move whole PROTOCORE_BEGIN_DECLS @@ -119,13 +119,13 @@ static void put(uint8_t *work, const char *s) return; } const size_t cap = XmppV.out.cap; - const size_t sl = str.len(s, cap); + const size_t sl = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = s, .cap = cap); if (XmppV.n + sl >= cap) { XmppV.ok = PROTO_FALSE; return; } - mem.cpy(XmppV.out.buf + XmppV.n, s, sl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = XmppV.out.buf + XmppV.n, .src = s, .bytes = sl); XmppV.n += sl; } @@ -162,7 +162,7 @@ static void put_attr(uint8_t *work, const char *name, const char *value) put(work, name); put_char(work, '='); put_char(work, '"'); - put_escaped(work, value, str.len(value, XmppV.out.cap)); + put_escaped(work, value, EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = value, .cap = XmppV.out.cap)); put_char(work, '"'); } @@ -203,7 +203,8 @@ void protocore_xmpp_message(uint8_t *work) if (XmppV.child.body != NULL) { put(work, ""); - put_escaped(work, XmppV.child.body, str.len(XmppV.child.body, XmppV.out.cap)); + put_escaped(work, XmppV.child.body, + EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = XmppV.child.body, .cap = XmppV.out.cap)); put(work, ""); } put(work, ""); @@ -304,7 +305,7 @@ void protocore_xmpp_attr(uint8_t *work) finish(work); return; } - const size_t nl = str.len(name, len); + const size_t nl = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = name, .cap = len); // An attribute specification belongs to the start-tag, which ends at its '>'. size_t end = 0; @@ -328,7 +329,10 @@ void protocore_xmpp_attr(uint8_t *work) { sep = PROTO_TRUE; } - if (sep && str.starts(xml + i, name, nl + 1, PROTO_FALSE) && xml[i + nl] == '=') + if (sep && + EMBED_CALL(cellul.starts, CatenaFinitaCfg, .src = xml + i, .other = name, .cap = nl + 1, + .ci = PROTO_FALSE) && + xml[i + nl] == '=') { found = PROTO_TRUE; } diff --git a/src/services/machine_tool/atc/CMakeLists.txt b/src/services/machine_tool/atc/CMakeLists.txt index a96a2cfa1..c38ed15a5 100644 --- a/src/services/machine_tool/atc/CMakeLists.txt +++ b/src/services/machine_tool/atc/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/machine_tool/atc GATE PROTOCORE_ENABLE_ATC SOURCES atc.c PRIVATE_DEPS - mmgr/membuild - mmgr/protostr + mmgr ) diff --git a/src/services/machine_tool/atc/atc.c b/src/services/machine_tool/atc/atc.c index f1663cced..9b4b045f1 100644 --- a/src/services/machine_tool/atc/atc.c +++ b/src/services/machine_tool/atc/atc.c @@ -10,36 +10,31 @@ #if PROTOCORE_ENABLE_ATC -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protostr/protostr.h" // str.eq: the FIO point name lookup +#include "cellularum_laboro/cellularum_laboro.h" // cellul.eq: the FIO point name lookup #include "services/machine_tool/atc/atc.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS -static void put_json_str(protocore_sb *b, const char *s) +static size_t put_json_str(char *out, size_t cap, size_t at, const char *s) { - Sb.put(b, "\""); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "\""); for (const char *p = s ? s : ""; *p; p++) { if (*p == '"' || *p == '\\') { char esc[3] = {'\\', *p, '\0'}; - Sb.put(b, esc); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = esc); } else { - if (b->len + 1 >= b->cap) - { - b->ok = PROTO_FALSE; - return; - } - b->p[b->len++] = *p; + at = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = out, .cap = cap, .at = at, .ch = *p); } } - Sb.put(b, "\""); + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "\""); } -static void put_u8(protocore_sb *b, uint8_t v) +static size_t put_u8(char *out, size_t cap, size_t at, uint8_t v) { char t[4]; int n = 0; @@ -54,13 +49,13 @@ static void put_u8(protocore_sb *b, uint8_t v) o[i] = t[n - 1 - i]; } o[n] = '\0'; - Sb.put(b, o); + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = o); } // Append the points of one direction (outputs or inputs) as a JSON array. -static void put_array(protocore_sb *b, const AtcFieldIo *io, proto_bool outputs) +static size_t put_array(char *out, size_t cap, size_t at, const AtcFieldIo *io, proto_bool outputs) { - Sb.put(b, "["); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "["); proto_bool first = PROTO_TRUE; for (size_t i = 0; i < io->count; i++) { @@ -70,16 +65,16 @@ static void put_array(protocore_sb *b, const AtcFieldIo *io, proto_bool outputs) } if (!first) { - Sb.put(b, ","); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = ","); } first = PROTO_FALSE; - Sb.put(b, "{\"name\":"); - put_json_str(b, io->points[i].name); - Sb.put(b, ",\"value\":"); - put_u8(b, io->points[i].value); - Sb.put(b, "}"); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "{\"name\":"); + at = put_json_str(out, cap, at, io->points[i].name); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = ",\"value\":"); + at = put_u8(out, cap, at, io->points[i].value); + at = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "}"); } - Sb.put(b, "]"); + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = "]"); } size_t protocore_atc_snapshot_json(const AtcFieldIo *io, char *out, size_t cap) @@ -88,18 +83,18 @@ size_t protocore_atc_snapshot_json(const AtcFieldIo *io, char *out, size_t cap) { return 0; } - protocore_sb b = {out, cap, 0, cap > 0}; - Sb.put(&b, "{\"inputs\":"); - put_array(&b, io, PROTO_FALSE); - Sb.put(&b, ",\"outputs\":"); - put_array(&b, io, PROTO_TRUE); - Sb.put(&b, "}"); - if (!b.ok) + size_t b = 0; + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "{\"inputs\":"); + b = put_array(out, cap, b, io, PROTO_FALSE); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"outputs\":"); + b = put_array(out, cap, b, io, PROTO_TRUE); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "}"); + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = b)) { return 0; } - out[b.len] = '\0'; - return b.len; + out[b] = '\0'; + return b; } proto_bool protocore_atc_set_output(AtcFieldIo *io, const char *name, uint8_t value) @@ -110,7 +105,9 @@ proto_bool protocore_atc_set_output(AtcFieldIo *io, const char *name, uint8_t va } for (size_t i = 0; i < io->count; i++) { - if (io->points[i].is_output && io->points[i].name && str.eq(io->points[i].name, name, MAX_KEY_LEN, PROTO_FALSE)) + if (io->points[i].is_output && io->points[i].name && + EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = io->points[i].name, .other = name, .cap = MAX_KEY_LEN, + .ci = PROTO_FALSE)) { io->points[i].value = value; return PROTO_TRUE; @@ -131,7 +128,8 @@ uint8_t protocore_atc_get(const AtcFieldIo *io, const char *name, proto_bool *fo } for (size_t i = 0; i < io->count; i++) { - if (io->points[i].name && str.eq(io->points[i].name, name, MAX_KEY_LEN, PROTO_FALSE)) + if (io->points[i].name && EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = io->points[i].name, .other = name, + .cap = MAX_KEY_LEN, .ci = PROTO_FALSE)) { if (found) { diff --git a/src/services/machine_tool/dnc/dnc_stream/CMakeLists.txt b/src/services/machine_tool/dnc/dnc_stream/CMakeLists.txt index f20544bd7..73638a98f 100644 --- a/src/services/machine_tool/dnc/dnc_stream/CMakeLists.txt +++ b/src/services/machine_tool/dnc/dnc_stream/CMakeLists.txt @@ -7,5 +7,5 @@ protocore_add_module(services/machine_tool/dnc/dnc_stream DEPS services/machine_tool/dnc/dnc PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/machine_tool/dnc/dnc_stream/dnc_stream.c b/src/services/machine_tool/dnc/dnc_stream/dnc_stream.c index 60c648c29..06e08f1dc 100644 --- a/src/services/machine_tool/dnc/dnc_stream/dnc_stream.c +++ b/src/services/machine_tool/dnc/dnc_stream/dnc_stream.c @@ -11,7 +11,7 @@ #if PROTOCORE_ENABLE_DNC -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/machine_tool/dnc/dnc_stream/dnc_stream.h" PROTOCORE_BEGIN_DECLS @@ -58,7 +58,7 @@ static proto_bool emit(DncFlow *flow, DncSendFn send, DncRecvFn recv, void *ctx, static proto_bool emit_runout(DncFlow *flow, DncSendFn send, DncRecvFn recv, void *ctx, uint16_t count) { uint8_t zeros[32]; - mem.set(zeros, 0, sizeof(zeros)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = zeros, .val = 0, .bytes = sizeof(zeros)); while (count) { uint16_t chunk = count < sizeof(zeros) ? count : (uint16_t)sizeof(zeros); diff --git a/src/services/machine_tool/fanuc_j519/CMakeLists.txt b/src/services/machine_tool/fanuc_j519/CMakeLists.txt index 03c087dae..35117eb11 100644 --- a/src/services/machine_tool/fanuc_j519/CMakeLists.txt +++ b/src/services/machine_tool/fanuc_j519/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/machine_tool/fanuc_j519 GATE PROTOCORE_ENABLE_FANUC_J519 SOURCES fanuc_j519.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/services/machine_tool/fanuc_j519/fanuc_j519.c b/src/services/machine_tool/fanuc_j519/fanuc_j519.c index 43bb3503f..c83d3307b 100644 --- a/src/services/machine_tool/fanuc_j519/fanuc_j519.c +++ b/src/services/machine_tool/fanuc_j519/fanuc_j519.c @@ -15,10 +15,10 @@ #if PROTOCORE_ENABLE_FANUC_J519 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/machine_tool/fanuc_j519/fanuc_j519.h" -#include "mmgr/endian/endian.h" +#include "endian/endian.h" // memcpy (string.h is allowed; the no-stdlib rule is about stdlib.h/malloc) PROTOCORE_BEGIN_DECLS @@ -27,14 +27,14 @@ PROTOCORE_BEGIN_DECLS static size_t wr_f32be(uint8_t *p, float v) { uint32_t u; - mem.cpy(&u, &v, 4); - return endian.wr32be(p, u); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &u, .src = &v, .bytes = 4); + return EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = p, .val = u, .width = MMGR_ENDIAN_32); } static float rd_f32be(const uint8_t *p) { - uint32_t u = endian.rd32be(p); + uint32_t u = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = p, .width = MMGR_ENDIAN_32); float v; - mem.cpy(&v, &u, 4); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &v, .src = &u, .bytes = 4); return v; } @@ -57,15 +57,17 @@ static void rd_f32_block(const uint8_t *p, float *dst, size_t n) // Every packet opens with { type, version } - written once here so no builder repeats it. static void wr_header(uint8_t *buf, J519Type type, uint32_t version_no) { - endian.wr32be(buf + 0, (uint32_t)type); - endian.wr32be(buf + 4, version_no); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 0, .val = (uint32_t)type, .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 4, .val = version_no, .width = MMGR_ENDIAN_32); } // A parser accepts only its own exact length and type code (the type space is shared per direction, // so length is what actually separates Start from Status and Request from Ack). static proto_bool hdr_ok(const uint8_t *buf, size_t len, size_t want_len, J519Type want_type) { - return buf && len == want_len && endian.rd32be(buf + 0) == (uint32_t)want_type; + return buf && len == want_len && + (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 0, .width = MMGR_ENDIAN_32) == + (uint32_t)want_type; } // --- header --------------------------------------------------------------------------------------- @@ -78,11 +80,11 @@ proto_bool protocore_j519_peek(const uint8_t *buf, size_t len, uint32_t *type, u } if (type) { - *type = endian.rd32be(buf + 0); + *type = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 0, .width = MMGR_ENDIAN_32); } if (version_no) { - *version_no = endian.rd32be(buf + 4); + *version_no = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 4, .width = MMGR_ENDIAN_32); } return PROTO_TRUE; } @@ -116,17 +118,17 @@ size_t protocore_j519_build_motion(uint8_t *buf, size_t cap, const J519MotionCom return 0; } wr_header(buf, J519_MOTION, cmd->version_no); - endian.wr32be(buf + 8, cmd->sequence_no); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 8, .val = cmd->sequence_no, .width = MMGR_ENDIAN_32); buf[12] = cmd->last_data; buf[13] = cmd->read_io_type; - endian.wr16be(buf + 14, cmd->read_io_index); - endian.wr16be(buf + 16, cmd->read_io_mask); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 14, .val = cmd->read_io_index, .width = MMGR_ENDIAN_16); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 16, .val = cmd->read_io_mask, .width = MMGR_ENDIAN_16); buf[18] = cmd->data_style; buf[19] = cmd->write_io_type; - endian.wr16be(buf + 20, cmd->write_io_index); - endian.wr16be(buf + 22, cmd->write_io_mask); - endian.wr16be(buf + 24, cmd->write_io_value); - endian.wr16be(buf + 26, 0); // unused + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 20, .val = cmd->write_io_index, .width = MMGR_ENDIAN_16); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 22, .val = cmd->write_io_mask, .width = MMGR_ENDIAN_16); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 24, .val = cmd->write_io_value, .width = MMGR_ENDIAN_16); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 26, .val = 0, .width = MMGR_ENDIAN_16); // unused wr_f32_block(buf + 28, cmd->joint_data, PROTOCORE_J519_AXES); return PROTOCORE_J519_LEN_MOTION; } @@ -138,8 +140,8 @@ size_t protocore_j519_build_request(uint8_t *buf, size_t cap, const J519Request return 0; } wr_header(buf, J519_REQUEST_OR_ACK, req->version_no); - endian.wr32be(buf + 8, req->axis_no); - endian.wr32be(buf + 12, req->threshold_type); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 8, .val = req->axis_no, .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 12, .val = req->threshold_type, .width = MMGR_ENDIAN_32); return PROTOCORE_J519_LEN_REQUEST; } @@ -151,17 +153,19 @@ proto_bool protocore_j519_parse_motion(const uint8_t *buf, size_t len, J519Motio { return PROTO_FALSE; } - out->version_no = endian.rd32be(buf + 4); - out->sequence_no = endian.rd32be(buf + 8); + out->version_no = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 4, .width = MMGR_ENDIAN_32); + out->sequence_no = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 8, .width = MMGR_ENDIAN_32); out->last_data = buf[12]; out->read_io_type = buf[13]; - out->read_io_index = endian.rd16be(buf + 14); - out->read_io_mask = endian.rd16be(buf + 16); + out->read_io_index = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 14, .width = MMGR_ENDIAN_16); + out->read_io_mask = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 16, .width = MMGR_ENDIAN_16); out->data_style = buf[18]; out->write_io_type = buf[19]; - out->write_io_index = endian.rd16be(buf + 20); - out->write_io_mask = endian.rd16be(buf + 22); - out->write_io_value = endian.rd16be(buf + 24); + out->write_io_index = + (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 20, .width = MMGR_ENDIAN_16); + out->write_io_mask = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 22, .width = MMGR_ENDIAN_16); + out->write_io_value = + (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 24, .width = MMGR_ENDIAN_16); // octets 26..27 are unused padding - not surfaced rd_f32_block(buf + 28, out->joint_data, PROTOCORE_J519_AXES); return PROTO_TRUE; @@ -173,9 +177,10 @@ proto_bool protocore_j519_parse_request(const uint8_t *buf, size_t len, J519Requ { return PROTO_FALSE; } - out->version_no = endian.rd32be(buf + 4); - out->axis_no = endian.rd32be(buf + 8); - out->threshold_type = endian.rd32be(buf + 12); + out->version_no = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 4, .width = MMGR_ENDIAN_32); + out->axis_no = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 8, .width = MMGR_ENDIAN_32); + out->threshold_type = + (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 12, .width = MMGR_ENDIAN_32); return PROTO_TRUE; } @@ -188,13 +193,13 @@ size_t protocore_j519_build_status(uint8_t *buf, size_t cap, const J519RobotStat return 0; } wr_header(buf, J519_START_OR_STATUS, st->version_no); - endian.wr32be(buf + 8, st->sequence_no); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 8, .val = st->sequence_no, .width = MMGR_ENDIAN_32); buf[12] = st->status; buf[13] = st->read_io_type; - endian.wr16be(buf + 14, st->read_io_index); - endian.wr16be(buf + 16, st->read_io_mask); - endian.wr16be(buf + 18, st->read_io_value); - endian.wr32be(buf + 20, st->time_stamp); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 14, .val = st->read_io_index, .width = MMGR_ENDIAN_16); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 16, .val = st->read_io_mask, .width = MMGR_ENDIAN_16); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 18, .val = st->read_io_value, .width = MMGR_ENDIAN_16); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 20, .val = st->time_stamp, .width = MMGR_ENDIAN_32); wr_f32_block(buf + 24, st->cartesian_pose, PROTOCORE_J519_AXES); wr_f32_block(buf + 60, st->joint_pose, PROTOCORE_J519_AXES); wr_f32_block(buf + 96, st->motor_current, PROTOCORE_J519_AXES); @@ -208,10 +213,10 @@ size_t protocore_j519_build_ack(uint8_t *buf, size_t cap, const J519Ack *ack) return 0; } wr_header(buf, J519_REQUEST_OR_ACK, ack->version_no); - endian.wr32be(buf + 8, ack->axis_no); - endian.wr32be(buf + 12, ack->threshold_type); - endian.wr32be(buf + 16, ack->max_cart_speed); - endian.wr32be(buf + 20, ack->unknown0); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 8, .val = ack->axis_no, .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 12, .val = ack->threshold_type, .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 16, .val = ack->max_cart_speed, .width = MMGR_ENDIAN_32); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + 20, .val = ack->unknown0, .width = MMGR_ENDIAN_32); wr_f32_block(buf + 24, ack->threshold_no_load, PROTOCORE_J519_THRESHOLDS); wr_f32_block(buf + 104, ack->threshold_max_load, PROTOCORE_J519_THRESHOLDS); return PROTOCORE_J519_LEN_ACK; @@ -225,14 +230,14 @@ proto_bool protocore_j519_parse_status(const uint8_t *buf, size_t len, J519Robot { return PROTO_FALSE; } - out->version_no = endian.rd32be(buf + 4); - out->sequence_no = endian.rd32be(buf + 8); + out->version_no = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 4, .width = MMGR_ENDIAN_32); + out->sequence_no = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 8, .width = MMGR_ENDIAN_32); out->status = buf[12]; out->read_io_type = buf[13]; - out->read_io_index = endian.rd16be(buf + 14); - out->read_io_mask = endian.rd16be(buf + 16); - out->read_io_value = endian.rd16be(buf + 18); - out->time_stamp = endian.rd32be(buf + 20); + out->read_io_index = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 14, .width = MMGR_ENDIAN_16); + out->read_io_mask = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 16, .width = MMGR_ENDIAN_16); + out->read_io_value = (uint16_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 18, .width = MMGR_ENDIAN_16); + out->time_stamp = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 20, .width = MMGR_ENDIAN_32); rd_f32_block(buf + 24, out->cartesian_pose, PROTOCORE_J519_AXES); rd_f32_block(buf + 60, out->joint_pose, PROTOCORE_J519_AXES); rd_f32_block(buf + 96, out->motor_current, PROTOCORE_J519_AXES); @@ -245,11 +250,13 @@ proto_bool protocore_j519_parse_ack(const uint8_t *buf, size_t len, J519Ack *out { return PROTO_FALSE; } - out->version_no = endian.rd32be(buf + 4); - out->axis_no = endian.rd32be(buf + 8); - out->threshold_type = endian.rd32be(buf + 12); - out->max_cart_speed = endian.rd32be(buf + 16); - out->unknown0 = endian.rd32be(buf + 20); + out->version_no = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 4, .width = MMGR_ENDIAN_32); + out->axis_no = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 8, .width = MMGR_ENDIAN_32); + out->threshold_type = + (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 12, .width = MMGR_ENDIAN_32); + out->max_cart_speed = + (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 16, .width = MMGR_ENDIAN_32); + out->unknown0 = (uint32_t)EMBED_CALL(magna_extremitas.rd, EndianCfg, .src = buf + 20, .width = MMGR_ENDIAN_32); rd_f32_block(buf + 24, out->threshold_no_load, PROTOCORE_J519_THRESHOLDS); rd_f32_block(buf + 104, out->threshold_max_load, PROTOCORE_J519_THRESHOLDS); return PROTO_TRUE; diff --git a/src/services/machine_tool/focas/CMakeLists.txt b/src/services/machine_tool/focas/CMakeLists.txt index b44bbd95d..dcaaa039f 100644 --- a/src/services/machine_tool/focas/CMakeLists.txt +++ b/src/services/machine_tool/focas/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/machine_tool/focas GATE PROTOCORE_ENABLE_FOCAS SOURCES focas.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/machine_tool/focas/focas.c b/src/services/machine_tool/focas/focas.c index 0963dd067..ae200c2ad 100644 --- a/src/services/machine_tool/focas/focas.c +++ b/src/services/machine_tool/focas/focas.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_FOCAS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/machine_tool/focas/focas.h" PROTOCORE_BEGIN_DECLS @@ -104,7 +104,7 @@ size_t protocore_focas_build_request(uint8_t *buf, size_t cap, FocasCmd cmd, int p += put32be(buf + p, (uint32_t)v5); if (extra_len) { - mem.cpy(buf + p, extra, extra_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = extra, .bytes = extra_len); p += extra_len; } return p; @@ -207,15 +207,15 @@ proto_bool protocore_focas_parse_sysinfo(const uint8_t *data, size_t data_len, F } out->add_info = get16be(data); out->max_axis = get16be(data + 2); - mem.cpy(out->cnc_type, data + 4, 2); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->cnc_type, .src = data + 4, .bytes = 2); out->cnc_type[2] = '\0'; - mem.cpy(out->mt_type, data + 6, 2); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->mt_type, .src = data + 6, .bytes = 2); out->mt_type[2] = '\0'; - mem.cpy(out->series, data + 8, 4); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->series, .src = data + 8, .bytes = 4); out->series[4] = '\0'; - mem.cpy(out->version, data + 12, 4); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->version, .src = data + 12, .bytes = 4); out->version[4] = '\0'; - mem.cpy(out->axes, data + 16, 2); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->axes, .src = data + 16, .bytes = 2); out->axes[2] = '\0'; return PROTO_TRUE; } diff --git a/src/services/machine_tool/haas_mdc/CMakeLists.txt b/src/services/machine_tool/haas_mdc/CMakeLists.txt index 7645f7c0f..26cdce89b 100644 --- a/src/services/machine_tool/haas_mdc/CMakeLists.txt +++ b/src/services/machine_tool/haas_mdc/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/machine_tool/haas_mdc GATE PROTOCORE_ENABLE_HAAS_MDC SOURCES haas_mdc.c PRIVATE_DEPS - mmgr/membuild + mmgr ) diff --git a/src/services/machine_tool/haas_mdc/haas_mdc.c b/src/services/machine_tool/haas_mdc/haas_mdc.c index 3dbc7cebf..629368869 100644 --- a/src/services/machine_tool/haas_mdc/haas_mdc.c +++ b/src/services/machine_tool/haas_mdc/haas_mdc.c @@ -12,7 +12,7 @@ #include "services/machine_tool/haas_mdc/haas_mdc.h" -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -86,11 +86,13 @@ size_t protocore_haas_mdc_build_q(char *buf, size_t cap, uint16_t qnum) { return 0; } - protocore_sb sb_q = {buf, cap, 0, PROTO_TRUE}; - protocore_sb_lit(&sb_q, "?Q"); - Sb.u32(&sb_q, qnum); - Sb.ch(&sb_q, '\n'); // [NGC] Query Format: the query is "terminated with a new line" - return Sb.finish(&sb_q); + size_t sb_q = 0; + sb_q = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_q, .text = "?Q", + .text_len = sizeof("?Q") - 1); + sb_q = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_q, .val = qnum); + // [NGC] Query Format: the query is "terminated with a new line" + sb_q = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = buf, .cap = cap, .at = sb_q, .ch = '\n'); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = buf, .cap = cap, .at = sb_q); } size_t protocore_haas_mdc_build_var(char *buf, size_t cap, uint32_t var) @@ -99,11 +101,13 @@ size_t protocore_haas_mdc_build_var(char *buf, size_t cap, uint32_t var) { return 0; } - protocore_sb sb_var = {buf, cap, 0, PROTO_TRUE}; - protocore_sb_lit(&sb_var, "?Q600 "); - Sb.u32(&sb_var, var); - Sb.ch(&sb_var, '\n'); // the ?Q600 line is a query in the ?Q### family, same sentence - return Sb.finish(&sb_var); + size_t sb_var = 0; + sb_var = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = buf, .cap = cap, .at = sb_var, .text = "?Q600 ", + .text_len = sizeof("?Q600 ") - 1); + sb_var = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = buf, .cap = cap, .at = sb_var, .val = var); + // the ?Q600 line is a query in the ?Q### family, same sentence + sb_var = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = buf, .cap = cap, .at = sb_var, .ch = '\n'); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = buf, .cap = cap, .at = sb_var); } proto_bool protocore_haas_mdc_parse(const char *buf, size_t len, HaasMdcResp *out) diff --git a/src/services/machine_tool/lsv2/CMakeLists.txt b/src/services/machine_tool/lsv2/CMakeLists.txt index a772acbda..2c2a6cf63 100644 --- a/src/services/machine_tool/lsv2/CMakeLists.txt +++ b/src/services/machine_tool/lsv2/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/machine_tool/lsv2 GATE PROTOCORE_ENABLE_LSV2 SOURCES lsv2.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/machine_tool/lsv2/lsv2.c b/src/services/machine_tool/lsv2/lsv2.c index 45b5256a5..f824a3af0 100644 --- a/src/services/machine_tool/lsv2/lsv2.c +++ b/src/services/machine_tool/lsv2/lsv2.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_LSV2 -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/machine_tool/lsv2/lsv2.h" // memcpy / memcmp / memset (framing + parsing are hand-rolled) @@ -25,7 +25,7 @@ static size_t finalize(uint8_t *buf, const char *mnemonic, size_t payload_len) buf[1] = (uint8_t)(payload_len >> 16); buf[2] = (uint8_t)(payload_len >> 8); buf[3] = (uint8_t)(payload_len); - mem.cpy(buf + 4, mnemonic, PROTOCORE_LSV2_MNEMONIC_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + 4, .src = mnemonic, .bytes = PROTOCORE_LSV2_MNEMONIC_LEN); return PROTOCORE_LSV2_HEADER_LEN + payload_len; } @@ -71,7 +71,7 @@ size_t protocore_lsv2_build(uint8_t *buf, size_t cap, const char *mnemonic, cons } if (payload_len) { - mem.cpy(buf + PROTOCORE_LSV2_HEADER_LEN, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + PROTOCORE_LSV2_HEADER_LEN, .src = payload, .bytes = payload_len); } return finalize(buf, mnemonic, payload_len); } @@ -82,7 +82,7 @@ proto_bool protocore_lsv2_parse(const uint8_t *buf, size_t len, Lsv2Telegram *ou { return PROTO_FALSE; } - mem.set(out->mnemonic, 0, PROTOCORE_LSV2_MNEMONIC_LEN); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out->mnemonic, .val = 0, .bytes = PROTOCORE_LSV2_MNEMONIC_LEN); out->payload = NULL; out->payload_len = 0; @@ -98,7 +98,7 @@ proto_bool protocore_lsv2_parse(const uint8_t *buf, size_t len, Lsv2Telegram *ou return PROTO_FALSE; // incomplete - caller accumulates more } - mem.cpy(out->mnemonic, buf + 4, PROTOCORE_LSV2_MNEMONIC_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->mnemonic, .src = buf + 4, .bytes = PROTOCORE_LSV2_MNEMONIC_LEN); out->payload = plen ? buf + PROTOCORE_LSV2_HEADER_LEN : NULL; out->payload_len = plen; if (consumed) @@ -110,7 +110,9 @@ proto_bool protocore_lsv2_parse(const uint8_t *buf, size_t len, Lsv2Telegram *ou proto_bool protocore_lsv2_is(const Lsv2Telegram *t, const char *mnemonic4) { - return t && mnemonic4 && mem.cmp(t->mnemonic, mnemonic4, PROTOCORE_LSV2_MNEMONIC_LEN) == 0; + return t && mnemonic4 && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = t->mnemonic, .other = mnemonic4, + .bytes = PROTOCORE_LSV2_MNEMONIC_LEN) == 0; } size_t protocore_lsv2_build_login(uint8_t *buf, size_t cap, const char *login, const char *password) diff --git a/src/services/machine_tool/mtconnect/CMakeLists.txt b/src/services/machine_tool/mtconnect/CMakeLists.txt index f64f96a21..88b764e93 100644 --- a/src/services/machine_tool/mtconnect/CMakeLists.txt +++ b/src/services/machine_tool/mtconnect/CMakeLists.txt @@ -5,9 +5,8 @@ protocore_add_module(services/machine_tool/mtconnect GATE PROTOCORE_ENABLE_MTCONNECT SOURCES mtconnect.c PRIVATE_DEPS - mmgr/plaintext - mmgr/protomem - mmgr/protostr + mmgr + server/core/worker server/clock shared/time_compat ) diff --git a/src/services/machine_tool/mtconnect/mtconnect.c b/src/services/machine_tool/mtconnect/mtconnect.c index e78254579..4989714a3 100644 --- a/src/services/machine_tool/mtconnect/mtconnect.c +++ b/src/services/machine_tool/mtconnect/mtconnect.c @@ -13,10 +13,10 @@ #if PROTOCORE_ENABLE_MTCONNECT -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" -#include "server/clock/clock.h" // the always-on system clock behind creationTime +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" +#include "server/clock/clock.h" // the always-on system clock behind creationTime +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "services/machine_tool/mtconnect/mtconnect.h" #include "shared/time_compat/time_compat.h" // the UTC breakdown creationTime is formatted from @@ -64,8 +64,8 @@ static_assert(MTC_OFF_RING + (size_t)PROTOCORE_MTC_SAMPLE_BUFFER * sizeof(MtConn "PROTOCORE_MTCONNECT_BORROW is short of the context and the observation ring - raise it in " "protocore_config.h, which sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(MTC_OFF_CTX % _Alignof(MtConnectCtx) == 0, @@ -87,7 +87,7 @@ uint8_t *protocore_mtconnect_span(void) { if (s_span == NULL) { - s_span = protocore_plaintext_persist_span(PROTOCORE_MTCONNECT_BORROW).buf; + s_span = (uint8_t *)protocore_plain_persist(PROTOCORE_MTCONNECT_BORROW); } return s_span; } @@ -102,13 +102,13 @@ static void put(uint8_t *work, const char *text) { return; } - size_t tl = str.len(text, c->cap + 1); + size_t tl = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = text, .cap = c->cap + 1); if (c->len + tl >= c->cap) { c->ok = PROTO_FALSE; return; } - mem.cpy(c->out + c->len, text, tl); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = c->out + c->len, .src = text, .bytes = tl); c->len += tl; } @@ -187,7 +187,7 @@ static char *open_gap(uint8_t *work, size_t at, size_t n) c->ok = PROTO_FALSE; return NULL; } - mem.move(c->out + at + n, c->out + at, c->len - at); + EMBED_CALL(memor.move_up, MemoriaCfg, .dst = c->out + at + n, .src = c->out + at, .bytes = c->len - at); c->len += n; return c->out + at; } @@ -195,11 +195,11 @@ static char *open_gap(uint8_t *work, size_t at, size_t n) // Put the literal @p text at @p at rather than at the end. static void put_at(uint8_t *work, size_t at, const char *text) { - size_t n = str.len(text, MTC_CTX(work)->cap + 1); + size_t n = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = text, .cap = MTC_CTX(work)->cap + 1); char *gap = open_gap(work, at, n); if (gap) { - mem.cpy(gap, text, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = gap, .src = text, .bytes = n); } } diff --git a/src/services/net/flow_export/CMakeLists.txt b/src/services/net/flow_export/CMakeLists.txt index 9bcc5a1b9..d2070ac4e 100644 --- a/src/services/net/flow_export/CMakeLists.txt +++ b/src/services/net/flow_export/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(services/net/flow_export GATE PROTOCORE_ENABLE_FLOW_EXPORT SOURCES flow_export.c PRIVATE_DEPS - mmgr/endian - mmgr/plaintext - mmgr/protomem + mmgr + server/core/worker ) diff --git a/src/services/net/flow_export/flow_export.c b/src/services/net/flow_export/flow_export.c index 4cd1ad2df..b2789d768 100644 --- a/src/services/net/flow_export/flow_export.c +++ b/src/services/net/flow_export/flow_export.c @@ -17,11 +17,11 @@ #if PROTOCORE_ENABLE_FLOW_EXPORT -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "services/net/flow_export/flow_export.h" -#include "mmgr/endian/endian.h" +#include "endian/endian.h" PROTOCORE_BEGIN_DECLS @@ -79,7 +79,7 @@ uint8_t *protocore_flow_export_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_FLOW_EXPORT_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_FLOW_EXPORT_BORROW); } return s_own.span; } @@ -105,7 +105,7 @@ static void put_u16(uint8_t *work, uint16_t v) m->error = PROTO_TRUE; return; } - m->pos += endian.wr16be(m->buf + m->pos, v); + m->pos += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = m->buf + m->pos, .val = v, .width = MMGR_ENDIAN_16); } // Append @p v as four octets, most significant first. @@ -121,7 +121,7 @@ static void put_u32(uint8_t *work, uint32_t v) m->error = PROTO_TRUE; return; } - m->pos += endian.wr32be(m->buf + m->pos, v); + m->pos += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = m->buf + m->pos, .val = v, .width = MMGR_ENDIAN_32); } // Append @p n octets from @p p. @@ -137,7 +137,7 @@ static void put_span(uint8_t *work, const uint8_t *p, size_t n) m->error = PROTO_TRUE; return; } - mem.cpy(m->buf + m->pos, p, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = m->buf + m->pos, .src = p, .bytes = n); m->pos += n; } @@ -154,14 +154,15 @@ static void put_zero(uint8_t *work, size_t n) m->error = PROTO_TRUE; return; } - mem.set(m->buf + m->pos, 0, n); + EMBED_CALL(memor.set, MemoriaCfg, .dst = m->buf + m->pos, .val = 0, .bytes = n); m->pos += n; } // Overwrite the two octets at @p off with @p v. Only reached with off + 2 <= pos. static void patch_u16(uint8_t *work, size_t off, uint16_t v) { - endian.wr16be(FLOW_EXPORT_CTX(work)->buf + off, v); + EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = FLOW_EXPORT_CTX(work)->buf + off, .val = v, + .width = MMGR_ENDIAN_16); } // --------------------------------------------------------------------------- @@ -181,15 +182,16 @@ void protocore_flow_export_v5_header(uint8_t *work) return; } size_t p = 0; - p += endian.wr16be(buf + p, FLOW_V5_VERSION); - p += endian.wr16be(buf + p, h->count); - p += endian.wr32be(buf + p, h->sys_uptime); - p += endian.wr32be(buf + p, h->unix_secs); - p += endian.wr32be(buf + p, h->unix_nsecs); - p += endian.wr32be(buf + p, h->flow_sequence); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = FLOW_V5_VERSION, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = h->count, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = h->sys_uptime, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = h->unix_secs, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = h->unix_nsecs, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = h->flow_sequence, .width = MMGR_ENDIAN_32); buf[p++] = h->engine_type; buf[p++] = h->engine_id; - p += endian.wr16be(buf + p, h->sampling_interval); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = h->sampling_interval, + .width = MMGR_ENDIAN_16); FlowExportV.n = p; // 24 FlowExportV.ok = PROTO_TRUE; } @@ -206,23 +208,23 @@ void protocore_flow_export_v5_record(uint8_t *work) return; } size_t p = 0; - p += endian.wr32be(buf + p, r->src_addr); - p += endian.wr32be(buf + p, r->dst_addr); - p += endian.wr32be(buf + p, r->next_hop); - p += endian.wr16be(buf + p, r->input); - p += endian.wr16be(buf + p, r->output); - p += endian.wr32be(buf + p, r->d_pkts); - p += endian.wr32be(buf + p, r->d_octets); - p += endian.wr32be(buf + p, r->first); - p += endian.wr32be(buf + p, r->last); - p += endian.wr16be(buf + p, r->src_port); - p += endian.wr16be(buf + p, r->dst_port); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->src_addr, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->dst_addr, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->next_hop, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->input, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->output, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->d_pkts, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->d_octets, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->first, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->last, .width = MMGR_ENDIAN_32); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->src_port, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->dst_port, .width = MMGR_ENDIAN_16); buf[p++] = 0; // pad1 buf[p++] = r->tcp_flags; buf[p++] = r->prot; buf[p++] = r->tos; - p += endian.wr16be(buf + p, r->src_as); - p += endian.wr16be(buf + p, r->dst_as); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->src_as, .width = MMGR_ENDIAN_16); + p += EMBED_CALL(magna_extremitas.wr, EndianCfg, .dst = buf + p, .val = r->dst_as, .width = MMGR_ENDIAN_16); buf[p++] = r->src_mask; buf[p++] = r->dst_mask; buf[p++] = 0; // pad2, two octets diff --git a/src/services/net/snmp/snmp_crypto/CMakeLists.txt b/src/services/net/snmp/snmp_crypto/CMakeLists.txt index d5b7bf2bb..73ba3f1ca 100644 --- a/src/services/net/snmp/snmp_crypto/CMakeLists.txt +++ b/src/services/net/snmp/snmp_crypto/CMakeLists.txt @@ -7,7 +7,5 @@ protocore_add_module(services/net/snmp/snmp_crypto PRIVATE_DEPS crypto/cipher/aes_sbox crypto/hash/sha256 - mmgr/protomem - mmgr/protostr - mmgr/secure + mmgr ) diff --git a/src/services/net/snmp/snmp_crypto/snmp_crypto.c b/src/services/net/snmp/snmp_crypto/snmp_crypto.c index 47d37ecef..d782a3b07 100644 --- a/src/services/net/snmp/snmp_crypto/snmp_crypto.c +++ b/src/services/net/snmp/snmp_crypto/snmp_crypto.c @@ -10,13 +10,13 @@ #if PROTOCORE_ENABLE_SNMP_V3 -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" -#include "mmgr/secure/secure.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "services/net/snmp/snmp_crypto/snmp_crypto.h" #include "crypto/cipher/aes_sbox/aes_sbox.h" #include "crypto/hash/sha256/sha256.h" +#include "locus_carcerum/locus_carcerum.h" // mmgr_zero_buf: the wipe the compiler cannot drop PROTOCORE_BEGIN_DECLS @@ -38,12 +38,13 @@ void protocore_snmp_crypto_localize_key(uint8_t *work) (void)work; const char *password = SnmpCryptoV.key.password; uint8_t *key_out = SnmpCryptoV.key.out; - size_t pwlen = password ? str.len(password, PROTOCORE_SNMP_USM_PASS_MAX) : 0; + size_t pwlen = + password ? EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = password, .cap = PROTOCORE_SNMP_USM_PASS_MAX) : 0; if (pwlen == 0 || key_out == NULL) { if (key_out != NULL) { - mem.set(key_out, 0, SNMP_USM_KEY_LEN); + EMBED_CALL(memor.set, MemoriaCfg, .dst = key_out, .val = 0, .bytes = SNMP_USM_KEY_LEN); } SnmpCryptoV.ok = PROTO_FALSE; return; @@ -75,8 +76,8 @@ void protocore_snmp_crypto_localize_key(uint8_t *work) Sha256.update(sha, ku, SNMP_USM_KEY_LEN); Sha256.final(sha, key_out); - protocore_secure_wipe(ku, sizeof(ku)); - protocore_secure_wipe(block, sizeof(block)); + mmgr_zero_buf(ku, sizeof(ku)); + mmgr_zero_buf(block, sizeof(block)); SnmpCryptoV.ok = PROTO_TRUE; } @@ -91,11 +92,11 @@ static const uint8_t kRcon[10] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 // Expand a 128-bit key into 11 round keys (44 words). static void aes128_key_schedule(const uint8_t key[16], uint8_t rk[176]) { - mem.cpy(rk, key, 16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = rk, .src = key, .bytes = 16); for (int i = 4; i < 44; i++) { uint8_t t[4]; - mem.cpy(t, rk + (i - 1) * 4, 4); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = t, .src = rk + (i - 1) * 4, .bytes = 4); if (i % 4 == 0) { uint8_t tmp = t[0]; // RotWord @@ -143,7 +144,7 @@ static void aes128_encrypt_block(const uint8_t rk[176], const uint8_t in[16], ui t[r + 4 * c] = s[r + 4 * ((c + r) % 4)]; } } - mem.cpy(s, t, 16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = s, .src = t, .bytes = 16); // MixColumns, skipped in the final round if (round != 10) @@ -168,7 +169,7 @@ static void aes128_encrypt_block(const uint8_t rk[176], const uint8_t in[16], ui s[i] ^= rk[round * 16 + i]; } } - mem.cpy(out, s, 16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = s, .bytes = 16); } // CFB128: each block of input is XORed with the cipher applied to the feedback register, and the @@ -190,7 +191,7 @@ void protocore_snmp_crypto_aes_cfb128(uint8_t *work) uint8_t rk[176]; aes128_key_schedule(SnmpCryptoV.priv.key, rk); uint8_t fb[16]; - mem.cpy(fb, SnmpCryptoV.priv.iv, 16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = fb, .src = SnmpCryptoV.priv.iv, .bytes = 16); uint8_t ks[16]; size_t off = 0; @@ -222,14 +223,14 @@ void protocore_snmp_crypto_aes_cfb128(uint8_t *work) } if (bl == 16) { - mem.cpy(fb, cipher, 16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = fb, .src = cipher, .bytes = 16); } off += bl; } - protocore_secure_wipe(rk, sizeof(rk)); - protocore_secure_wipe(ks, sizeof(ks)); - protocore_secure_wipe(fb, sizeof(fb)); + mmgr_zero_buf(rk, sizeof(rk)); + mmgr_zero_buf(ks, sizeof(ks)); + mmgr_zero_buf(fb, sizeof(fb)); SnmpCryptoV.ok = PROTO_TRUE; } diff --git a/src/services/radio/ble_gatt/CMakeLists.txt b/src/services/radio/ble_gatt/CMakeLists.txt index d77f6eb52..2c23d0cb1 100644 --- a/src/services/radio/ble_gatt/CMakeLists.txt +++ b/src/services/radio/ble_gatt/CMakeLists.txt @@ -5,7 +5,6 @@ protocore_add_module(services/radio/ble_gatt GATE PROTOCORE_ENABLE_BLE_GATT SOURCES ble_gatt.c PRIVATE_DEPS - mmgr/membuild - mmgr/protomem + mmgr shared/hex ) diff --git a/src/services/radio/ble_gatt/ble_gatt.c b/src/services/radio/ble_gatt/ble_gatt.c index 544205f29..6c4f39812 100644 --- a/src/services/radio/ble_gatt/ble_gatt.c +++ b/src/services/radio/ble_gatt/ble_gatt.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_BLE_GATT -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/radio/ble_gatt/ble_gatt.h" -#include "shared/hex/hex.h" // PROTOCORE_HEX: the shared digit tables +#include "shared/hex/hex.h" // PROTOCORE_HEX: the shared digit tables +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain // --- the entries ----------------------------------------------------------- @@ -45,7 +45,7 @@ size_t protocore_ble_gatt_att_read_rsp(uint8_t *work, const uint8_t *val, size_t out[0] = ATT_OP_READ_RSP; if (vlen) { - mem.cpy(out + 1, val, vlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 1, .src = val, .bytes = vlen); } return 1 + vlen; } @@ -61,7 +61,7 @@ static size_t att_handle_value(uint8_t op, uint16_t handle, const uint8_t *val, out[2] = (uint8_t)(handle >> 8); if (vlen) { - mem.cpy(out + 3, val, vlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 3, .src = val, .bytes = vlen); } return 3 + vlen; } @@ -157,19 +157,19 @@ proto_bool protocore_ble_gatt_att_parse(uint8_t *work, const uint8_t *pdu, size_ return PROTO_TRUE; default: ok = PROTO_TRUE; // unknown opcode: still report it, no fixed fields - return ok; + break; } return ok; } -static void put_hex16(protocore_sb *b, uint16_t v) +static size_t put_hex16(char *out, size_t cap, size_t at, uint16_t v) { char t[7] = "0x0000"; for (int i = 0; i < 4; i++) { t[2 + i] = PROTOCORE_HEX.lower[(v >> ((3 - i) * 4)) & 0xF]; } - Sb.put(b, t); + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = t); } size_t protocore_ble_gatt_char_json(uint8_t *work, const GattChar *chars, size_t n, char *out, size_t cap) @@ -180,29 +180,29 @@ size_t protocore_ble_gatt_char_json(uint8_t *work, const GattChar *chars, size_t { return 0; } - protocore_sb b = {out, cap, 0, PROTO_TRUE}; - Sb.put(&b, "["); + size_t b = 0; + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "["); for (size_t i = 0; i < n; i++) { if (i) { - Sb.put(&b, ","); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ","); } - Sb.put(&b, "{\"handle\":"); - Sb.u32(&b, chars[i].handle); - Sb.put(&b, ",\"uuid\":\""); - put_hex16(&b, chars[i].uuid); - Sb.put(&b, "\",\"props\":"); - Sb.u32(&b, chars[i].props); - Sb.put(&b, "}"); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "{\"handle\":"); + b = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = b, .val = chars[i].handle); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = ",\"uuid\":\""); + b = put_hex16(out, cap, b, chars[i].uuid); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "\",\"props\":"); + b = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = b, .val = chars[i].props); + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "}"); } - Sb.put(&b, "]"); - if (!b.ok) + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = "]"); + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = b)) { return 0; } - out[b.len] = '\0'; - return b.len; + out[b] = '\0'; + return b; } #endif // PROTOCORE_ENABLE_BLE_GATT diff --git a/src/services/radio/enocean/CMakeLists.txt b/src/services/radio/enocean/CMakeLists.txt index e6a08cb2a..758ac5fd5 100644 --- a/src/services/radio/enocean/CMakeLists.txt +++ b/src/services/radio/enocean/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(services/radio/enocean GATE PROTOCORE_ENABLE_ENOCEAN SOURCES enocean.c PRIVATE_DEPS - mmgr/protomem + mmgr shared/crc ) diff --git a/src/services/radio/enocean/enocean.c b/src/services/radio/enocean/enocean.c index a4dcc37c2..c623006b2 100644 --- a/src/services/radio/enocean/enocean.c +++ b/src/services/radio/enocean/enocean.c @@ -13,7 +13,7 @@ #if PROTOCORE_ENABLE_ENOCEAN -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/radio/enocean/enocean.h" #include "shared/crc/crc.h" // PROTOCORE_CRC8_SMBUS @@ -157,7 +157,7 @@ uint16_t protocore_enocean_erp1_build(uint8_t *work, uint8_t *out, uint16_t cap, out[p++] = rorg; if (payload_len) { - mem.cpy(out + p, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + p, .src = payload, .bytes = payload_len); p = (uint16_t)(p + payload_len); } out[p++] = (uint8_t)(sender_id >> 24); // 4-octet sender id, big-endian diff --git a/src/services/radio/espnow/CMakeLists.txt b/src/services/radio/espnow/CMakeLists.txt index 975fd7463..6fc7db0be 100644 --- a/src/services/radio/espnow/CMakeLists.txt +++ b/src/services/radio/espnow/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(services/radio/espnow GATE PROTOCORE_ENABLE_ESPNOW SOURCES espnow.c PRIVATE_DEPS - mmgr/plaintext - mmgr/protomem + mmgr + server/core/worker ) diff --git a/src/services/radio/espnow/espnow.c b/src/services/radio/espnow/espnow.c index a586aeeba..64a1ee84b 100644 --- a/src/services/radio/espnow/espnow.c +++ b/src/services/radio/espnow/espnow.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_ESPNOW -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "services/radio/espnow/espnow.h" PROTOCORE_BEGIN_DECLS @@ -43,7 +43,7 @@ uint8_t *protocore_espnow_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_ESPNOW_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_ESPNOW_BORROW); } return s_own.span; } @@ -72,7 +72,7 @@ void protocore_espnow_encode(uint8_t *work) out[2] = (uint8_t)len; if (len && payload) { - mem.cpy(out + PROTOCORE_ESPNOW_HDR, payload, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + PROTOCORE_ESPNOW_HDR, .src = payload, .bytes = len); } EspnowV.n = len + PROTOCORE_ESPNOW_HDR; } @@ -140,8 +140,8 @@ static_assert(ESPNOW_OFF_CTX + sizeof(EspnowCtx) <= PROTOCORE_ESPNOW_BORROW, "PROTOCORE_ESPNOW_BORROW is short of the module context - raise it in protocore_config.h, which" " sums it into its arena"); -// A region reached through a cast is only aligned if its OFFSET is: the arena aligns the base up to -// PROTOCORE_ARENA_MAX_ALIGN, so a borrow is met by aligning its offset alone. Both sides are +// A region reached through a cast is only aligned if its OFFSET is: a cellblock hands out cells on +// MMGR_CARCER_ALIGN boundaries, so a borrow is met by aligning its offset alone. Both sides are // compile-time constants, so this is a compile-time claim rather than a runtime branch. The size // assert above bounds the far end of the chain and says nothing about where a region begins. static_assert(ESPNOW_OFF_CTX % _Alignof(EspnowCtx) == 0, @@ -155,7 +155,8 @@ static int peer_find(const EspnowCtx *c, const uint8_t mac[6]) { for (int i = 0; i < PROTOCORE_ESPNOW_MAX_PEERS; i++) { - if (c->peers[i].used && mem.cmp(c->peers[i].mac, mac, 6) == 0) + if (c->peers[i].used && + EMBED_CALL(memor.cmp, MemoriaCfg, .src = c->peers[i].mac, .other = mac, .bytes = 6) == 0) { return i; } @@ -189,7 +190,7 @@ void protocore_espnow_peer_add(uint8_t *work) { if (!ESPNOW_CTX(work)->peers[i].used) { - mem.cpy(ESPNOW_CTX(work)->peers[i].mac, mac, 6); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = ESPNOW_CTX(work)->peers[i].mac, .src = mac, .bytes = 6); ESPNOW_CTX(work)->peers[i].used = PROTO_TRUE; EspnowV.ok = PROTO_TRUE; return; @@ -273,8 +274,8 @@ static void on_recv(const uint8_t *mac, const uint8_t *data, int len) static proto_bool radio_add_peer(const uint8_t mac[6], uint8_t channel) { esp_now_peer_info_t p; - mem.set(&p, 0, sizeof(p)); - mem.cpy(p.peer_addr, mac, 6); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &p, .val = 0, .bytes = sizeof(p)); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = p.peer_addr, .src = mac, .bytes = 6); p.channel = channel; p.encrypt = PROTO_FALSE; if (esp_now_is_peer_exist(mac)) diff --git a/src/services/radio/radio_sniff/CMakeLists.txt b/src/services/radio/radio_sniff/CMakeLists.txt index c1e35768e..f46050bd2 100644 --- a/src/services/radio/radio_sniff/CMakeLists.txt +++ b/src/services/radio/radio_sniff/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(services/radio/radio_sniff GATE PROTOCORE_ENABLE_RADIO_SNIFF SOURCES radio_sniff.c PRIVATE_DEPS - mmgr/endian + mmgr shared/pcap ) diff --git a/src/services/radio/radio_sniff/radio_sniff.c b/src/services/radio/radio_sniff/radio_sniff.c index 99a696c1c..194712abb 100644 --- a/src/services/radio/radio_sniff/radio_sniff.c +++ b/src/services/radio/radio_sniff/radio_sniff.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_RADIO_SNIFF -#include "mmgr/endian/endian.h" +#include "endian/endian.h" #include "services/radio/radio_sniff/radio_sniff.h" #include "shared/pcap/pcap.h" @@ -85,16 +85,16 @@ size_t protocore_radio_sniff_tap_record(uint8_t *work, uint8_t *out, size_t cap, // 802.15.4 TAP header: version(1)=0, reserved(1)=0, length(2 LE) = whole TAP block. p[0] = 0; p[1] = 0; - endian.wr16le(p + 2, RADIO_SNIFF_TAP_LEN); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = p + 2, .val = RADIO_SNIFF_TAP_LEN, .width = MMGR_ENDIAN_16); // TLV: Received Signal Strength (type 1, len 4), float32 dBm. - endian.wr16le(p + 4, 1); - endian.wr16le(p + 6, 4); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = p + 4, .val = 1, .width = MMGR_ENDIAN_16); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = p + 6, .val = 4, .width = MMGR_ENDIAN_16); uint32_t radio_sniff_u32 = RadioSniff.i2f32(work, rssi_dbm); - endian.wr32le(p + 8, radio_sniff_u32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = p + 8, .val = radio_sniff_u32, .width = MMGR_ENDIAN_32); // TLV: Channel Assignment (type 3, len 3 -> padded to 4): channel number(2 LE) + page(1). - endian.wr16le(p + 12, 3); - endian.wr16le(p + 14, 3); - endian.wr16le(p + 16, channel); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = p + 12, .val = 3, .width = MMGR_ENDIAN_16); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = p + 14, .val = 3, .width = MMGR_ENDIAN_16); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = p + 16, .val = channel, .width = MMGR_ENDIAN_16); p[18] = 0; // channel page 0 p[19] = 0; // pad diff --git a/src/services/security/totp/CMakeLists.txt b/src/services/security/totp/CMakeLists.txt index 4995cf6e4..3f11de4f2 100644 --- a/src/services/security/totp/CMakeLists.txt +++ b/src/services/security/totp/CMakeLists.txt @@ -6,7 +6,6 @@ protocore_add_module(services/security/totp SOURCES totp.c PRIVATE_DEPS crypto/hash/sha1 - mmgr/protomem - mmgr/secure - mmgr/span + mmgr + server/core/worker ) diff --git a/src/services/security/totp/totp.c b/src/services/security/totp/totp.c index a045e715a..cfc88c35f 100644 --- a/src/services/security/totp/totp.c +++ b/src/services/security/totp/totp.c @@ -15,12 +15,11 @@ #if PROTOCORE_ENABLE_TOTP -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/security/totp/totp.h" #include "crypto/hash/sha1/sha1.h" -#include "mmgr/secure/secure.h" // the pool the digest borrow comes from -#include "mmgr/span/span.h" // protocore_span, span.ok +#include "server/core/worker/worker.h" // the cellblock guards the temporary borrows go through PROTOCORE_BEGIN_DECLS @@ -44,13 +43,14 @@ static uint32_t pow10u(uint8_t n) // One SHA-1 over the caller's bytes, out of a pool borrow taken and released per digest. static void sha1_of(const uint8_t *data, size_t len, uint8_t out[PROTOCORE_SHA1_DIGEST_LEN]) { - const size_t mark = protocore_secure_mark(); - protocore_span w = protocore_secure_span(PROTOCORE_SHA1_BORROW, 8); - if (span.ok(w)) + const MaximumSecurityGuard *const secure_guard = protocore_secure_guard(); + const size_t mark = secure_guard->temporary_buf_mark(); + uint8_t *w = (uint8_t *)secure_guard->temporary_buf_alloc(PROTOCORE_SHA1_BORROW); + if (w) { - Sha1.hash(w.buf, data, len, out); + Sha1.hash(w, data, len, out); } - protocore_secure_release(mark); + secure_guard->temporary_buf_release(mark); } // RFC 2104 sec 2 H(K XOR opad, H(K XOR ipad, text)) with text the 8-byte counter C: K is zero-padded @@ -63,11 +63,11 @@ static void hmac_sha1_counter(const uint8_t *key, size_t keylen, const uint8_t c { uint8_t kh[PROTOCORE_SHA1_DIGEST_LEN]; sha1_of(key, keylen, kh); - mem.cpy(k, kh, PROTOCORE_SHA1_DIGEST_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = k, .src = kh, .bytes = PROTOCORE_SHA1_DIGEST_LEN); } else { - mem.cpy(k, key, keylen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = k, .src = key, .bytes = keylen); } uint8_t inner_in[PROTOCORE_TOTP_HMAC_B + PROTOCORE_TOTP_C_LEN]; @@ -75,7 +75,7 @@ static void hmac_sha1_counter(const uint8_t *key, size_t keylen, const uint8_t c { inner_in[i] = k[i] ^ 0x36; // ipad } - mem.cpy(inner_in + PROTOCORE_TOTP_HMAC_B, c, PROTOCORE_TOTP_C_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = inner_in + PROTOCORE_TOTP_HMAC_B, .src = c, .bytes = PROTOCORE_TOTP_C_LEN); uint8_t inner[PROTOCORE_SHA1_DIGEST_LEN]; sha1_of(inner_in, sizeof(inner_in), inner); @@ -84,7 +84,8 @@ static void hmac_sha1_counter(const uint8_t *key, size_t keylen, const uint8_t c { outer_in[i] = k[i] ^ 0x5c; // opad } - mem.cpy(outer_in + PROTOCORE_TOTP_HMAC_B, inner, PROTOCORE_SHA1_DIGEST_LEN); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = outer_in + PROTOCORE_TOTP_HMAC_B, .src = inner, + .bytes = PROTOCORE_SHA1_DIGEST_LEN); sha1_of(outer_in, sizeof(outer_in), out); } diff --git a/src/services/southbound/southbound/CMakeLists.txt b/src/services/southbound/southbound/CMakeLists.txt index f53dd72de..3f5f039d7 100644 --- a/src/services/southbound/southbound/CMakeLists.txt +++ b/src/services/southbound/southbound/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(services/southbound/southbound GATE PROTOCORE_ENABLE_SOUTHBOUND SOURCES southbound.c PRIVATE_DEPS - mmgr/plaintext - mmgr/protostr + mmgr + server/core/worker ) diff --git a/src/services/southbound/southbound/southbound.c b/src/services/southbound/southbound/southbound.c index cf07feb62..ca4df7e82 100644 --- a/src/services/southbound/southbound/southbound.c +++ b/src/services/southbound/southbound/southbound.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_SOUTHBOUND -#include "mmgr/plaintext/plaintext.h" // the persistent end this module's state is taken from -#include "mmgr/protostr/protostr.h" // str.eq: the driver registry name lookup +#include "cellularum_laboro/cellularum_laboro.h" // cellul.eq: the driver registry name lookup +#include "server/core/worker/worker.h" // the cellblock this module's state is taken from #include "services/southbound/southbound/southbound.h" PROTOCORE_BEGIN_DECLS @@ -57,7 +57,7 @@ uint8_t *protocore_southbound_span(void) { if (s_own.span == NULL) { - s_own.span = protocore_plaintext_persist_span(PROTOCORE_SOUTHBOUND_BORROW).buf; + s_own.span = (uint8_t *)protocore_plain_persist(PROTOCORE_SOUTHBOUND_BORROW); } return s_own.span; } @@ -81,7 +81,8 @@ static const SouthboundDriver *lookup(const struct SouthboundStorage *store, con for (size_t i = 0; i < store->count; i++) { if (store->drivers[i] && store->drivers[i]->name && - str.eq(store->drivers[i]->name, name, MAX_KEY_LEN, PROTO_FALSE)) + EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = store->drivers[i]->name, .other = name, .cap = MAX_KEY_LEN, + .ci = PROTO_FALSE)) { return store->drivers[i]; } diff --git a/src/services/storage/sqlite/sqlite_format/CMakeLists.txt b/src/services/storage/sqlite/sqlite_format/CMakeLists.txt index ebdf31b6b..bc81f68f9 100644 --- a/src/services/storage/sqlite/sqlite_format/CMakeLists.txt +++ b/src/services/storage/sqlite/sqlite_format/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/storage/sqlite/sqlite_format GATE PROTOCORE_ENABLE_SQLITE SOURCES sqlite_format.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/storage/sqlite/sqlite_format/sqlite_format.c b/src/services/storage/sqlite/sqlite_format/sqlite_format.c index 8316f0f8f..764c90eb6 100644 --- a/src/services/storage/sqlite/sqlite_format/sqlite_format.c +++ b/src/services/storage/sqlite/sqlite_format/sqlite_format.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_SQLITE -#include "mmgr/protomem/protomem.h" -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" +#include "memoria_operor/memoria_operor.h" #include "services/storage/sqlite/sqlite_format/sqlite_format.h" PROTOCORE_BEGIN_DECLS @@ -93,7 +93,7 @@ uint64_t protocore_sqlite_serial_type_size(uint64_t t) proto_bool protocore_sqlite_parse_db_header(const uint8_t *buf, size_t len, SqliteDbHeader *out) { - if (len < 100 || mem.cmp(buf, SQLITE_MAGIC, 16) != 0) + if (len < 100 || EMBED_CALL(memor.cmp, MemoriaCfg, .src = buf, .other = SQLITE_MAGIC, .bytes = 16) != 0) { return PROTO_FALSE; } @@ -230,7 +230,7 @@ proto_bool protocore_sqlite_read_payload(SqlitePageReader read, void *ctx, uint3 return PROTO_FALSE; } - mem.cpy(out, leaf_page + cell->local_off, cell->local_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = leaf_page + cell->local_off, .bytes = cell->local_len); uint32_t got = cell->local_len; if (!cell->has_overflow) { @@ -279,7 +279,7 @@ proto_bool protocore_sqlite_read_payload(SqlitePageReader read, void *ctx, uint3 { return PROTO_FALSE; } - mem.cpy(out + got, work_page + 4, chunk); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + got, .src = work_page + 4, .bytes = chunk); got += chunk; next = nnext; } @@ -372,7 +372,8 @@ double protocore_sqlite_column_float(const uint8_t *val, uint32_t val_len) u = (u << 8) | val[i]; } double d = 0.0; - mem.cpy(&d, &u, 8); // u holds the big-endian-read IEEE-754 bit pattern as a native u64 + // u holds the big-endian-read IEEE-754 bit pattern as a native u64 + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &d, .src = &u, .bytes = 8); return d; } @@ -415,7 +416,7 @@ static proto_bool cursor_descend(SqliteTableCursor *c, uint32_t pgno) } if (h.type == SQLITE_BTREE_LEAF_TABLE) { - mem.cpy(c->leaf, c->work, c->page_size); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = c->leaf, .src = c->work, .bytes = c->page_size); c->leaf_hdr = h; c->leaf_off = (uint32_t)off; c->leaf_pgno = pgno; @@ -671,14 +672,14 @@ static uint32_t write_value(const SqliteValue *v, uint64_t st, uint32_t vlen, ui { if (vlen) { - mem.cpy(out, v->data, vlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = v->data, .bytes = vlen); } return vlen; } if (v->type == SQLITE_COL_FLOAT) { uint64_t u = 0; - mem.cpy(&u, &v->f, 8); // native bit pattern -> emit big-endian + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &u, .src = &v->f, .bytes = 8); // native bit pattern -> emit big-endian for (int i = 7; i >= 0; i--) { *out++ = (uint8_t)(u >> (i * 8)); @@ -884,10 +885,10 @@ uint32_t protocore_sqlite_build_table_db(uint32_t page_size, const char *table_n return 0; } - mem.set(out, 0, (size_t)page_size * 2); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = (size_t)page_size * 2); // --- Page 1: the 100-byte database header --- - mem.cpy(out, SQLITE_MAGIC, 16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = SQLITE_MAGIC, .bytes = 16); wr_be16(out + 16, (uint16_t)(page_size == 65536 ? 1 : page_size)); out[18] = 1; // write version (legacy) out[19] = 1; // read version (legacy) @@ -904,8 +905,8 @@ uint32_t protocore_sqlite_build_table_db(uint32_t page_size, const char *table_n wr_be32(out + 96, 3046001); // SQLITE_VERSION_NUMBER that wrote the file // --- Page 1: the protocore_sqlite_schema row for our table (type,name,tbl_name,rootpage,sql) --- - uint32_t name_len = (uint32_t)str.len(table_name, out_cap); - uint32_t sql_len = (uint32_t)str.len(create_sql, out_cap); + uint32_t name_len = (uint32_t)EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = table_name, .cap = out_cap); + uint32_t sql_len = (uint32_t)EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = create_sql, .cap = out_cap); SqliteValue master[5]; master[0] = (SqliteValue){SQLITE_COL_TEXT, 0, 0, (const uint8_t *)"table", 5}; master[1] = (SqliteValue){SQLITE_COL_TEXT, 0, 0, (const uint8_t *)table_name, name_len}; diff --git a/src/services/storage/wal/wal/CMakeLists.txt b/src/services/storage/wal/wal/CMakeLists.txt index 82a53ae60..996e8bada 100644 --- a/src/services/storage/wal/wal/CMakeLists.txt +++ b/src/services/storage/wal/wal/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/storage/wal/wal GATE PROTOCORE_ENABLE_WAL SOURCES wal.c PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/services/storage/wal/wal/wal.c b/src/services/storage/wal/wal/wal.c index 3e4b4e0f0..d1bacd9fc 100644 --- a/src/services/storage/wal/wal/wal.c +++ b/src/services/storage/wal/wal/wal.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_WAL -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/storage/wal/wal/wal.h" -#include "mmgr/endian/endian.h" +#include "endian/endian.h" PROTOCORE_BEGIN_DECLS @@ -87,16 +87,16 @@ size_t protocore_wal_record_encode(uint8_t *out, size_t cap, uint64_t seq, const { return 0; } - endian.wr32le(out + 0, WAL_MAGIC); - endian.wr64le(out + 4, seq); - endian.wr32le(out + 12, len); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 0, .val = WAL_MAGIC, .width = MMGR_ENDIAN_32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 4, .val = seq, .width = MMGR_ENDIAN_64); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 12, .val = len, .width = MMGR_ENDIAN_32); // crc over the 16 header bytes (magic+seq+len) then the payload uint32_t crc = crc32_step(0xFFFFFFFFu, out, 16); crc = crc32_step(crc, payload, len) ^ 0xFFFFFFFFu; - endian.wr32le(out + 16, crc); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 16, .val = crc, .width = MMGR_ENDIAN_32); if (len) { - mem.cpy(out + WAL_RECORD_HEADER, payload, len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + WAL_RECORD_HEADER, .src = payload, .bytes = len); } return need; } @@ -107,13 +107,14 @@ size_t protocore_wal_replay(const uint8_t *img, size_t len, WalRecordCb cb, void while (off + WAL_RECORD_HEADER <= len) { const uint8_t *r = img + off; - if (endian.rd32le(r) != WAL_MAGIC) + if ((uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = r, .width = MMGR_ENDIAN_32) != WAL_MAGIC) { break; // not a record start (end of log or garbage) } - uint64_t seq = endian.rd64le(r + 4); - uint32_t plen = endian.rd32le(r + 12); - uint32_t crc_stored = endian.rd32le(r + 16); + uint64_t seq = EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = r + 4, .width = MMGR_ENDIAN_64); + uint32_t plen = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = r + 12, .width = MMGR_ENDIAN_32); + uint32_t crc_stored = + (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = r + 16, .width = MMGR_ENDIAN_32); if (off + (size_t)WAL_RECORD_HEADER + plen > len) { break; // truncated tail (power loss mid-record) diff --git a/src/services/storage/wal/wal_fs/CMakeLists.txt b/src/services/storage/wal/wal_fs/CMakeLists.txt index 21332026a..2c80441f6 100644 --- a/src/services/storage/wal/wal_fs/CMakeLists.txt +++ b/src/services/storage/wal/wal_fs/CMakeLists.txt @@ -4,7 +4,7 @@ protocore_add_module(services/storage/wal/wal_fs HEADER_ONLY DEPS - mmgr/protomem + mmgr server/storage/mnt services/storage/wal/wal_store ) diff --git a/src/services/storage/wal/wal_fs/wal_fs.h b/src/services/storage/wal/wal_fs/wal_fs.h index e01429535..d42d40b65 100644 --- a/src/services/storage/wal/wal_fs/wal_fs.h +++ b/src/services/storage/wal/wal_fs/wal_fs.h @@ -40,7 +40,7 @@ PROTOCORE_BEGIN_DECLS -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "server/storage/mnt/mnt.h" // protocore_mnt_backend - the store the log lives on #include "services/storage/wal/wal_store/wal_store.h" @@ -99,7 +99,7 @@ PROTOCORE_INLINE proto_bool protocore_wal_fs_prealloc(const protocore_mnt_backen return PROTO_FALSE; } uint8_t z[256]; - mem.set(z, 0, sizeof z); + EMBED_CALL(memor.set, MemoriaCfg, .dst = z, .val = 0, .bytes = sizeof z); uint64_t left = size; proto_bool ok = PROTO_TRUE; while (left) diff --git a/src/services/storage/wal/wal_store/CMakeLists.txt b/src/services/storage/wal/wal_store/CMakeLists.txt index bb732759c..5585b270c 100644 --- a/src/services/storage/wal/wal_store/CMakeLists.txt +++ b/src/services/storage/wal/wal_store/CMakeLists.txt @@ -7,6 +7,5 @@ protocore_add_module(services/storage/wal/wal_store DEPS services/storage/wal/wal PRIVATE_DEPS - mmgr/endian - mmgr/protomem + mmgr ) diff --git a/src/services/storage/wal/wal_store/wal_store.c b/src/services/storage/wal/wal_store/wal_store.c index e6700ef7a..2b778637f 100644 --- a/src/services/storage/wal/wal_store/wal_store.c +++ b/src/services/storage/wal/wal_store/wal_store.c @@ -10,10 +10,10 @@ #if PROTOCORE_ENABLE_WAL -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/storage/wal/wal_store/wal_store.h" -#include "mmgr/endian/endian.h" +#include "endian/endian.h" PROTOCORE_BEGIN_DECLS @@ -34,12 +34,13 @@ static proto_bool dev_write(const WalDev *d, uint64_t off, const uint8_t *buf, s static proto_bool write_super(WalStore *s, int ab, uint64_t gen, uint64_t head, uint64_t seq) { uint8_t sb[WAL_SUPER_SIZE]; - mem.set(sb, 0, sizeof(sb)); - endian.wr32le(sb + 0, WAL_SUPER_MAGIC); - endian.wr64le(sb + 4, gen); - endian.wr64le(sb + 12, head); - endian.wr64le(sb + 20, seq); - endian.wr32le(sb + 28, protocore_wal_crc32(sb, SUPER_USED)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = sb, .val = 0, .bytes = sizeof(sb)); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = sb + 0, .val = WAL_SUPER_MAGIC, .width = MMGR_ENDIAN_32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = sb + 4, .val = gen, .width = MMGR_ENDIAN_64); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = sb + 12, .val = head, .width = MMGR_ENDIAN_64); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = sb + 20, .val = seq, .width = MMGR_ENDIAN_64); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = sb + 28, .val = protocore_wal_crc32(sb, SUPER_USED), + .width = MMGR_ENDIAN_32); return dev_write(&s->dev, (uint64_t)ab * WAL_SUPER_SIZE, sb, sizeof(sb)); } @@ -51,17 +52,18 @@ static proto_bool read_super(const WalStore *s, int ab, uint64_t *gen, uint64_t { return PROTO_FALSE; } - if (endian.rd32le(sb + 0) != WAL_SUPER_MAGIC) + if ((uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = sb + 0, .width = MMGR_ENDIAN_32) != WAL_SUPER_MAGIC) { return PROTO_FALSE; } - if (endian.rd32le(sb + 28) != protocore_wal_crc32(sb, SUPER_USED)) + if ((uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = sb + 28, .width = MMGR_ENDIAN_32) != + protocore_wal_crc32(sb, SUPER_USED)) { return PROTO_FALSE; } - *gen = endian.rd64le(sb + 4); - *head = endian.rd64le(sb + 12); - *seq = endian.rd64le(sb + 20); + *gen = EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = sb + 4, .width = MMGR_ENDIAN_64); + *head = EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = sb + 12, .width = MMGR_ENDIAN_64); + *seq = EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = sb + 20, .width = MMGR_ENDIAN_64); // A head past the data region is corruption a matching CRC cannot happen for, but guard anyway. if (*head > s->data_cap) { @@ -87,13 +89,14 @@ static void protocore_wal_replay_tail(WalStore *s) { break; } - if (endian.rd32le(hdr + 0) != WAL_MAGIC) + if ((uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = hdr + 0, .width = MMGR_ENDIAN_32) != WAL_MAGIC) { break; } - uint64_t seq = endian.rd64le(hdr + 4); - uint32_t plen = endian.rd32le(hdr + 12); - uint32_t crc_stored = endian.rd32le(hdr + 16); + uint64_t seq = EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = hdr + 4, .width = MMGR_ENDIAN_64); + uint32_t plen = (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = hdr + 12, .width = MMGR_ENDIAN_32); + uint32_t crc_stored = + (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = hdr + 16, .width = MMGR_ENDIAN_32); if (off + (uint64_t)WAL_RECORD_HEADER + plen > s->data_cap) { break; // truncated tail @@ -133,7 +136,7 @@ proto_bool protocore_wal_store_format(WalStore *s, const WalDev *dev) { return PROTO_FALSE; } - mem.set(s, 0, sizeof(*s)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = s, .val = 0, .bytes = sizeof(*s)); s->dev = *dev; s->data_off = WAL_DATA_OFFSET; s->data_cap = dev->size - WAL_DATA_OFFSET; @@ -144,7 +147,7 @@ proto_bool protocore_wal_store_format(WalStore *s, const WalDev *dev) s->ab = 0; // Invalidate copy B, then commit copy A as the live generation-1 superblock. uint8_t zero[WAL_SUPER_SIZE]; - mem.set(zero, 0, sizeof(zero)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = zero, .val = 0, .bytes = sizeof(zero)); if (!dev_write(&s->dev, (uint64_t)1 * WAL_SUPER_SIZE, zero, sizeof(zero))) { return PROTO_FALSE; @@ -162,7 +165,7 @@ proto_bool protocore_wal_store_mount(WalStore *s, const WalDev *dev) { return PROTO_FALSE; } - mem.set(s, 0, sizeof(*s)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = s, .val = 0, .bytes = sizeof(*s)); s->dev = *dev; s->data_off = WAL_DATA_OFFSET; s->data_cap = dev->size - WAL_DATA_OFFSET; @@ -211,12 +214,13 @@ proto_bool protocore_wal_store_append(WalStore *s, const uint8_t *payload, uint3 } // Assemble the 20-byte header (magic+seq+len+crc); CRC covers header + payload without buffering both. uint8_t hdr[WAL_RECORD_HEADER]; - endian.wr32le(hdr + 0, WAL_MAGIC); - endian.wr64le(hdr + 4, s->next_seq); - endian.wr32le(hdr + 12, len); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = hdr + 0, .val = WAL_MAGIC, .width = MMGR_ENDIAN_32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = hdr + 4, .val = s->next_seq, .width = MMGR_ENDIAN_64); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = hdr + 12, .val = len, .width = MMGR_ENDIAN_32); uint32_t crc = protocore_wal_crc32_update(protocore_wal_crc32_init(), hdr, 16); crc = protocore_wal_crc32_update(crc, payload, len); - endian.wr32le(hdr + 16, protocore_wal_crc32_final(crc)); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = hdr + 16, .val = protocore_wal_crc32_final(crc), + .width = MMGR_ENDIAN_32); uint64_t at = s->data_off + s->head; if (!dev_write(&s->dev, at, hdr, WAL_RECORD_HEADER)) @@ -270,11 +274,12 @@ size_t protocore_wal_store_scan(WalStore *s, WalStoreRecordCb cb, void *ctx, uin { break; } - if (endian.rd32le(scratch) != WAL_MAGIC) + if ((uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = scratch, .width = MMGR_ENDIAN_32) != WAL_MAGIC) { break; } - uint32_t plen = endian.rd32le(scratch + 12); + uint32_t plen = + (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = scratch + 12, .width = MMGR_ENDIAN_32); size_t total = (size_t)WAL_RECORD_HEADER + plen; if (off + total > s->head || total > scratch_len) { @@ -286,13 +291,15 @@ size_t protocore_wal_store_scan(WalStore *s, WalStoreRecordCb cb, void *ctx, uin } uint32_t crc = protocore_wal_crc32_update(protocore_wal_crc32_init(), scratch, 16); crc = protocore_wal_crc32_update(crc, scratch + WAL_RECORD_HEADER, plen); - if (protocore_wal_crc32_final(crc) != endian.rd32le(scratch + 16)) + if (protocore_wal_crc32_final(crc) != + (uint32_t)EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = scratch + 16, .width = MMGR_ENDIAN_32)) { break; } if (cb) { - cb(endian.rd64le(scratch + 4), off, scratch + WAL_RECORD_HEADER, plen, ctx); + cb(EMBED_CALL(parva_extremitas.rd, EndianCfg, .src = scratch + 4, .width = MMGR_ENDIAN_64), off, + scratch + WAL_RECORD_HEADER, plen, ctx); } count++; off += total; diff --git a/src/services/system/control/CMakeLists.txt b/src/services/system/control/CMakeLists.txt index a9e95e137..97eaee957 100644 --- a/src/services/system/control/CMakeLists.txt +++ b/src/services/system/control/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/system/control GATE PROTOCORE_ENABLE_CONTROL SOURCES control.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/system/control/control.c b/src/services/system/control/control.c index 1392091a2..c0667481d 100644 --- a/src/services/system/control/control.c +++ b/src/services/system/control/control.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_CONTROL -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/system/control/control.h" PROTOCORE_BEGIN_DECLS @@ -174,7 +174,8 @@ static size_t put_u32le(uint8_t *p, uint32_t v) static size_t put_f32le(uint8_t *p, float v) { uint32_t u; - mem.cpy(&u, &v, 4); // reinterpret the IEEE-754 bits, then emit little-endian + // reinterpret the IEEE-754 bits, then emit little-endian + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &u, .src = &v, .bytes = 4); return put_u32le(p, u); } @@ -192,7 +193,7 @@ void protocore_control_pid_log_header(uint8_t *work) return; } size_t o = 0; - mem.cpy(buf, PID_LOG_MAGIC, 4); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf, .src = PID_LOG_MAGIC, .bytes = 4); o += 4; buf[o++] = PID_LOG_VERSION; buf[o++] = 0; // flags (reserved) diff --git a/src/services/timing_position/gnss/gnss_survey/CMakeLists.txt b/src/services/timing_position/gnss/gnss_survey/CMakeLists.txt index f63aa487d..95d72a8eb 100644 --- a/src/services/timing_position/gnss/gnss_survey/CMakeLists.txt +++ b/src/services/timing_position/gnss/gnss_survey/CMakeLists.txt @@ -7,6 +7,5 @@ protocore_add_module(services/timing_position/gnss/gnss_survey DEPS services/timing_position/nmea0183 PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/timing_position/gnss/gnss_survey/gnss_survey.c b/src/services/timing_position/gnss/gnss_survey/gnss_survey.c index 4c91f71ec..c6e866027 100644 --- a/src/services/timing_position/gnss/gnss_survey/gnss_survey.c +++ b/src/services/timing_position/gnss/gnss_survey/gnss_survey.c @@ -10,13 +10,13 @@ #if PROTOCORE_ENABLE_NTRIP_CASTER -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/timing_position/gnss/gnss_survey/gnss_survey.h" PROTOCORE_BEGIN_DECLS #if PROTOCORE_ENABLE_NMEA0183 -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" #include "services/timing_position/nmea0183/nmea0183.h" #endif #include @@ -77,7 +77,7 @@ int64_t protocore_gnss_ecef_m_to_01mm(double metres) void protocore_gnss_survey_reset(GnssSurvey *s) { - mem.set(s, 0, sizeof(*s)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = s, .val = 0, .bytes = sizeof(*s)); } void protocore_gnss_survey_add_ecef(GnssSurvey *s, const GnssEcef *e) @@ -173,7 +173,7 @@ static proto_bool dm_to_deg(const char *field, uint8_t len, double *out) return PROTO_FALSE; } const char *end = field; - double dm = str.to_double(field, &end); + double dm = EMBED_CALL(cellul.to_double, TransfiguroCfg, .src = field, .end = &end); if (end == field) { return PROTO_FALSE; diff --git a/src/services/timing_position/gnss/ntrip_caster/CMakeLists.txt b/src/services/timing_position/gnss/ntrip_caster/CMakeLists.txt index 89889b985..7169b231c 100644 --- a/src/services/timing_position/gnss/ntrip_caster/CMakeLists.txt +++ b/src/services/timing_position/gnss/ntrip_caster/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/timing_position/gnss/ntrip_caster GATE PROTOCORE_ENABLE_NTRIP_CASTER SOURCES ntrip_caster.c PRIVATE_DEPS - mmgr/membuild - mmgr/protomem + mmgr ) diff --git a/src/services/timing_position/gnss/ntrip_caster/ntrip_caster.c b/src/services/timing_position/gnss/ntrip_caster/ntrip_caster.c index a935580c3..ff5ff7259 100644 --- a/src/services/timing_position/gnss/ntrip_caster/ntrip_caster.c +++ b/src/services/timing_position/gnss/ntrip_caster/ntrip_caster.c @@ -10,9 +10,9 @@ #if PROTOCORE_ENABLE_NTRIP_CASTER -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/timing_position/gnss/ntrip_caster/ntrip_caster.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS @@ -57,12 +57,14 @@ static void fmt_deg2(char *out, size_t cap, double v) frac = -frac; } const char *sign = (v < 0.0 && whole == 0) ? "-" : ""; // preserve "-0.xx" - protocore_sb sb_out = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out, sign); - Sb.i64(&sb_out, (int64_t)(whole)); - Sb.put(&sb_out, "."); - Sb.u32w(&sb_out, (uint32_t)(frac), 2); - if (Sb.finish(&sb_out) == 0) + size_t sb_out = 0; + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = sign); + sb_out = + EMBED_CALL(verba_numerus.i64, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, .sval = (int64_t)(whole)); + sb_out = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, .text = "."); + sb_out = EMBED_CALL(verba_numerus.u32w, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out, + .val = (uint32_t)(frac), .min = 2); + if (EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out) == 0) { out[0] = '\0'; } @@ -136,7 +138,7 @@ static void scan_headers(const char *buf, const char *end, NtripRequest *out) proto_bool protocore_ntrip_request_parse(const char *buf, size_t len, NtripRequest *out) { - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); out->version = NTRIP_V1; // Find the end of the request header block (blank line): CRLFCRLF, or bare LFLF as a fallback. @@ -184,7 +186,7 @@ proto_bool protocore_ntrip_request_parse(const char *buf, size_t len, NtripReque { mlen = sizeof(out->mountpoint) - 1; } - mem.cpy(out->mountpoint, mp, mlen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out->mountpoint, .src = mp, .bytes = mlen); out->mountpoint[mlen] = '\0'; } @@ -197,13 +199,15 @@ size_t protocore_ntrip_build_stream_response(char *out, size_t cap, NtripVersion { // One builder, branching only on which response line goes in it: the version picks the text, // not a separate copy of the build-and-check. - protocore_sb sb_out = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out, (version == NTRIP_V2) - ? "HTTP/1.1 200 OK\r\nNtrip-Version: Ntrip/2.0\r\nServer: ProtoCore/2.0\r\nContent-Type: " - "gnss/data\r\nConnection: close\r\n\r\n" - : "ICY 200 OK\r\n\r\n"); - size_t n = Sb.finish(&sb_out); - if (!sb_out.ok) + size_t sb_out = 0; + sb_out = EMBED_CALL( + verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out, + .text = (version == NTRIP_V2) + ? "HTTP/1.1 200 OK\r\nNtrip-Version: Ntrip/2.0\r\nServer: ProtoCore/2.0\r\nContent-Type: " + "gnss/data\r\nConnection: close\r\n\r\n" + : "ICY 200 OK\r\n\r\n"); + size_t n = EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out); + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = sb_out)) { return 0; } @@ -215,16 +219,18 @@ size_t protocore_ntrip_build_error_response(char *out, size_t cap, NtripVersion int n; if (version == NTRIP_V2) { - protocore_sb sb_out4 = {out, cap, 0, PROTO_TRUE}; + size_t sb_out4 = 0; // The mountpoint names no resource the caster serves: RFC 9110 sec 15.5.5. - Sb.put(&sb_out4, "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"); - n = (int)Sb.finish(&sb_out4); + sb_out4 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out4, + .text = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\nConnection: close\r\n\r\n"); + n = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out4); } else { - protocore_sb sb_out5 = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out5, "ERROR - Bad Request\r\n"); - n = (int)Sb.finish(&sb_out5); + size_t sb_out5 = 0; + sb_out5 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out5, + .text = "ERROR - Bad Request\r\n"); + n = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out5); } if (n == 0) // the frame is a fixed literal, so a zero length can only mean it did not fit { @@ -238,16 +244,19 @@ size_t protocore_ntrip_build_unauthorized_response(char *out, size_t cap, NtripV int n; if (version == NTRIP_V2) { - protocore_sb sb_out6 = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out6, "HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"NTRIP\"\r\nContent-Length: " - "0\r\nConnection: close\r\n\r\n"); - n = (int)Sb.finish(&sb_out6); + size_t sb_out6 = 0; + sb_out6 = EMBED_CALL( + verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out6, + .text = "HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: Basic realm=\"NTRIP\"\r\nContent-Length: " + "0\r\nConnection: close\r\n\r\n"); + n = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out6); } else { - protocore_sb sb_out7 = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out7, "ERROR - Bad Password\r\n"); - n = (int)Sb.finish(&sb_out7); + size_t sb_out7 = 0; + sb_out7 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out7, + .text = "ERROR - Bad Password\r\n"); + n = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out7); } if (n == 0) // the frame is a fixed literal, so a zero length can only mean it did not fit { @@ -273,28 +282,31 @@ size_t protocore_ntrip_build_str_record(char *out, size_t cap, const NtripMount const char *gen = m->generator ? m->generator : "PC"; // STR;mount;identifier;format;format-details;carrier;nav;network;country;lat;lon;nmea;solution; // generator;compr;auth;fee;bitrate;misc (carrier 0 = station reference only, no observations) - protocore_sb sb_out8 = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out8, "STR;"); - Sb.put(&sb_out8, m->mountpoint); - Sb.put(&sb_out8, ";"); - Sb.put(&sb_out8, ident); - Sb.put(&sb_out8, ";RTCM 3.3;"); - Sb.put(&sb_out8, fmtd); - Sb.put(&sb_out8, ";0;"); - Sb.put(&sb_out8, nav); - Sb.put(&sb_out8, ";none;"); - Sb.put(&sb_out8, ctry); - Sb.put(&sb_out8, ";"); - Sb.put(&sb_out8, lat); - Sb.put(&sb_out8, ";"); - Sb.put(&sb_out8, lon); - Sb.put(&sb_out8, ";"); - Sb.i64(&sb_out8, (int64_t)(m->nmea_required ? 1 : 0)); - Sb.put(&sb_out8, ";0;"); - Sb.put(&sb_out8, gen); - Sb.put(&sb_out8, ";none;N;N;9600;"); - int n = (int)Sb.finish(&sb_out8); - if (!sb_out8.ok) + size_t sb_out8 = 0; + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = "STR;"); + sb_out8 = + EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = m->mountpoint); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ";"); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ident); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ";RTCM 3.3;"); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = fmtd); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ";0;"); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = nav); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ";none;"); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ctry); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ";"); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = lat); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ";"); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = lon); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ";"); + sb_out8 = EMBED_CALL(verba_numerus.i64, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out8, + .sval = (int64_t)(m->nmea_required ? 1 : 0)); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ";0;"); + sb_out8 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = gen); + sb_out8 = + EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out8, .text = ";none;N;N;9600;"); + int n = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out8); + if (!EMBED_CALL(verba_finis.ok, VerbaFinisCfg, .cap = cap, .at = sb_out8)) { return 0; } @@ -324,21 +336,28 @@ size_t protocore_ntrip_build_sourcetable(char *out, size_t cap, NtripVersion ver int hn; if (version == NTRIP_V2) { - protocore_sb sb_out9 = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out9, "HTTP/1.1 200 OK\r\nNtrip-Version: Ntrip/2.0\r\nServer: ProtoCore/2.0\r\nContent-Type: " - "gnss/sourcetable\r\nContent-Length: "); - Sb.u32(&sb_out9, (uint32_t)((unsigned)body_len)); - Sb.put(&sb_out9, "\r\nConnection: close\r\n\r\n"); - hn = (int)Sb.finish(&sb_out9); + size_t sb_out9 = 0; + sb_out9 = + EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out9, + .text = "HTTP/1.1 200 OK\r\nNtrip-Version: Ntrip/2.0\r\nServer: ProtoCore/2.0\r\nContent-Type: " + "gnss/sourcetable\r\nContent-Length: "); + sb_out9 = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out9, + .val = (uint32_t)((unsigned)body_len)); + sb_out9 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out9, + .text = "\r\nConnection: close\r\n\r\n"); + hn = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out9); } else { - protocore_sb sb_out10 = {out, cap, 0, PROTO_TRUE}; - Sb.put(&sb_out10, - "SOURCETABLE 200 OK\r\nServer: ProtoCore/1.0\r\nContent-Type: text/plain\r\nContent-Length: "); - Sb.u32(&sb_out10, (uint32_t)((unsigned)body_len)); - Sb.put(&sb_out10, "\r\n\r\n"); - hn = (int)Sb.finish(&sb_out10); + size_t sb_out10 = 0; + sb_out10 = EMBED_CALL( + verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out10, + .text = "SOURCETABLE 200 OK\r\nServer: ProtoCore/1.0\r\nContent-Type: text/plain\r\nContent-Length: "); + sb_out10 = EMBED_CALL(verba_numerus.u32, VerbaNumerusCfg, .out = out, .cap = cap, .at = sb_out10, + .val = (uint32_t)((unsigned)body_len)); + sb_out10 = + EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = sb_out10, .text = "\r\n\r\n"); + hn = (int)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = sb_out10); } if (hn == 0) // the frame always has a literal prefix, so a zero length means it did not fit { @@ -361,7 +380,7 @@ size_t protocore_ntrip_build_sourcetable(char *out, size_t cap, NtripVersion ver { return 0; } - mem.cpy(out + pos, ENDLINE, sizeof(ENDLINE) - 1); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + pos, .src = ENDLINE, .bytes = sizeof(ENDLINE) - 1); pos += sizeof(ENDLINE) - 1; out[pos] = '\0'; return pos; diff --git a/src/services/timing_position/gnss/rtcm3/CMakeLists.txt b/src/services/timing_position/gnss/rtcm3/CMakeLists.txt index 4c38bac07..632171bd1 100644 --- a/src/services/timing_position/gnss/rtcm3/CMakeLists.txt +++ b/src/services/timing_position/gnss/rtcm3/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/timing_position/gnss/rtcm3 GATE PROTOCORE_ENABLE_NTRIP_CASTER SOURCES rtcm3.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/timing_position/gnss/rtcm3/rtcm3.c b/src/services/timing_position/gnss/rtcm3/rtcm3.c index 7d7d12028..307609f87 100644 --- a/src/services/timing_position/gnss/rtcm3/rtcm3.c +++ b/src/services/timing_position/gnss/rtcm3/rtcm3.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_NTRIP_CASTER -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/timing_position/gnss/rtcm3/rtcm3.h" // --------------------------------------------------------------------------------------------- @@ -158,7 +158,7 @@ size_t protocore_rtcm3_frame_build(uint8_t *out, size_t cap, const uint8_t *payl out[2] = (uint8_t)(payload_len & 0xFFu); if (payload_len && payload) { - mem.cpy(out + RTCM3_HDR_LEN, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + RTCM3_HDR_LEN, .src = payload, .bytes = payload_len); } uint32_t crc = protocore_rtcm3_crc24q(out, (size_t)RTCM3_HDR_LEN + payload_len); out[RTCM3_HDR_LEN + payload_len] = (uint8_t)((crc >> 16) & 0xFFu); @@ -175,7 +175,7 @@ static size_t build_arp(uint8_t *out, size_t cap, uint16_t msg, uint16_t station proto_bool with_h, uint16_t h) { uint8_t payload[21]; - mem.set(payload, 0, sizeof payload); + EMBED_CALL(memor.set, MemoriaCfg, .dst = payload, .val = 0, .bytes = sizeof payload); RtcmBitWriter w; protocore_rtcm_bw_init(&w, payload, sizeof payload); protocore_rtcm_bw_u(&w, msg, 12); // DF002 message number diff --git a/src/services/timing_position/nmea0183/CMakeLists.txt b/src/services/timing_position/nmea0183/CMakeLists.txt index 1cd94ec3e..324e2168e 100644 --- a/src/services/timing_position/nmea0183/CMakeLists.txt +++ b/src/services/timing_position/nmea0183/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/timing_position/nmea0183 GATE PROTOCORE_ENABLE_NMEA0183 SOURCES nmea0183.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/timing_position/nmea0183/nmea0183.c b/src/services/timing_position/nmea0183/nmea0183.c index 7e7bb9aad..e94d98642 100644 --- a/src/services/timing_position/nmea0183/nmea0183.c +++ b/src/services/timing_position/nmea0183/nmea0183.c @@ -7,11 +7,11 @@ */ #include "services/timing_position/nmea0183/nmea0183.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #if PROTOCORE_ENABLE_NMEA0183 -#include "mmgr/protostr/protostr.h" +#include "cellularum_laboro/cellularum_laboro.h" PROTOCORE_BEGIN_DECLS @@ -54,7 +54,7 @@ size_t protocore_nmea0183_build(char *buf, size_t cap, const char *body) { return 0; } - size_t blen = str.len(body, cap); + size_t blen = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = body, .cap = cap); size_t total = 1 + blen + 1 + 2 + 2; // '$' + body + '*' + HH + CRLF if (cap < total + 1) // + NUL { @@ -63,7 +63,7 @@ size_t protocore_nmea0183_build(char *buf, size_t cap, const char *body) uint8_t cs = protocore_nmea0183_checksum(body, blen); size_t p = 0; buf[p++] = '$'; - mem.cpy(buf + p, body, blen); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = buf + p, .src = body, .bytes = blen); p += blen; buf[p++] = '*'; buf[p++] = hex_digit((uint8_t)(cs >> 4)); @@ -133,8 +133,8 @@ proto_bool protocore_nmea0183_parse(const char *s, size_t len, Nmea0183 *out) out->field_count = fc; // Derive talker / type from the address field (field 0). - mem.set(out->talker, 0, sizeof(out->talker)); - mem.set(out->type, 0, sizeof(out->type)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out->talker, .val = 0, .bytes = sizeof(out->talker)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out->type, .val = 0, .bytes = sizeof(out->type)); if (fc > 0) // point) guarantees star >= 1 (it is only ever set inside the search loop, which // starts at i = 1), so the split loop's `i <= star` bound guarantees an i == star @@ -166,8 +166,8 @@ proto_bool protocore_nmea0183_field_float(const Nmea0183 *m, uint8_t idx, float return PROTO_FALSE; } const char *end = m->fields[idx]; - // The field is delimited by a ',' or '*' in the source, so str.to_float stops at the field end. - float v = str.to_float(m->fields[idx], &end); + // The field is delimited by a ',' or '*' in the source, so cellul.to_float stops at the field end. + float v = EMBED_CALL(cellul.to_float, TransfiguroCfg, .src = m->fields[idx], .end = &end); if (end == m->fields[idx]) { return PROTO_FALSE; @@ -183,7 +183,7 @@ proto_bool protocore_nmea0183_field_int(const Nmea0183 *m, uint8_t idx, long *ou return PROTO_FALSE; } const char *end = m->fields[idx]; - long v = str.to_long(m->fields[idx], &end); + long v = EMBED_CALL(cellul.to_long, TransfiguroCfg, .src = m->fields[idx], .end = &end); if (end == m->fields[idx]) { return PROTO_FALSE; @@ -218,7 +218,8 @@ static void nmea_time(const Nmea0183 *m, uint8_t idx, uint8_t *h, uint8_t *mi, f *h = (uint8_t)((f[0] - '0') * 10 + (f[1] - '0')); *mi = (uint8_t)((f[2] - '0') * 10 + (f[3] - '0')); const char *end = f + 4; - *s = str.to_float(f + 4, &end); // ss.ss, stopped at the ',' / '*' delimiter + // ss.ss, stopped at the ',' / '*' delimiter + *s = EMBED_CALL(cellul.to_float, TransfiguroCfg, .src = f + 4, .end = &end); } // Split a ddmmyy date field into day / month / (2-digit) year. @@ -239,12 +240,14 @@ static void nmea_date(const Nmea0183 *m, uint8_t idx, uint8_t *d, uint8_t *mo, u proto_bool protocore_nmea0183_parse_gga(const Nmea0183 *m, protocore_nmea_gga *out) { - if (!m || !out || !str.eq(m->type, "GGA", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "GGA", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 10) // need through altitude (field 9) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); nmea_time(m, 1, &out->hour, &out->minute, &out->second); float lat = 0.0f, lon = 0.0f; if (protocore_nmea0183_field_float(m, 2, &lat) && m->field_len[3] >= 1) @@ -272,12 +275,14 @@ proto_bool protocore_nmea0183_parse_gga(const Nmea0183 *m, protocore_nmea_gga *o proto_bool protocore_nmea0183_parse_rmc(const Nmea0183 *m, protocore_nmea_rmc *out) { - if (!m || !out || !str.eq(m->type, "RMC", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "RMC", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 10) // need through date (field 9) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); nmea_time(m, 1, &out->hour, &out->minute, &out->second); out->valid = (m->field_len[2] >= 1 && (m->fields[2][0] == 'A' || m->fields[2][0] == 'a')); float lat = 0.0f, lon = 0.0f; @@ -297,12 +302,14 @@ proto_bool protocore_nmea0183_parse_rmc(const Nmea0183 *m, protocore_nmea_rmc *o proto_bool protocore_nmea0183_parse_gsv(const Nmea0183 *m, protocore_nmea_gsv *out) { - if (!m || !out || !str.eq(m->type, "GSV", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "GSV", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 4) // header: totalMsgs, msgNum, satsInView { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); long v = 0; if (protocore_nmea0183_field_int(m, 1, &v)) { @@ -352,12 +359,14 @@ proto_bool protocore_nmea0183_parse_gsv(const Nmea0183 *m, protocore_nmea_gsv *o proto_bool protocore_nmea0183_parse_zda(const Nmea0183 *m, protocore_nmea_zda *out) { - if (!m || !out || !str.eq(m->type, "ZDA", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "ZDA", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 5) // need through year (field 4) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); nmea_time(m, 1, &out->hour, &out->minute, &out->second); long v = 0; if (protocore_nmea0183_field_int(m, 2, &v)) @@ -386,12 +395,14 @@ proto_bool protocore_nmea0183_parse_zda(const Nmea0183 *m, protocore_nmea_zda *o proto_bool protocore_nmea0183_parse_vtg(const Nmea0183 *m, protocore_nmea_vtg *out) { - if (!m || !out || !str.eq(m->type, "VTG", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "VTG", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 9) // need through the km/h unit (field 8) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); protocore_nmea0183_field_float(m, 1, &out->course_true_deg); // stays 0 if empty (out was zeroed) protocore_nmea0183_field_float(m, 3, &out->course_mag_deg); protocore_nmea0183_field_float(m, 5, &out->speed_knots); @@ -406,12 +417,14 @@ proto_bool protocore_nmea0183_parse_vtg(const Nmea0183 *m, protocore_nmea_vtg *o proto_bool protocore_nmea0183_parse_gsa(const Nmea0183 *m, protocore_nmea_gsa *out) { - if (!m || !out || !str.eq(m->type, "GSA", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "GSA", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 18) // need through VDOP (field 17) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); if (m->field_len[1] >= 1) { out->mode = m->fields[1][0]; @@ -439,12 +452,14 @@ proto_bool protocore_nmea0183_parse_gsa(const Nmea0183 *m, protocore_nmea_gsa *o proto_bool protocore_nmea0183_parse_mwv(const Nmea0183 *m, protocore_nmea_mwv *out) { - if (!m || !out || !str.eq(m->type, "MWV", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "MWV", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 6) // need through status (field 5) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); protocore_nmea0183_field_float(m, 1, &out->wind_angle_deg); // stays 0 if empty (out was zeroed) if (m->field_len[2] >= 1) { @@ -461,12 +476,14 @@ proto_bool protocore_nmea0183_parse_mwv(const Nmea0183 *m, protocore_nmea_mwv *o proto_bool protocore_nmea0183_parse_dpt(const Nmea0183 *m, protocore_nmea_dpt *out) { - if (!m || !out || !str.eq(m->type, "DPT", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "DPT", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 3) // need depth (field 1) + offset (field 2) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); protocore_nmea0183_field_float(m, 1, &out->depth_m); // stays 0 if empty (out was zeroed) protocore_nmea0183_field_float(m, 2, &out->offset_m); out->has_range = protocore_nmea0183_field_float(m, 3, &out->range_m); // the range scale is optional @@ -475,12 +492,14 @@ proto_bool protocore_nmea0183_parse_dpt(const Nmea0183 *m, protocore_nmea_dpt *o proto_bool protocore_nmea0183_parse_hdg(const Nmea0183 *m, protocore_nmea_hdg *out) { - if (!m || !out || !str.eq(m->type, "HDG", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "HDG", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 6) // heading + dev + dir + var + dir { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); protocore_nmea0183_field_float(m, 1, &out->heading_deg); float dev = 0.0f; if (protocore_nmea0183_field_float(m, 2, &dev)) // field 3 is the E/W direction (West -> negative) @@ -497,12 +516,14 @@ proto_bool protocore_nmea0183_parse_hdg(const Nmea0183 *m, protocore_nmea_hdg *o proto_bool protocore_nmea0183_parse_gll(const Nmea0183 *m, protocore_nmea_gll *out) { - if (!m || !out || !str.eq(m->type, "GLL", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "GLL", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 7) // need through status (field 6) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); float lat = 0.0f, lon = 0.0f; if (protocore_nmea0183_field_float(m, 1, &lat) && m->field_len[2] >= 1) { @@ -524,12 +545,14 @@ proto_bool protocore_nmea0183_parse_gll(const Nmea0183 *m, protocore_nmea_gll *o proto_bool protocore_nmea0183_parse_vhw(const Nmea0183 *m, protocore_nmea_vhw *out) { - if (!m || !out || !str.eq(m->type, "VHW", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "VHW", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 8) // need through speed km/h (field 7) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); protocore_nmea0183_field_float(m, 1, &out->heading_true_deg); // heading true; stays 0 if empty (out was zeroed) protocore_nmea0183_field_float(m, 3, &out->heading_mag_deg); // heading magnetic protocore_nmea0183_field_float(m, 5, &out->speed_knots); // speed through water, knots @@ -539,12 +562,14 @@ proto_bool protocore_nmea0183_parse_vhw(const Nmea0183 *m, protocore_nmea_vhw *o proto_bool protocore_nmea0183_parse_vlw(const Nmea0183 *m, protocore_nmea_vlw *out) { - if (!m || !out || !str.eq(m->type, "VLW", sizeof(m->type), PROTO_FALSE) || + if (!m || !out || + !EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = m->type, .other = "VLW", .cap = sizeof(m->type), + .ci = PROTO_FALSE) || m->field_count < 4) // need through the trip distance (field 3) { return PROTO_FALSE; } - mem.set(out, 0, sizeof(*out)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = sizeof(*out)); protocore_nmea0183_field_float(m, 1, &out->total_water_nm); // total cumulative; stays 0 if empty (out was zeroed) protocore_nmea0183_field_float(m, 3, &out->trip_water_nm); // since the last reset return PROTO_TRUE; diff --git a/src/services/timing_position/nmea0183/nmea0183.h b/src/services/timing_position/nmea0183/nmea0183.h index f925022f3..8565962e0 100644 --- a/src/services/timing_position/nmea0183/nmea0183.h +++ b/src/services/timing_position/nmea0183/nmea0183.h @@ -9,7 +9,7 @@ * AIS-encapsulated), a comma-separated field list whose first field is the 5-char address * (2-char talker id + 3-char sentence type), a `*`, and a two-hex-digit XOR checksum. This * codec builds a sentence (adding the `$`, checksum, and CR/LF) and parses one (validating the - * checksum and splitting the fields), with `str.to_float` / `str.to_long` field-value helpers. + * checksum and splitting the fields), with `cellul.to_float` / `cellul.to_long` field-value helpers. * * GPS / marine receivers are cheap UART breakouts, so on an ESP32 this is a plain * `HardwareSerial` link (commonly 4800 or 9600 baud); the UART is the application's. Pure diff --git a/src/services/timing_position/ubx/CMakeLists.txt b/src/services/timing_position/ubx/CMakeLists.txt index f35dbb9f5..e09c8614d 100644 --- a/src/services/timing_position/ubx/CMakeLists.txt +++ b/src/services/timing_position/ubx/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/timing_position/ubx GATE PROTOCORE_ENABLE_UBX SOURCES ubx.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/timing_position/ubx/ubx.c b/src/services/timing_position/ubx/ubx.c index a8c71556d..ec4f5f4c1 100644 --- a/src/services/timing_position/ubx/ubx.c +++ b/src/services/timing_position/ubx/ubx.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_UBX -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/timing_position/ubx/ubx.h" PROTOCORE_BEGIN_DECLS @@ -293,7 +293,7 @@ void protocore_ubx_stream_init(protocore_ubx_stream *st) { if (st) { - mem.set(st, 0, sizeof(*st)); // state = S_SYNC1 + EMBED_CALL(memor.set, MemoriaCfg, .dst = st, .val = 0, .bytes = sizeof(*st)); // state = S_SYNC1 } } diff --git a/src/services/transportation/nema_ts2/CMakeLists.txt b/src/services/transportation/nema_ts2/CMakeLists.txt index fa4cdb9a3..55c2bfbe2 100644 --- a/src/services/transportation/nema_ts2/CMakeLists.txt +++ b/src/services/transportation/nema_ts2/CMakeLists.txt @@ -5,6 +5,6 @@ protocore_add_module(services/transportation/nema_ts2 GATE PROTOCORE_ENABLE_NEMA_TS2 SOURCES nema_ts2.c PRIVATE_DEPS - mmgr/protomem + mmgr shared/crc ) diff --git a/src/services/transportation/nema_ts2/nema_ts2.c b/src/services/transportation/nema_ts2/nema_ts2.c index 37756d0c4..77f4f745d 100644 --- a/src/services/transportation/nema_ts2/nema_ts2.c +++ b/src/services/transportation/nema_ts2/nema_ts2.c @@ -7,7 +7,7 @@ */ #include "services/transportation/nema_ts2/nema_ts2.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "shared/crc/crc.h" // PROTOCORE_CRC16_X25 #if PROTOCORE_ENABLE_NEMA_TS2 @@ -43,7 +43,7 @@ size_t protocore_nema_ts2_build(uint8_t address, uint8_t control, uint8_t frame_ out[2] = frame_type; if (data_len) { - mem.cpy(out + 3, data, data_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 3, .src = data, .bytes = data_len); } uint16_t crc = protocore_nema_ts2_crc(out, 3 + data_len); out[3 + data_len] = (uint8_t)crc; // FCS low byte first diff --git a/src/services/transportation/ocit/CMakeLists.txt b/src/services/transportation/ocit/CMakeLists.txt index ac78f0a63..1ab18f857 100644 --- a/src/services/transportation/ocit/CMakeLists.txt +++ b/src/services/transportation/ocit/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/transportation/ocit GATE PROTOCORE_ENABLE_OCIT SOURCES ocit.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/transportation/ocit/ocit.c b/src/services/transportation/ocit/ocit.c index 90c1dda44..baea5a87b 100644 --- a/src/services/transportation/ocit/ocit.c +++ b/src/services/transportation/ocit/ocit.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_OCIT -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/transportation/ocit/ocit.h" PROTOCORE_BEGIN_DECLS @@ -35,7 +35,7 @@ size_t protocore_ocit_build(uint8_t msg_type, uint16_t object_type, uint16_t ins out[5] = data_type; if (value_len) { - mem.cpy(out + 6, value, value_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 6, .src = value, .bytes = value_len); } return n; } diff --git a/src/services/transportation/utmc/CMakeLists.txt b/src/services/transportation/utmc/CMakeLists.txt index 23eed9d3c..2188f4b13 100644 --- a/src/services/transportation/utmc/CMakeLists.txt +++ b/src/services/transportation/utmc/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/transportation/utmc GATE PROTOCORE_ENABLE_UTMC SOURCES utmc.c PRIVATE_DEPS - mmgr/membuild - mmgr/protomem + mmgr ) diff --git a/src/services/transportation/utmc/utmc.c b/src/services/transportation/utmc/utmc.c index 62bafd340..24c95169d 100644 --- a/src/services/transportation/utmc/utmc.c +++ b/src/services/transportation/utmc/utmc.c @@ -10,13 +10,13 @@ #if PROTOCORE_ENABLE_UTMC -#include "mmgr/membuild/membuild.h" // protocore_sb frame builder -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/transportation/utmc/utmc.h" +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain PROTOCORE_BEGIN_DECLS -static void put_u(protocore_sb *b, uint32_t v) +static size_t put_u(char *out, size_t cap, size_t at, uint32_t v) { char tmp[11]; int n = 0; @@ -25,38 +25,48 @@ static void put_u(protocore_sb *b, uint32_t v) tmp[n++] = (char)('0' + (int)(v % 10)); v /= 10; } while (v); - char out[12]; + char digits[12]; for (int i = 0; i < n; i++) { - out[i] = tmp[n - 1 - i]; + digits[i] = tmp[n - 1 - i]; } - out[n] = '\0'; - Sb.put(b, out); + digits[n] = '\0'; + return EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = at, .text = digits); } size_t protocore_utmc_request(const char *object_id, char *out, size_t cap) { - protocore_sb b = {out, cap, 0, out != NULL && cap > 0}; - Sb.put(&b, ""); - return Sb.finish(&b); + if (!out || cap == 0) + { + return 0; + } + size_t b = 0; + b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, + .text = ""); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = b); } size_t protocore_utmc_response(const char *object_id, const char *value, uint8_t quality, const char *timestamp, char *out, size_t cap) { - protocore_sb b2 = {out, cap, 0, out != NULL && cap > 0}; - Sb.put(&b2, ""); - return Sb.finish(&b2); + if (!out || cap == 0) + { + return 0; + } + size_t b2 = 0; + b2 = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b2, + .text = ""); + return EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = cap, .at = b2); } size_t protocore_utmc_parse_request(const char *xml, size_t len, char *out, size_t cap) @@ -70,7 +80,7 @@ size_t protocore_utmc_parse_request(const char *xml, size_t len, char *out, size size_t kl = 4; for (size_t i = 0; i + kl < len; i++) { - if (mem.cmp(xml + i, key, kl) != 0) + if (EMBED_CALL(memor.cmp, MemoriaCfg, .src = xml + i, .other = key, .bytes = kl) != 0) { continue; } diff --git a/src/services/transportation/wave/CMakeLists.txt b/src/services/transportation/wave/CMakeLists.txt index e50b1bb8b..10eef854e 100644 --- a/src/services/transportation/wave/CMakeLists.txt +++ b/src/services/transportation/wave/CMakeLists.txt @@ -5,5 +5,5 @@ protocore_add_module(services/transportation/wave GATE PROTOCORE_ENABLE_WAVE SOURCES wave.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/services/transportation/wave/wave.c b/src/services/transportation/wave/wave.c index a3d591a89..7f3506bba 100644 --- a/src/services/transportation/wave/wave.c +++ b/src/services/transportation/wave/wave.c @@ -10,7 +10,7 @@ #if PROTOCORE_ENABLE_WAVE -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "services/transportation/wave/wave.h" PROTOCORE_BEGIN_DECLS @@ -131,7 +131,7 @@ size_t protocore_wsmp_build(uint32_t psid, const uint8_t *payload, size_t payloa out[i++] = (uint8_t)payload_len; // WSM length if (payload_len) { - mem.cpy(out + i, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + i, .src = payload, .bytes = payload_len); i += payload_len; } return i; @@ -185,7 +185,7 @@ size_t protocore_wave_1609dot2_wrap(uint8_t content_type, const uint8_t *payload out[1] = content_type; if (payload_len) { - mem.cpy(out + 2, payload, payload_len); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 2, .src = payload, .bytes = payload_len); } return n; } diff --git a/src/shared/der/CMakeLists.txt b/src/shared/der/CMakeLists.txt index 2d53d6406..e6a877b68 100644 --- a/src/shared/der/CMakeLists.txt +++ b/src/shared/der/CMakeLists.txt @@ -4,5 +4,5 @@ protocore_add_module(shared/der SOURCES der.c PRIVATE_DEPS - mmgr/protomem + mmgr ) diff --git a/src/shared/der/der.c b/src/shared/der/der.c index a7a637466..c0ce27d74 100644 --- a/src/shared/der/der.c +++ b/src/shared/der/der.c @@ -8,7 +8,7 @@ #include "shared/der/der.h" -#include "mmgr/protomem/protomem.h" // mem.cmp: the OID comparison +#include "memoria_operor/memoria_operor.h" // memor.cmp: the OID comparison PROTOCORE_BEGIN_DECLS @@ -197,7 +197,8 @@ void protocore_der_oid_eq(uint8_t *work) return; } DerV.ok = (DerV.tlv.len == DerV.oid_args.oid_len) && - (mem.cmp(DerV.tlv.content, DerV.oid_args.oid, DerV.oid_args.oid_len) == 0); + (EMBED_CALL(memor.cmp, MemoriaCfg, .src = DerV.tlv.content, .other = DerV.oid_args.oid, + .bytes = DerV.oid_args.oid_len) == 0); } // Four ASCII digits as a number, or -1 when any of them is not a digit. diff --git a/src/shared/http_date/CMakeLists.txt b/src/shared/http_date/CMakeLists.txt index d4712e7e7..ac4406067 100644 --- a/src/shared/http_date/CMakeLists.txt +++ b/src/shared/http_date/CMakeLists.txt @@ -6,5 +6,5 @@ protocore_add_module(shared/http_date DEPS shared/time_compat PRIVATE_DEPS - mmgr/membuild + mmgr ) diff --git a/src/shared/http_date/http_date.c b/src/shared/http_date/http_date.c index ad95ede13..b9465f104 100644 --- a/src/shared/http_date/http_date.c +++ b/src/shared/http_date/http_date.c @@ -11,7 +11,7 @@ #include "shared/http_date/http_date.h" -#include "mmgr/membuild/membuild.h" // ::Sb: the builder each fixed-width field is appended through +#include "verba_scribo/verba_scribo.h" // verba_*: the text and number writers the builders chain // The day-name and month literals of RFC 9110 sec 5.6.7, in the order struct tm numbers them: // tm_wday counts from Sunday and tm_mon from January. The grammar spells both with ABNF's @@ -65,22 +65,31 @@ void protocore_http_date_format(uint8_t *work) // Every field is fixed width, so the whole form is 29 octets and the builder's one bound decides // whether it lands. finish reports 0 when it did not fit, which empties the buffer rather than // leaving a partial date. - protocore_sb b = {out, out_cap, 0, PROTO_TRUE}; - Sb.put_n(&b, PROTOCORE_HTTP_DATE_DAY[broken_down.tm_wday], sizeof PROTOCORE_HTTP_DATE_DAY[0]); - Sb.put_n(&b, ", ", 2); - Sb.u32w(&b, (uint32_t)broken_down.tm_mday, PROTOCORE_HTTP_DATE_2DIGIT); - Sb.ch(&b, ' '); - Sb.put_n(&b, PROTOCORE_HTTP_DATE_MON[broken_down.tm_mon], sizeof PROTOCORE_HTTP_DATE_MON[0]); - Sb.ch(&b, ' '); - Sb.u32w(&b, (uint32_t)year, PROTOCORE_HTTP_DATE_4DIGIT); - Sb.ch(&b, ' '); - Sb.u32w(&b, (uint32_t)broken_down.tm_hour, PROTOCORE_HTTP_DATE_2DIGIT); - Sb.ch(&b, ':'); - Sb.u32w(&b, (uint32_t)broken_down.tm_min, PROTOCORE_HTTP_DATE_2DIGIT); - Sb.ch(&b, ':'); - Sb.u32w(&b, (uint32_t)broken_down.tm_sec, PROTOCORE_HTTP_DATE_2DIGIT); - Sb.put_n(&b, " GMT", 4); - HttpDateV.n = (uint8_t)Sb.finish(&b); + size_t b = 0; + b = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = out, .cap = out_cap, .at = b, + .text = PROTOCORE_HTTP_DATE_DAY[broken_down.tm_wday], .text_len = sizeof PROTOCORE_HTTP_DATE_DAY[0]); + b = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = out, .cap = out_cap, .at = b, .text = ", ", + .text_len = 2); + b = EMBED_CALL(verba_numerus.u32w, VerbaNumerusCfg, .out = out, .cap = out_cap, .at = b, + .val = (uint32_t)broken_down.tm_mday, .min = PROTOCORE_HTTP_DATE_2DIGIT); + b = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = out, .cap = out_cap, .at = b, .ch = ' '); + b = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = out, .cap = out_cap, .at = b, + .text = PROTOCORE_HTTP_DATE_MON[broken_down.tm_mon], .text_len = sizeof PROTOCORE_HTTP_DATE_MON[0]); + b = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = out, .cap = out_cap, .at = b, .ch = ' '); + b = EMBED_CALL(verba_numerus.u32w, VerbaNumerusCfg, .out = out, .cap = out_cap, .at = b, .val = (uint32_t)year, + .min = PROTOCORE_HTTP_DATE_4DIGIT); + b = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = out, .cap = out_cap, .at = b, .ch = ' '); + b = EMBED_CALL(verba_numerus.u32w, VerbaNumerusCfg, .out = out, .cap = out_cap, .at = b, + .val = (uint32_t)broken_down.tm_hour, .min = PROTOCORE_HTTP_DATE_2DIGIT); + b = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = out, .cap = out_cap, .at = b, .ch = ':'); + b = EMBED_CALL(verba_numerus.u32w, VerbaNumerusCfg, .out = out, .cap = out_cap, .at = b, + .val = (uint32_t)broken_down.tm_min, .min = PROTOCORE_HTTP_DATE_2DIGIT); + b = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = out, .cap = out_cap, .at = b, .ch = ':'); + b = EMBED_CALL(verba_numerus.u32w, VerbaNumerusCfg, .out = out, .cap = out_cap, .at = b, + .val = (uint32_t)broken_down.tm_sec, .min = PROTOCORE_HTTP_DATE_2DIGIT); + b = EMBED_CALL(verba_textus.put_n, VerbaTextusCfg, .out = out, .cap = out_cap, .at = b, .text = " GMT", + .text_len = 4); + HttpDateV.n = (uint8_t)EMBED_CALL(verba_finis.finish, VerbaFinisCfg, .out = out, .cap = out_cap, .at = b); if (HttpDateV.n == 0) { // The builder appends as it goes, so an overflow leaves the octets it managed to write. diff --git a/src/shared/ip/CMakeLists.txt b/src/shared/ip/CMakeLists.txt index 5488600da..18ab65680 100644 --- a/src/shared/ip/CMakeLists.txt +++ b/src/shared/ip/CMakeLists.txt @@ -4,6 +4,6 @@ protocore_add_module(shared/ip SOURCES ip.c PRIVATE_DEPS - mmgr/protomem + mmgr shared/hex ) diff --git a/src/shared/ip/ip.c b/src/shared/ip/ip.c index 82a7c6215..0dcc2e904 100644 --- a/src/shared/ip/ip.c +++ b/src/shared/ip/ip.c @@ -12,7 +12,7 @@ */ #include "shared/ip/ip.h" -#include "mmgr/protomem/protomem.h" +#include "memoria_operor/memoria_operor.h" #include "shared/hex/hex.h" // PROTOCORE_HEX: the shared digit tables // ------------------------------------------------------------------------------------------- @@ -111,7 +111,7 @@ static proto_bool parse_hextet(const char *s, size_t len, uint16_t *out) static void assemble_v6(const uint16_t *head, int nhead, const uint16_t *tail, int ntail, uint8_t out[16]) { uint16_t g[8]; - mem.set(g, 0, sizeof(g)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = g, .val = 0, .bytes = sizeof(g)); for (int k = 0; k < nhead; k++) { g[k] = head[k]; @@ -160,7 +160,7 @@ static proto_bool parse_v6(const char *s, size_t len, uint8_t out[16]) i = 2; if (i == len) // the whole address is "::" { - mem.set(out, 0, 16); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out, .val = 0, .bytes = 16); return PROTO_TRUE; } } @@ -277,7 +277,7 @@ static size_t format_v4(const uint8_t *b, char *out, size_t cap) { return 0; } - mem.cpy(out, tmp, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = tmp, .bytes = n); out[n] = '\0'; return n; } @@ -468,7 +468,7 @@ void protocore_ip_parse(uint8_t *work) return; } - mem.set(out->bytes, 0, 16); + EMBED_CALL(memor.set, MemoriaCfg, .dst = out->bytes, .val = 0, .bytes = 16); if (colon) { if (!parse_v6(s, len, out->bytes)) @@ -529,8 +529,8 @@ void protocore_ip_format(uint8_t *work) IpV.n = 0; return; } - mem.cpy(out, "::ffff:", 7); - mem.cpy(out + 7, tail, tn); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = "::ffff:", .bytes = 7); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 7, .src = tail, .bytes = tn); out[7 + tn] = '\0'; IpV.n = 7 + tn; return; @@ -575,7 +575,7 @@ void protocore_ip_format(uint8_t *work) IpV.n = 0; return; } - mem.cpy(out, tmp, n); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out, .src = tmp, .bytes = n); out[n] = '\0'; IpV.n = n; } @@ -633,13 +633,13 @@ void protocore_ip_equal(uint8_t *work) IpV.ok = PROTO_TRUE; return; // both the same non-address family (PROTOCORE_IP_NONE) } - IpV.ok = mem.cmp(a->bytes, b->bytes, (size_t)n) == 0; + IpV.ok = EMBED_CALL(memor.cmp, MemoriaCfg, .src = a->bytes, .other = b->bytes, .bytes = (size_t)n) == 0; } protocore_ip protocore_ip_from_v4_octets(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { protocore_ip ip; - mem.set(&ip, 0, sizeof(ip)); + EMBED_CALL(memor.set, MemoriaCfg, .dst = &ip, .val = 0, .bytes = sizeof(ip)); ip.family = PROTOCORE_IP_V4; ip.bytes[0] = a; ip.bytes[1] = b; @@ -652,7 +652,7 @@ protocore_ip protocore_ip_from_v6_bytes(const uint8_t bytes[16]) { protocore_ip ip; ip.family = PROTOCORE_IP_V6; - mem.cpy(ip.bytes, bytes, 16); + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = ip.bytes, .src = bytes, .bytes = 16); return ip; } diff --git a/src/shared/pcap/CMakeLists.txt b/src/shared/pcap/CMakeLists.txt index 6d0485adb..44423bd0f 100644 --- a/src/shared/pcap/CMakeLists.txt +++ b/src/shared/pcap/CMakeLists.txt @@ -4,5 +4,5 @@ protocore_add_module(shared/pcap SOURCES pcap.c DEPS - mmgr/endian + mmgr ) diff --git a/src/shared/pcap/pcap.c b/src/shared/pcap/pcap.c index 1673754b6..f3229bdd5 100644 --- a/src/shared/pcap/pcap.c +++ b/src/shared/pcap/pcap.c @@ -21,13 +21,15 @@ void protocore_pcap_global_header(uint8_t *work) { return; } - endian.wr32le(out + 0, 0xa1b2c3d4); // magic: usec timestamps, little-endian - endian.wr16le(out + 4, 2); // version major - endian.wr16le(out + 6, 4); // version minor - endian.wr32le(out + 8, 0); // thiszone (GMT) - endian.wr32le(out + 12, 0); // sigfigs - endian.wr32le(out + 16, 65535); // snaplen - endian.wr32le(out + 20, PcapV.args.linktype); // network / DLT + // magic: usec timestamps, little-endian + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 0, .val = 0xa1b2c3d4, .width = MMGR_ENDIAN_32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 4, .val = 2, .width = MMGR_ENDIAN_16); // version major + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 6, .val = 4, .width = MMGR_ENDIAN_16); // version minor + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 8, .val = 0, .width = MMGR_ENDIAN_32); // thiszone (GMT) + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 12, .val = 0, .width = MMGR_ENDIAN_32); // sigfigs + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 16, .val = 65535, .width = MMGR_ENDIAN_32); // snaplen + // network / DLT + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 20, .val = PcapV.args.linktype, .width = MMGR_ENDIAN_32); PcapV.n = PROTOCORE_PCAP_GLOBAL_HDR_LEN; } @@ -41,10 +43,10 @@ void protocore_pcap_record_header(uint8_t *work) { return; } - endian.wr32le(out + 0, PcapV.rec.ts_sec); - endian.wr32le(out + 4, PcapV.rec.ts_usec); - endian.wr32le(out + 8, PcapV.rec.caplen); - endian.wr32le(out + 12, PcapV.rec.origlen); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 0, .val = PcapV.rec.ts_sec, .width = MMGR_ENDIAN_32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 4, .val = PcapV.rec.ts_usec, .width = MMGR_ENDIAN_32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 8, .val = PcapV.rec.caplen, .width = MMGR_ENDIAN_32); + EMBED_CALL(parva_extremitas.wr, EndianCfg, .dst = out + 12, .val = PcapV.rec.origlen, .width = MMGR_ENDIAN_32); PcapV.n = PROTOCORE_PCAP_REC_HDR_LEN; } diff --git a/src/shared/pcap/pcap.h b/src/shared/pcap/pcap.h index a5f162e79..a770ab2c2 100644 --- a/src/shared/pcap/pcap.h +++ b/src/shared/pcap/pcap.h @@ -17,7 +17,7 @@ #ifndef PROTOCORE_PCAP_H #define PROTOCORE_PCAP_H -#include "mmgr/endian/endian.h" // endian.wr32le / endian.wr16le - libpcap headers are little-endian +#include "endian/endian.h" // parva_extremitas.wr - libpcap headers are little-endian #include "protocore_config.h" // the entry point: protocore_types.h for the widths diff --git a/src/web_assets/wizard/gen_theme_blobs.py b/src/web_assets/wizard/gen_theme_blobs.py index 4b65456b3..c2363ee6c 100644 --- a/src/web_assets/wizard/gen_theme_blobs.py +++ b/src/web_assets/wizard/gen_theme_blobs.py @@ -156,7 +156,7 @@ def render_source(themes): '#include "protocore_config.h" // the entry point: the widths', "", '#include "binary_asset_blobs.h"', - '#include "mmgr/protostr/protostr.h"', + '#include "cellularum_laboro/cellularum_laboro.h"', "", "#if PROTOCORE_ENABLE_THEMES", "", @@ -200,13 +200,14 @@ def render_source(themes): " {", " return NULL;", " }", - " // str.eq reads read_cap bytes of both operands, so the lengths are matched first: two", + " // cellul.eq reads cap bytes of both operands, so the lengths are matched first: two", " // strings of length n each hold n + 1 readable bytes, the terminator included.", - " const size_t n = str.len(name, THEME_NAME_CAP);", + " const size_t n = EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = name, .cap = THEME_NAME_CAP);", " for (size_t i = 0; i < PROTOCORE_THEME_BLOB_COUNT; i++)", " {", " const char *have = PROTOCORE_THEME_BLOBS[i].name;", - " if (str.len(have, THEME_NAME_CAP) == n && str.eq(have, name, n + 1u, PROTO_FALSE))", + " if (EMBED_CALL(cellul.len, CatenaFinitaCfg, .src = have, .cap = THEME_NAME_CAP) == n &&", + " EMBED_CALL(cellul.eq, CatenaFinitaCfg, .src = have, .other = name, .cap = n + 1u, .ci = PROTO_FALSE))", " {", " return PROTOCORE_THEME_BLOBS[i].css;", " }", diff --git a/test/harness.py b/test/harness.py index aa59346ef..548769e2f 100644 --- a/test/harness.py +++ b/test/harness.py @@ -1210,8 +1210,18 @@ def _flag_split(flags): elif f.startswith("-D"): defs.append(f) # -Iinclude is PlatformIO's implicit include_dir, where protocore.h lives. Nothing here is pio, - # so every path that compiles or scans a TU names it. - for base in ("-Itest/core_setup/hal/host", "-Itest/support", "-Isrc", "-Iinclude", "-I."): + # so every path that compiles or scans a TU names it. The last three are MMgr's roots, the same + # set as tools/ci_tooling/build/gen_cmake.py BASE_INCLUDES. + for base in ( + "-Itest/core_setup/hal/host", + "-Itest/support", + "-Isrc", + "-Iinclude", + "-I.", + "-Iinclude/MMgr/include", + "-Iinclude/MMgr/src", + "-Iinclude/embedded_types/include", + ): if base not in incs: incs.append(base) return incs, defs diff --git a/test/test_matrix.json b/test/test_matrix.json index 703925b33..333029d44 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -90,14 +90,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ads1115/test_ads1115" @@ -342,16 +336,10 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/signaling/test_bus_capture" @@ -376,15 +364,9 @@ "+", "+", "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "env/peripherals/test_bus_wire" @@ -1016,7 +998,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -1034,30 +1015,15 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -1114,18 +1080,9 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": ["unit/src/server/storage/config_io/test_config_io"], "extra_scripts": ["pre:test/gen_test_runners.py"] @@ -1136,14 +1093,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": ["unit/src/server/storage/config_store/test_config_store"], "extra_scripts": ["pre:test/gen_test_runners.py"] @@ -1367,19 +1318,10 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/web/dashboard/test_dashboard" @@ -1472,16 +1414,10 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": ["unit/src/server/signaling/test_device_id"], "extra_scripts": ["pre:test/gen_test_runners.py"] @@ -2421,13 +2357,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/radio/espnow/test_espnow" @@ -2492,13 +2423,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/core/test_failsafe" @@ -2529,14 +2455,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/fdc2214/test_fdc2214" @@ -2605,14 +2525,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/net/flow_export/test_flow_export" @@ -2828,13 +2742,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/net/gateway/test_gateway" @@ -2933,17 +2842,9 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/iot/graphql/test_graphql" @@ -2972,18 +2873,10 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/core/guardrails/test_guardrails" @@ -3338,13 +3231,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/hmmd/test_hmmd" @@ -3362,13 +3250,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/hmmd/test_hmmd" @@ -3397,17 +3280,9 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/storage/hotswap/test_hotswap" @@ -3711,19 +3586,9 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -3751,19 +3616,9 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -3788,19 +3643,9 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -3815,15 +3660,9 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ina219/test_ina219" @@ -3922,13 +3761,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/fieldbus/j1939/test_j1939" @@ -4038,8 +3872,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -4061,30 +3893,17 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -4103,13 +3922,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ld2410/test_ld2410" @@ -4127,13 +3941,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ld2410/test_ld2410" @@ -4149,14 +3958,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ldc1614/test_ldc1614" @@ -4204,18 +4007,9 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/shared/log/test_log" @@ -4231,18 +4025,9 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/core/test_logbuf" @@ -4295,14 +4080,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/iot/lwm2m/test_lwm2m_tlv" @@ -4497,19 +4276,10 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/storage/mnt/test_mnt" @@ -4592,13 +4362,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/mpr121/test_mpr121" @@ -4858,13 +4623,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/timing_position/nmea2000/test_nmea2000" @@ -5173,21 +4933,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -5428,14 +5176,9 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/pca9685/test_pca9685" @@ -5565,23 +5308,11 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -5724,14 +5455,9 @@ "src": [ "+", "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/test_pmbus" @@ -5783,18 +5509,10 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/core/power_mgmt/test_power_mgmt" @@ -6014,14 +5732,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/iot/protobuf/test_protobuf" @@ -6567,8 +6279,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -6582,7 +6292,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -6595,26 +6304,14 @@ "+", "+", "+", - "+", "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -6659,13 +6356,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/rcwl0516/test_rcwl0516" @@ -6898,13 +6590,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/rtc/test_rtc" @@ -6970,14 +6657,7 @@ "+", "+", "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -7003,19 +6683,10 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/network_drivers/session/scp/test_scp" @@ -7069,8 +6740,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -7083,7 +6752,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -7106,25 +6774,15 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", "+", "+", "+" @@ -7193,13 +6851,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/sen0192/test_sen0192" @@ -7293,8 +6946,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -7307,7 +6958,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -7330,27 +6980,17 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -7370,15 +7010,9 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/sht3x/test_sht3x" @@ -7425,13 +7059,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/fieldbus/simatic/test_simatic" @@ -7473,18 +7102,10 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -7610,16 +7231,8 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+" ], @@ -7651,19 +7264,9 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", "+", "+" ], @@ -7681,14 +7284,9 @@ ], "src": [ "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/test_smbus" @@ -7908,14 +7506,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/southbound/southbound/test_southbound" @@ -7959,14 +7551,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/iot/sparkplug/test_sparkplug" @@ -8013,7 +7599,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8034,13 +7619,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -8050,16 +7631,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+", "+" @@ -8170,8 +7743,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -8184,7 +7755,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8209,12 +7779,9 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", "+", "+", "+", @@ -8222,16 +7789,9 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", "+", "+" ], @@ -8255,7 +7815,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8280,13 +7839,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -8297,17 +7852,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+" ], @@ -8336,8 +7882,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -8350,7 +7894,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8373,22 +7916,12 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", "+", "+" ], @@ -8406,16 +7939,8 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+" ], @@ -8430,16 +7955,8 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -8584,20 +8101,8 @@ ], "src": [ "-<*>", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -8609,7 +8114,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8649,20 +8153,8 @@ ], "src": [ "-<*>", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -8674,7 +8166,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8729,8 +8220,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -8743,7 +8232,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8766,12 +8254,9 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", "+", "+", "+", @@ -8779,16 +8264,9 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", "+", "+" ], @@ -8808,7 +8286,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8830,13 +8307,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -8846,16 +8319,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+" ], @@ -8905,7 +8370,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8926,13 +8390,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -8942,16 +8402,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+" ], @@ -8978,7 +8430,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8999,13 +8450,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -9015,16 +8462,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+", "+" @@ -9045,7 +8484,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -9069,13 +8507,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -9085,16 +8519,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+" ], @@ -9112,22 +8538,13 @@ ], "src": [ "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/network_drivers/application/sftp/test_ssh_sftp" @@ -9210,8 +8627,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -9235,7 +8650,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -9243,25 +8657,13 @@ "+", "+", "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -9956,14 +9358,6 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -9979,11 +9373,7 @@ "+", "+", "+", - "+", "+", - "+", - "+", - "+", "+", "+", "+", @@ -10007,14 +9397,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": ["unit/src/services/security/totp/test_totp"], "extra_scripts": ["pre:test/gen_test_runners.py"] @@ -10028,13 +9412,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/signaling/test_trace_capture" @@ -10206,8 +9585,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -10230,30 +9607,17 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -10300,13 +9664,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/vl53l0x/test_vl53l0x" @@ -10454,8 +9813,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -10481,33 +9838,20 @@ "+", "+", "+", - "+", "+", "+", "+", "+", - "+", "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -10684,21 +10028,11 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", "+", - "+" + "+" ], "tests": [ "unit/src/services/net/ws_client/test_ws_client" @@ -10721,21 +10055,11 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", "+", - "+" + "+" ], "tests": [] }, diff --git a/test/unit/src/network_drivers/presentation/codec/deflate/test_rfc1951/test_rfc1951.c b/test/unit/src/network_drivers/presentation/codec/deflate/test_rfc1951/test_rfc1951.c index b484b23cb..0ce1177b0 100644 --- a/test/unit/src/network_drivers/presentation/codec/deflate/test_rfc1951/test_rfc1951.c +++ b/test/unit/src/network_drivers/presentation/codec/deflate/test_rfc1951/test_rfc1951.c @@ -59,7 +59,7 @@ static uint16_t rev(uint16_t code, int len) return Rfc1951V.u16; } -static void emit_literal(protocore_bit_writer *w, const uint16_t *ll_code, const uint8_t *ll_len, uint8_t b) +static void emit_literal(mmgr_bitor *w, const uint16_t *ll_code, const uint8_t *ll_len, uint8_t b) { Rfc1951V.emit_literal_args.w = w; Rfc1951V.emit_literal_args.ll_code = ll_code; @@ -68,7 +68,7 @@ static void emit_literal(protocore_bit_writer *w, const uint16_t *ll_code, const Rfc1951.emit_literal(rfc1951_work); } -static void emit_match(protocore_bit_writer *w, const uint16_t *ll_code, const uint8_t *ll_len, const uint16_t *d_code, +static void emit_match(mmgr_bitor *w, const uint16_t *ll_code, const uint8_t *ll_len, const uint16_t *d_code, const uint8_t *d_len, int len, int dist) { Rfc1951V.emit_match_args.w = w; @@ -229,13 +229,13 @@ void test_emit_literal_puts_the_code_on_the_wire(void) uint8_t out[4]; memset(out, 0, sizeof(out)); - protocore_bit_writer w = {out, sizeof(out), 0, 0, 0, PROTO_FALSE}; + mmgr_bitor w = {out, sizeof(out), 0, 0, 0, PROTO_FALSE}; emit_literal(&w, ll_code, ll_len, 'A'); - bitw.align(&w); + EMBED_CALL(bitio.align, BitorumCfg, .writer = &w); TEST_ASSERT_FALSE(w.overflow); - TEST_ASSERT_EQUAL_size_t(1, w.cnt); + TEST_ASSERT_EQUAL_size_t(1, w.bytes_written); TEST_ASSERT_EQUAL_HEX8(0x8E, out[0]); } @@ -253,13 +253,13 @@ void test_emit_match_selects_the_code_for_the_span(void) uint8_t out[4]; memset(out, 0, sizeof(out)); - protocore_bit_writer w = {out, sizeof(out), 0, 0, 0, PROTO_FALSE}; + mmgr_bitor w = {out, sizeof(out), 0, 0, 0, PROTO_FALSE}; emit_match(&w, ll_code, ll_len, d_code, d_len, 3, 1); - bitw.align(&w); + EMBED_CALL(bitio.align, BitorumCfg, .writer = &w); TEST_ASSERT_FALSE(w.overflow); - TEST_ASSERT_EQUAL_size_t(2, w.cnt); + TEST_ASSERT_EQUAL_size_t(2, w.bytes_written); TEST_ASSERT_EQUAL_HEX8(0x40, out[0]); TEST_ASSERT_EQUAL_HEX8(0x00, out[1]); } @@ -277,15 +277,15 @@ void test_emit_match_uses_the_single_length_code_for_258(void) uint8_t out[8]; memset(out, 0, sizeof(out)); - protocore_bit_writer w = {out, sizeof(out), 0, 0, 0, PROTO_FALSE}; + mmgr_bitor w = {out, sizeof(out), 0, 0, 0, PROTO_FALSE}; emit_match(&w, ll_code, ll_len, d_code, d_len, 258, 1); - bitw.align(&w); + EMBED_CALL(bitio.align, BitorumCfg, .writer = &w); TEST_ASSERT_FALSE(w.overflow); // Symbol 285 is 280 + 5, so its 8-bit code is 11000000 + 5 = 11000101; then the 5-bit distance // code 00000. Thirteen bits, so two octets. - TEST_ASSERT_EQUAL_size_t(2, w.cnt); + TEST_ASSERT_EQUAL_size_t(2, w.bytes_written); TEST_ASSERT_EQUAL_UINT16(rev(0xC5, 8), ll_code[285]); } @@ -309,14 +309,14 @@ void test_emit_match_writes_the_offset_in_the_extra_bits(void) uint8_t out[8]; memset(out, 0, sizeof(out)); - protocore_bit_writer w = {out, sizeof(out), 0, 0, 0, PROTO_FALSE}; + mmgr_bitor w = {out, sizeof(out), 0, 0, 0, PROTO_FALSE}; emit_match(&w, ll_code, ll_len, d_code, d_len, 12, 5); - bitw.align(&w); + EMBED_CALL(bitio.align, BitorumCfg, .writer = &w); TEST_ASSERT_FALSE(w.overflow); // 7 bits of code 265, 1 extra bit, 5 bits of distance code 4, 1 extra bit = 14 bits, two octets. - TEST_ASSERT_EQUAL_size_t(2, w.cnt); + TEST_ASSERT_EQUAL_size_t(2, w.bytes_written); } // A writer whose buffer is already full latches overflow instead of writing past it. @@ -330,12 +330,12 @@ void test_emit_past_the_buffer_latches_overflow(void) uint8_t out[1]; out[0] = 0; - protocore_bit_writer w = {out, 0, 0, 0, 0, PROTO_FALSE}; + mmgr_bitor w = {out, 0, 0, 0, 0, PROTO_FALSE}; emit_literal(&w, ll_code, ll_len, 'A'); - bitw.align(&w); + EMBED_CALL(bitio.align, BitorumCfg, .writer = &w); TEST_ASSERT_TRUE(w.overflow); - TEST_ASSERT_EQUAL_size_t(0, w.cnt); + TEST_ASSERT_EQUAL_size_t(0, w.bytes_written); TEST_ASSERT_EQUAL_HEX8(0x00, out[0]); } diff --git a/tools/ci_tooling/build/gen_cmake.py b/tools/ci_tooling/build/gen_cmake.py index f0fad304a..b4ba9ffe5 100644 --- a/tools/ci_tooling/build/gen_cmake.py +++ b/tools/ci_tooling/build/gen_cmake.py @@ -37,8 +37,18 @@ OWED = os.path.join(ROOT, "test", "yanked_includes.json") # The include dirs every env compiles with, whatever it named. -Iinclude is PlatformIO's implicit -# include_dir, where protocore.h lives; nothing here is pio, so each one is stated. -BASE_INCLUDES = ["test/core_setup/hal/host", "test/support", "src", "include", "."] +# include_dir, where protocore.h lives; nothing here is pio, so each one is stated. The last three are +# MMgr's roots (include/CMakeLists.txt): mmgr.h, /.h, and embedded_types. +BASE_INCLUDES = [ + "test/core_setup/hal/host", + "test/support", + "src", + "include", + ".", + "include/MMgr/include", + "include/MMgr/src", + "include/embedded_types/include", +] GENERATED_RUNNER = "unity_runner.c" @@ -301,6 +311,9 @@ def cmake_escape(s): target_include_directories(${name} PRIVATE ${E_INCLUDES}) target_compile_definitions(${name} PRIVATE ${E_DEFINES}) target_link_libraries(${name} PRIVATE protocore_env_base) + # MMgr is linked by every env directly, since an OBJECT library's objects reach only the target + # that names it and never pass through protocore_env_base. + target_link_libraries(${name} PRIVATE pc_mmgr) # The suite's own files and its include path arrive through its target, and are compiled here, # under this env's defines - see cmake/ProtoCoreSuite.cmake for why that is an INTERFACE library. protocore_suite_target("${E_SUITE}" _suite) @@ -340,7 +353,7 @@ def render_owed(owed): continue opts = [] for w in incs: - opts.append("-include" if w.startswith("<") else "-include") + opts.append("-include") opts.append(w.strip('"<>')) out.append( 'set_source_files_properties("${PROTOCORE_ROOT}/%s" PROPERTIES COMPILE_OPTIONS "%s")\n' diff --git a/tools/crypto/gen_mlkem_kat.py b/tools/crypto/gen_mlkem_kat.py index 89aea0a27..bd6ac49c2 100644 --- a/tools/crypto/gen_mlkem_kat.py +++ b/tools/crypto/gen_mlkem_kat.py @@ -61,14 +61,19 @@ def main(): # Independent agreement (optional): liboqs uses the same FIPS 203 encodings. checked = "kyber-py round-trip" + # Only the import and the call are optional; a disagreement is a failure, so it is checked + # outside the try that tolerates liboqs being absent. + oqs_k = None try: import oqs with oqs.KeyEncapsulation("ML-KEM-768", secret_key=bytearray(dk)) as kem: - assert kem.decap_secret(ct) == K, "liboqs disagreement" - checked += " + liboqs decaps" + oqs_k = kem.decap_secret(ct) except Exception as e: # noqa: BLE001 - liboqs is a nice-to-have cross-check checked += f" (liboqs skipped: {e})" + if oqs_k is not None: + assert oqs_k == K, "liboqs disagreement" + checked += " + liboqs decaps" assert len(ek) == 1184 and len(ct) == 1088 and len(K) == 32 diff --git a/tools/dev_env/goldenize.py b/tools/dev_env/goldenize.py index e8d967795..187f9fa81 100644 --- a/tools/dev_env/goldenize.py +++ b/tools/dev_env/goldenize.py @@ -641,7 +641,7 @@ def doc_tags(block): The prose a module already published is the prose the golden header keeps: a converted header that drops it trades a documented surface for an undocumented one. """ - body = re.sub(r"^\s*/\*\*|\*/\s*$", "", block) + body = re.sub(r"(?:^\s*/\*\*)|(?:\*/\s*$)", "", block) body = "\n".join(re.sub(r"^\s*\*\s?", "", ln).strip() for ln in body.splitlines()) tags, params, brief, ret = re.split(r"(?m)^@", body)[1:], {}, "", "" for t in tags: diff --git a/tools/harness.py b/tools/harness.py index 6c6414818..68d607a18 100644 --- a/tools/harness.py +++ b/tools/harness.py @@ -902,7 +902,7 @@ def cmd_hooks_status(rest): r"""|(?:not\s+in|in|==|!=)\s*["'](--[a-z0-9][a-z0-9-]*)["']""" r"""|argv\.(?:remove|count|index)\(\s*["'](--[a-z0-9][a-z0-9-]*)["']""" ) -SH_FLAG = re.compile(r"(?m)^\s*(--[a-z0-9][a-z0-9-]*)\)|\[\s*\"\$\w+\"\s*=\s*\"?(--[a-z0-9][a-z0-9-]*)") +SH_FLAG = re.compile(r"(?m)(?:^\s*(--[a-z0-9][a-z0-9-]*)\))|(?:\[\s*\"\$\w+\"\s*=\s*\"?(--[a-z0-9][a-z0-9-]*))") # Commands a Python file hands to the OS. PY_EXEC = re.compile( diff --git a/tools/repotools/lib/repotools/shape.py b/tools/repotools/lib/repotools/shape.py index 78ceb505d..39417eaa7 100644 --- a/tools/repotools/lib/repotools/shape.py +++ b/tools/repotools/lib/repotools/shape.py @@ -76,7 +76,7 @@ (?P[A-Za-z_][A-Za-z_0-9]*) | (?P0[xX][0-9A-Fa-f]+[uUlL]*|\d+\.?\d*([eE][-+]?\d+)?[uUlLfF]*) | (?P"(\\.|[^"\\])*"|'(\\.|[^'\\])*') - | (?P<<=|>>=|\.\.\.|->|\+\+|--|<<|>>|<=|>=|==|!=|&&|\|\||[-+*/%&|^!<>=]=|\#\#|[-+*/%&|^~!<>=?:;,.(){}\[\]\#]) + | (?P<<=|>>=|\.\.\.|->|\+\+|--|<<|>>|&&|\|\||[-+*/%&|^!<>=]=|\#\#|[-+*/%&|^~!<>=?:;,.(){}\[\]\#]) """, re.VERBOSE, )