From 478529a733e66537c90262e85111436c6802914f Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Tue, 29 Sep 2026 22:35:24 +0000 Subject: [PATCH 001/185] fix: SonarCloud bugs and vulnerabilities on main Fixed in code: - tls13_rpk_build_certificate returned nothing on either path (a bare return in a size_t function, and a fall-off at the end). - gen_mlkem_kat: the liboqs cross-check asserted inside a try that caught Exception, so a disagreement was reported as "skipped". - ble_gatt parse: dead return after the switch; h2_conn: unused comma expression; gen_cmake: identical ternary arms; three regexes with ambiguous alternation or a redundant alternative. sonar-project.properties: - The rule suppressions were keyed cpp: while src/ is C and reported under c:, so none applied; they are c: now. - c:S946 (the V args convention), c:S3519 on quic_server.c (slot pool in the borrow), c:S5332 on http_client.c, and the Python taint, ReDoS, PRNG and namespace-URI rules on tools/ are suppressed with the reason. - tools/ is out of the coverage denominator; the report measures the C. cspell ignores docs/CHANGELOG.md, which is generated from commit subjects. --- cspell.json | 3 +- sonar-project.properties | 100 +++++++++++++----- .../presentation/http/http2/h2_conn/h2_conn.c | 6 +- .../http/http3/tls13_rpk/tls13_rpk.c | 5 +- src/services/radio/ble_gatt/ble_gatt.c | 2 +- tools/ci_tooling/build/gen_cmake.py | 2 +- tools/crypto/gen_mlkem_kat.py | 9 +- tools/dev_env/goldenize.py | 2 +- tools/harness.py | 2 +- tools/repotools/lib/repotools/shape.py | 2 +- 10 files changed, 95 insertions(+), 38 deletions(-) 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/sonar-project.properties b/sonar-project.properties index 673bc95ce..f945e4202 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -48,6 +48,10 @@ sonar.cfamily.compile-commands=compile_commands.json # measures a subset of src/ and leaves it alone. sonar.coverageReportPaths=test/coverage.xml +# The coverage report is gcov over the C library; nothing measures tools/, whose Python is the repo's +# own tooling rather than shipped code. Left in, every tools/ line counts as uncovered new code. +sonar.coverage.exclusions=tools/** + # 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/** @@ -63,23 +67,69 @@ sonar.cpd.exclusions=core_setup/board_profiles/** # S3776, deep nesting S134, const-correctness S5817, dead code S125, security # hotspots) are intentionally NOT suppressed. # --------------------------------------------------------------------------- -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 +sonar.issue.ignore.multicriteria=vargs,qpool,httpc,pysec,pyredos,pyrand,uauri,uaurib,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. + +# S946 "address of stack memory is still referred to by a global": every module takes its operands +# through its V._args struct, and a caller routinely points a field at a local for the +# one synchronous call that consumes it (DashboardV.parse_control_args.key_out = key, then +# Dashboard.parse_control). The pointer is read only inside that call and every call writes its own +# args first, so the stale address left behind after the return is never dereferenced. The +# operands-in-V convention is the library's calling convention (docs/SYMBOLS.md). +sonar.issue.ignore.multicriteria.vargs.ruleKey=c:S946 +sonar.issue.ignore.multicriteria.vargs.resourceKey=**/* + +# S3519 "returned pointer points outside the original object": FALSE POSITIVE in quic_server.c. The +# slot pool lives in the caller's borrow at QSRV_OFF_POOL (QSRV_POOL(work)[i], i < MAX_CONNS), and +# the borrow is sized for it, but the analyzer sees only the uint8_t *work parameter and cannot. +sonar.issue.ignore.multicriteria.qpool.ruleKey=c:S3519 +sonar.issue.ignore.multicriteria.qpool.resourceKey=**/quic_server.c + +# S5332 "using HTTP is insecure": http_client.c parses the http:// scheme because it is an HTTP client; +# refusing the scheme is not a fix. https:// is the other arm of the same parse. +sonar.issue.ignore.multicriteria.httpc.ruleKey=c:S5332 +sonar.issue.ignore.multicriteria.httpc.resourceKey=**/http_client.c + +# Taint rules on tools/: every "path traversal" / "command injection" there is a developer's own +# command-line argument reaching the file or subprocess it names, on the developer's machine or in CI. +# There is no trust boundary to cross. src/ keeps every security rule. +sonar.issue.ignore.multicriteria.pysec.ruleKey=pythonsecurity:* +sonar.issue.ignore.multicriteria.pysec.resourceKey=tools/**/* + +# S5852 "regex vulnerable to catastrophic backtracking": the tools/ regexes read this repo's own source +# lines, not input anyone else controls. +sonar.issue.ignore.multicriteria.pyredos.ruleKey=python:S5852 +sonar.issue.ignore.multicriteria.pyredos.resourceKey=tools/**/* + +# S2245 "pseudorandom generator": gen_ed25519_comb.py seeds random to draw reproducible test scalars +# for the comb table's self-check. Deterministic on purpose; nothing secret comes out of it. +sonar.issue.ignore.multicriteria.pyrand.ruleKey=python:S2245 +sonar.issue.ignore.multicriteria.pyrand.resourceKey=**/gen_ed25519_comb.py + +# S5332 "using HTTP is insecure" in the OPC UA tools: http://opcfoundation.org/UA/... strings are +# namespace URIs - identifiers the spec defines with that exact spelling - not URLs that are fetched. +sonar.issue.ignore.multicriteria.uauri.ruleKey=python:S5332 +sonar.issue.ignore.multicriteria.uauri.resourceKey=**/nodeset.py +sonar.issue.ignore.multicriteria.uaurib.ruleKey=python:S5332 +sonar.issue.ignore.multicriteria.uaurib.resourceKey=**/uaspace.py # 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 +140,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 +188,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 +204,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 +212,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 +220,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 +234,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 +254,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 +272,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/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/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/services/radio/ble_gatt/ble_gatt.c b/src/services/radio/ble_gatt/ble_gatt.c index 544205f29..cc20fe40f 100644 --- a/src/services/radio/ble_gatt/ble_gatt.c +++ b/src/services/radio/ble_gatt/ble_gatt.c @@ -157,7 +157,7 @@ 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; } diff --git a/tools/ci_tooling/build/gen_cmake.py b/tools/ci_tooling/build/gen_cmake.py index f0fad304a..846489dd1 100644 --- a/tools/ci_tooling/build/gen_cmake.py +++ b/tools/ci_tooling/build/gen_cmake.py @@ -340,7 +340,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, ) From e21eabcc224d29867f85a1ebddab7ee70ca86af1 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Tue, 29 Sep 2026 23:03:57 +0000 Subject: [PATCH 002/185] sonar: drop the suppressions and coverage exclusion added in 478529a What is and is not a real finding is the project owner's call. Kept: the existing suppressions moved from cpp: to c: rule keys, so they apply to the C sources as written. --- sonar-project.properties | 48 +--------------------------------------- 1 file changed, 1 insertion(+), 47 deletions(-) diff --git a/sonar-project.properties b/sonar-project.properties index f945e4202..0e0661c6c 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -48,9 +48,6 @@ sonar.cfamily.compile-commands=compile_commands.json # measures a subset of src/ and leaves it alone. sonar.coverageReportPaths=test/coverage.xml -# The coverage report is gcov over the C library; nothing measures tools/, whose Python is the repo's -# own tooling rather than shipped code. Left in, every tools/ line counts as uncovered new code. -sonar.coverage.exclusions=tools/** # 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/** @@ -67,54 +64,11 @@ sonar.cpd.exclusions=core_setup/board_profiles/** # S3776, deep nesting S134, const-correctness S5817, dead code S125, security # hotspots) are intentionally NOT suppressed. # --------------------------------------------------------------------------- -sonar.issue.ignore.multicriteria=vargs,qpool,httpc,pysec,pyredos,pyrand,uauri,uaurib,carr,gmut,fptr,cmac,wbnd,hdr,mpar,vptr,rfor,rtyp,dstruct,jstr,aesctx,tdef,mord,sizeu,vlog,cfginc,ntrdecl,ntrloop,ntrjump,ntrnest,ntrcplx,ntrasgn +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. -# S946 "address of stack memory is still referred to by a global": every module takes its operands -# through its V._args struct, and a caller routinely points a field at a local for the -# one synchronous call that consumes it (DashboardV.parse_control_args.key_out = key, then -# Dashboard.parse_control). The pointer is read only inside that call and every call writes its own -# args first, so the stale address left behind after the return is never dereferenced. The -# operands-in-V convention is the library's calling convention (docs/SYMBOLS.md). -sonar.issue.ignore.multicriteria.vargs.ruleKey=c:S946 -sonar.issue.ignore.multicriteria.vargs.resourceKey=**/* - -# S3519 "returned pointer points outside the original object": FALSE POSITIVE in quic_server.c. The -# slot pool lives in the caller's borrow at QSRV_OFF_POOL (QSRV_POOL(work)[i], i < MAX_CONNS), and -# the borrow is sized for it, but the analyzer sees only the uint8_t *work parameter and cannot. -sonar.issue.ignore.multicriteria.qpool.ruleKey=c:S3519 -sonar.issue.ignore.multicriteria.qpool.resourceKey=**/quic_server.c - -# S5332 "using HTTP is insecure": http_client.c parses the http:// scheme because it is an HTTP client; -# refusing the scheme is not a fix. https:// is the other arm of the same parse. -sonar.issue.ignore.multicriteria.httpc.ruleKey=c:S5332 -sonar.issue.ignore.multicriteria.httpc.resourceKey=**/http_client.c - -# Taint rules on tools/: every "path traversal" / "command injection" there is a developer's own -# command-line argument reaching the file or subprocess it names, on the developer's machine or in CI. -# There is no trust boundary to cross. src/ keeps every security rule. -sonar.issue.ignore.multicriteria.pysec.ruleKey=pythonsecurity:* -sonar.issue.ignore.multicriteria.pysec.resourceKey=tools/**/* - -# S5852 "regex vulnerable to catastrophic backtracking": the tools/ regexes read this repo's own source -# lines, not input anyone else controls. -sonar.issue.ignore.multicriteria.pyredos.ruleKey=python:S5852 -sonar.issue.ignore.multicriteria.pyredos.resourceKey=tools/**/* - -# S2245 "pseudorandom generator": gen_ed25519_comb.py seeds random to draw reproducible test scalars -# for the comb table's self-check. Deterministic on purpose; nothing secret comes out of it. -sonar.issue.ignore.multicriteria.pyrand.ruleKey=python:S2245 -sonar.issue.ignore.multicriteria.pyrand.resourceKey=**/gen_ed25519_comb.py - -# S5332 "using HTTP is insecure" in the OPC UA tools: http://opcfoundation.org/UA/... strings are -# namespace URIs - identifiers the spec defines with that exact spelling - not URLs that are fetched. -sonar.issue.ignore.multicriteria.uauri.ruleKey=python:S5332 -sonar.issue.ignore.multicriteria.uauri.resourceKey=**/nodeset.py -sonar.issue.ignore.multicriteria.uaurib.ruleKey=python:S5332 -sonar.issue.ignore.multicriteria.uaurib.resourceKey=**/uaspace.py - # 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. From cd42cf2ff2f6aa6ade67f68eddea0647fb1171c5 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 01:19:17 +0000 Subject: [PATCH 003/185] ci: check out include/MMgr in the jobs that compile or package the library src/ moves onto MMgr, which is a submodule, and no workflow fetched it. Format, docs, interop and the discover/footprint jobs are left without it: none compiles against it, and the format job would otherwise walk MMgr's own sources. --- .github/workflows/arduino-build.yml | 2 ++ .github/workflows/codeql.yml | 2 ++ .github/workflows/esp-idf-build.yml | 2 ++ .github/workflows/esp32-build.yml | 2 ++ .github/workflows/pentest.yml | 2 ++ .github/workflows/release.yml | 3 +++ .github/workflows/sonar.yml | 1 + .github/workflows/test-report.yml | 1 + 8 files changed, 15 insertions(+) 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. From 01ba6aa25f10488f250e087255a6bc070d2a5b33 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 01:21:10 +0000 Subject: [PATCH 004/185] build: embedded_types as a submodule beside MMgr, at the commit MMgr pins MMgr's CMake fetches embedded_types (b0aacda) at configure time; the Arduino, PlatformIO and ESP-IDF builds have no such step and need it on disk. The CMake build is pointed at the same copy through FETCHCONTENT_SOURCE_DIR_EMBEDDED_TYPES so the two cannot drift. --- .gitmodules | 3 +++ include/CMakeLists.txt | 4 ++++ include/embedded_types | 1 + 3 files changed, 8 insertions(+) create mode 160000 include/embedded_types 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/include/CMakeLists.txt b/include/CMakeLists.txt index 233eabd88..a9e8ec616 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -25,5 +25,9 @@ protocore_add_module(include # 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") + # MMgr fetches embedded_types from GitHub at the SHA its deps/CMakeLists.txt pins. The submodule + # beside it is that same commit, and the Arduino, PlatformIO and ESP-IDF builds read it from there, + # so the CMake build is handed the same copy instead of fetching a second one. + set(FETCHCONTENT_SOURCE_DIR_EMBEDDED_TYPES "${CMAKE_CURRENT_SOURCE_DIR}/embedded_types") add_subdirectory(MMgr "${CMAKE_BINARY_DIR}/m") 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 From 4b09bad5f550dc1dcd19ab8b7047470945b07a6b Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 01:25:09 +0000 Subject: [PATCH 005/185] build: compile MMgr's sources as pc_mmgr under ProtoCore's flags MMgr's own CMake is not entered. It builds every module once per width environment for its suites, and reaches its include root through CMAKE_SOURCE_DIR, which is this tree's top once MMgr is a subdirectory, so every module failed on mmgr.h. pc_mmgr takes the same three include roots MMgr's mmgr_add_module gives a module and MMgr's default capability switches. --- include/CMakeLists.txt | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index a9e8ec616..0498e3859 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -12,22 +12,22 @@ 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") - # MMgr fetches embedded_types from GitHub at the SHA its deps/CMakeLists.txt pins. The submodule - # beside it is that same commit, and the Arduino, PlatformIO and ESP-IDF builds read it from there, - # so the CMake build is handed the same copy instead of fetching a second one. - set(FETCHCONTENT_SOURCE_DIR_EMBEDDED_TYPES "${CMAKE_CURRENT_SOURCE_DIR}/embedded_types") - add_subdirectory(MMgr "${CMAKE_BINARY_DIR}/m") +# 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") + file(GLOB_RECURSE PC_MMGR_SRCS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/MMgr/src/*.c") + add_library(pc_mmgr OBJECT ${PC_MMGR_SRCS}) + 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() From 43ca0c6aa179125ac56df1e200ec2256d6c1a645 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 19:28:36 +0000 Subject: [PATCH 006/185] harness: add MMgr and embedded_types include roots to the base include set --- test/harness.py | 14 ++++++++++++-- tools/ci_tooling/build/gen_cmake.py | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) 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/tools/ci_tooling/build/gen_cmake.py b/tools/ci_tooling/build/gen_cmake.py index 846489dd1..1aa28739e 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" From ea18dde40d2e39f3e78bada27cc70f6e041d79d1 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:05:11 +0000 Subject: [PATCH 007/185] build: compile MMgr's own source list as pc_mmgr and link it into every test env The GLOB compiled all five impensa_ancorae_acus profiles, which each define the same table, and two directories MMgr's build does not enter. --- include/CMakeLists.txt | 34 +++++++++++++++++++++++++++-- tools/ci_tooling/build/gen_cmake.py | 3 +++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 0498e3859..ac6f3ad5b 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -18,13 +18,43 @@ protocore_add_module(include # subdirectory. ProtoCore builds MMgr's sources as one more target under ProtoCore's own flags, as # the Arduino, PlatformIO and ESP-IDF builds do. # +# 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") - file(GLOB_RECURSE PC_MMGR_SRCS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/MMgr/src/*.c") - add_library(pc_mmgr OBJECT ${PC_MMGR_SRCS}) + 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" diff --git a/tools/ci_tooling/build/gen_cmake.py b/tools/ci_tooling/build/gen_cmake.py index 1aa28739e..b4ba9ffe5 100644 --- a/tools/ci_tooling/build/gen_cmake.py +++ b/tools/ci_tooling/build/gen_cmake.py @@ -311,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) From b42b7947893b9a0cc568341dc96f3e818813a419 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:05:11 +0000 Subject: [PATCH 008/185] crypto/hash/sha256: move onto MMgr (memoria_operor, magna_extremitas, proximus_operor) --- src/crypto/hash/sha256/CMakeLists.txt | 3 +- src/crypto/hash/sha256/sha256.c | 75 ++++++++++++++------------- 2 files changed, 39 insertions(+), 39 deletions(-) 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 ----------------------------------------------------------- From 6e6607116bad320c9a882ddfcae60a06c3e28536 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:05:26 +0000 Subject: [PATCH 009/185] crypto/cipher/aes_block: move onto MMgr (memoria_operor) --- src/crypto/cipher/aes_block/CMakeLists.txt | 2 +- src/crypto/cipher/aes_block/aes_block.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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. */ From e1817298b1e7309fe7401640c55ee0ae393405de Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:05:47 +0000 Subject: [PATCH 010/185] crypto/ct_eq: move onto MMgr (memoria_operor) --- src/crypto/ct_eq/CMakeLists.txt | 2 +- src/crypto/ct_eq/ct_eq.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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. */ From d56c3a037936fd42d47dd29525e7b6009e13dbf0 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:06:25 +0000 Subject: [PATCH 011/185] crypto/cipher/chacha20: name the cellblock alignment the region asserts rely on --- src/crypto/cipher/chacha20/chacha20.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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, From 34dab50300f7fc081e21b70ebec659aeb5f682ec Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:06:25 +0000 Subject: [PATCH 012/185] crypto/hash/sha3: name the cellblock alignment the region asserts rely on --- src/crypto/hash/sha3/sha3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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, From 8873c466384df53c5d5d2345d2990f36e453c0ec Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:06:49 +0000 Subject: [PATCH 013/185] network_drivers/transport/diffserv: take its state from the worker cellblock --- src/network_drivers/transport/diffserv/CMakeLists.txt | 3 ++- src/network_drivers/transport/diffserv/diffserv.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) 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; } From 68a9c4e051d1cc54c897c59fea6464d0b1790bbf Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:07:32 +0000 Subject: [PATCH 014/185] server/core/failsafe: take its state from the worker cellblock --- src/server/core/failsafe/CMakeLists.txt | 3 ++- src/server/core/failsafe/failsafe.c | 4 ++-- test/test_matrix.json | 9 ++------- 3 files changed, 6 insertions(+), 10 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 703925b33..d3d515651 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -2492,13 +2492,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/core/test_failsafe" From d21be4e0fabcdb05f26275da54cf28678665d2dd Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:08:08 +0000 Subject: [PATCH 015/185] server/net/relay/relay: move onto MMgr (memoria_operor) --- src/server/net/relay/relay/CMakeLists.txt | 2 +- src/server/net/relay/relay/relay.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; } From c8a6591d66e6423a64a82e7063fc77d7ff1705ea Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:08:24 +0000 Subject: [PATCH 016/185] services/energy/iccp: move onto MMgr (memoria_operor) --- src/services/energy/iccp/CMakeLists.txt | 2 +- src/services/energy/iccp/iccp.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) 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..f2b353d64 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). + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 2, .src = val, + .bytes = val_len); // 1/4-byte field, int_content's >=1 result, or n built from those). } return 2 + val_len; } From acec028758cca1bbaf6a1bc88c8dfa9712933298 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:08:42 +0000 Subject: [PATCH 017/185] services/fieldbus/directnet: move onto MMgr (memoria_operor) --- src/services/fieldbus/directnet/CMakeLists.txt | 2 +- src/services/fieldbus/directnet/directnet.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; From b71d1d003a126bcf391e2baae87ee00afd814fa4 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:08:52 +0000 Subject: [PATCH 018/185] services/fieldbus/hostlink: move onto MMgr (memoria_operor) --- src/services/fieldbus/hostlink/CMakeLists.txt | 2 +- src/services/fieldbus/hostlink/hostlink.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; From 0d3b761e834cae6405de4689bc43fe385415c22f Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:08:59 +0000 Subject: [PATCH 019/185] services/fieldbus/lonworks: move onto MMgr (memoria_operor) --- src/services/fieldbus/lonworks/CMakeLists.txt | 2 +- src/services/fieldbus/lonworks/lonworks.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; } From 7f07b194fe953b194af408f4e740b01b0a242211 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:09:06 +0000 Subject: [PATCH 020/185] services/fieldbus/powerlink: move onto MMgr (memoria_operor) --- src/services/fieldbus/powerlink/CMakeLists.txt | 2 +- src/services/fieldbus/powerlink/powerlink.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; } From 2eb5af99f9d91c99c4d1a793a76516fb0997aac6 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:09:14 +0000 Subject: [PATCH 021/185] services/fieldbus/profinet: move onto MMgr (memoria_operor) --- src/services/fieldbus/profinet/CMakeLists.txt | 2 +- src/services/fieldbus/profinet/profinet.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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) { From 1e800464207bc4f4fdaa3e0ee451ae108ed5f80e Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:09:21 +0000 Subject: [PATCH 022/185] services/fieldbus/s7comm: move onto MMgr (memoria_operor) --- src/services/fieldbus/s7comm/CMakeLists.txt | 2 +- src/services/fieldbus/s7comm/s7comm.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 From 0d51cb957f56d7bdf4e385d0c7dc60614855e963 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:09:28 +0000 Subject: [PATCH 023/185] services/fieldbus/sercos: move onto MMgr (memoria_operor) --- src/services/fieldbus/sercos/CMakeLists.txt | 2 +- src/services/fieldbus/sercos/sercos.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; } From 9421f9cad875f5ed80bd22c46260dca2558d7af0 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:09:36 +0000 Subject: [PATCH 024/185] services/fieldbus/snp: move onto MMgr (memoria_operor) --- src/services/fieldbus/snp/CMakeLists.txt | 2 +- src/services/fieldbus/snp/snp.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; From eb066d05441d507891b62e300034b4ca10a6b213 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:09:48 +0000 Subject: [PATCH 025/185] services/timing_position/ubx: move onto MMgr (memoria_operor) --- src/services/timing_position/ubx/CMakeLists.txt | 2 +- src/services/timing_position/ubx/ubx.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 } } From ef2630d0b56e1abb984fa3b3fc767d729e9a6aa5 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:09:56 +0000 Subject: [PATCH 026/185] services/transportation/ocit: move onto MMgr (memoria_operor) --- src/services/transportation/ocit/CMakeLists.txt | 2 +- src/services/transportation/ocit/ocit.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; } From 32ea64ba34960c3c9f27af91e1f27fdb5c8101a0 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:10:03 +0000 Subject: [PATCH 027/185] shared/der: move onto MMgr (memoria_operor) --- src/shared/der/CMakeLists.txt | 2 +- src/shared/der/der.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) 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. From 35bbe88ec376a8eb1af94559af1f7a4a8e98cb87 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:10:23 +0000 Subject: [PATCH 028/185] crypto/asymmetric/bignum: move onto MMgr (memoria_operor) --- src/crypto/asymmetric/bignum/CMakeLists.txt | 2 +- src/crypto/asymmetric/bignum/bignum.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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++) From 35c920262a5bdd0501ce5845d074215e4b03e91d Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:10:28 +0000 Subject: [PATCH 029/185] crypto/mac/poly1305: move onto MMgr (memoria_operor) --- src/crypto/mac/poly1305/CMakeLists.txt | 2 +- src/crypto/mac/poly1305/poly1305.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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]; From 061ccaa1ebf7ef2ff812b60b86e70daec61a5fa3 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:11:14 +0000 Subject: [PATCH 030/185] network_drivers/application/http_range: move onto MMgr (cellularum_laboro) --- src/network_drivers/application/http_range/CMakeLists.txt | 2 +- src/network_drivers/application/http_range/http_range.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) 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; } From e16ec986138a5a33acfd6ef374b2318b3a1242cc Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:11:46 +0000 Subject: [PATCH 031/185] network_drivers/application/nts: move onto MMgr (memoria_operor) --- src/network_drivers/application/nts/CMakeLists.txt | 2 +- src/network_drivers/application/nts/nts.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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++) { From 465427d1f68de307a8516f404191c6babbc24c4d Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:11:47 +0000 Subject: [PATCH 032/185] network_drivers/network/dns/dns_wire: move onto MMgr (proximus_operor) --- src/network_drivers/network/dns/dns_wire/CMakeLists.txt | 2 +- src/network_drivers/network/dns/dns_wire/dns_wire.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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') { From 4ff545f542525bead61e5aabe4dbdda5c9f641f3 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:01 +0000 Subject: [PATCH 033/185] network_drivers/presentation/codec/hpack_prim: move onto MMgr (memoria_operor) --- .../presentation/codec/hpack_prim/CMakeLists.txt | 2 +- .../presentation/codec/hpack_prim/hpack_prim.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; } From 2f8481509792658cd2e7558faf935e335f1adabf Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:04 +0000 Subject: [PATCH 034/185] server/peripherals/dmx: move onto MMgr --- src/server/peripherals/dmx/CMakeLists.txt | 2 +- src/server/peripherals/dmx/dmx.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; From c0cab75bec3fcb049b447517afb15d5d075868da Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:11 +0000 Subject: [PATCH 035/185] services/fieldbus/cclink: move onto MMgr --- src/services/fieldbus/cclink/CMakeLists.txt | 2 +- src/services/fieldbus/cclink/cclink.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; From 3143f1a74e43289f42acc4a553ebac9ae849e484 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:18 +0000 Subject: [PATCH 036/185] services/fieldbus/cip: move onto MMgr --- src/services/fieldbus/cip/CMakeLists.txt | 2 +- src/services/fieldbus/cip/cip.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; From c6852160268f8705f0b52b4d1dcb645f59f11218 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:25 +0000 Subject: [PATCH 037/185] services/fieldbus/fins: move onto MMgr --- src/services/fieldbus/fins/CMakeLists.txt | 2 +- src/services/fieldbus/fins/fins.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; } From a2f8f1e0afdd9655b68bc12d406b6d245b6fc761 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:31 +0000 Subject: [PATCH 038/185] services/fieldbus/hart: move onto MMgr --- src/services/fieldbus/hart/CMakeLists.txt | 2 +- src/services/fieldbus/hart/hart.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; From f607e93e02a07b0fbcff063346ed782a6adaddf2 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:39 +0000 Subject: [PATCH 039/185] services/fieldbus/mbus: move onto MMgr --- src/services/fieldbus/mbus/CMakeLists.txt | 2 +- src/services/fieldbus/mbus/mbus.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; } From 1768a34d601b6ffdb40ddc8a3f72f2e72edc8e78 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:46 +0000 Subject: [PATCH 040/185] services/fieldbus/profibus: move onto MMgr --- src/services/fieldbus/profibus/CMakeLists.txt | 2 +- src/services/fieldbus/profibus/profibus.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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); From 8fbf2e2df0c25943d2c4155621ceeac16719735a Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:53 +0000 Subject: [PATCH 041/185] services/iot/dds: move onto MMgr --- src/services/iot/dds/CMakeLists.txt | 2 +- src/services/iot/dds/dds.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) 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; } From 99bc4bc794e65724919ac4b827b15d0f5933e093 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:12:59 +0000 Subject: [PATCH 042/185] services/system/control: move onto MMgr --- src/services/system/control/CMakeLists.txt | 2 +- src/services/system/control/control.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) 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..8fcbd13a7 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 + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &u, .src = &v, + .bytes = 4); // reinterpret the IEEE-754 bits, then emit little-endian 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) From 23762a7abbfbd614f36f5ef775c5875cb6f4a077 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:13:11 +0000 Subject: [PATCH 043/185] services/system/control: keep the reinterpret comment on its own line --- src/services/system/control/control.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/system/control/control.c b/src/services/system/control/control.c index 8fcbd13a7..c0667481d 100644 --- a/src/services/system/control/control.c +++ b/src/services/system/control/control.c @@ -174,8 +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; - EMBED_CALL(memor.cpy, MemoriaCfg, .dst = &u, .src = &v, - .bytes = 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); } From 00801f9cd9152a93ca0c31ac47c099b5fa9a5c7f Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:14:23 +0000 Subject: [PATCH 044/185] services/energy/iccp: keep the tlv comment on its own line --- src/services/energy/iccp/iccp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/energy/iccp/iccp.c b/src/services/energy/iccp/iccp.c index f2b353d64..005e1ec6d 100644 --- a/src/services/energy/iccp/iccp.c +++ b/src/services/energy/iccp/iccp.c @@ -27,8 +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) { - EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + 2, .src = val, - .bytes = 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; } From 6325bc34460d8e8b7126b388c01252e16f0a33cd Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:14:28 +0000 Subject: [PATCH 045/185] services/timing_position/gnss/rtcm3: move onto MMgr --- src/services/timing_position/gnss/rtcm3/CMakeLists.txt | 2 +- src/services/timing_position/gnss/rtcm3/rtcm3.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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 From 0781b40030e0adce2c086e08f2b8b9bc79b06fa4 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:14:34 +0000 Subject: [PATCH 046/185] services/transportation/wave: move onto MMgr --- src/services/transportation/wave/CMakeLists.txt | 2 +- src/services/transportation/wave/wave.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; } From 49b2237671fe8415f9eec640d5c9bab563a7c54b Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:14:41 +0000 Subject: [PATCH 047/185] network_drivers/application/binary_asset_blobs: move onto MMgr --- .../application/binary_asset_blobs/CMakeLists.txt | 2 +- .../application/binary_asset_blobs/binary_asset_blobs.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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..c4833e6f9 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 @@ -2161,11 +2161,11 @@ const char *protocore_binary_asset_blobs_css(uint8_t *work, const char *name) } // str.eq reads read_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; } From 5d61ecaa23cf2ae3799c748cb5c4aab35e00821e Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:15:19 +0000 Subject: [PATCH 048/185] binary_asset_blobs: generate the MMgr theme lookup from gen_theme_blobs.py --- .../application/binary_asset_blobs/binary_asset_blobs.c | 5 +++-- src/web_assets/wizard/gen_theme_blobs.py | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) 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 c4833e6f9..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 @@ -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 = 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 (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)) + 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/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;", " }", From fbcb58e74c48d5184fcb1122118d573cc999edef Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:15:50 +0000 Subject: [PATCH 049/185] network_drivers/presentation/http/http2/h2_frame: move onto MMgr --- .../presentation/http/http2/h2_frame/CMakeLists.txt | 2 +- .../presentation/http/http2/h2_frame/h2_frame.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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; } From 5dc0e51486438d8912973ccc5672b967b3176422 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:16:25 +0000 Subject: [PATCH 050/185] network_drivers/presentation/http/httpcache: move onto MMgr --- .../presentation/http/httpcache/CMakeLists.txt | 3 +-- .../presentation/http/httpcache/httpcache.c | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) 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; } From c2d6464b6841268c5ae5b8503df0890bdbebaacd Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:17:03 +0000 Subject: [PATCH 051/185] network_drivers/presentation/http/route/http_route: move onto MMgr --- .../presentation/http/route/http_route/CMakeLists.txt | 4 ++-- .../presentation/http/route/http_route/http_route.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) 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; } From f2cc08ee1fedfd52c34b309ab85a3e358ceaf9d9 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:17:35 +0000 Subject: [PATCH 052/185] services/energy/sunspec: move onto MMgr --- src/services/energy/sunspec/CMakeLists.txt | 3 +-- src/services/energy/sunspec/sunspec.c | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/services/energy/sunspec/CMakeLists.txt b/src/services/energy/sunspec/CMakeLists.txt index 1714e704e..77e20e77b 100644 --- a/src/services/energy/sunspec/CMakeLists.txt +++ b/src/services/energy/sunspec/CMakeLists.txt @@ -5,6 +5,5 @@ protocore_add_module(services/energy/sunspec GATE PROTOCORE_ENABLE_SUNSPEC SOURCES sunspec.c PRIVATE_DEPS - mmgr/protomem - mmgr/protostr + mmgr ) diff --git a/src/services/energy/sunspec/sunspec.c b/src/services/energy/sunspec/sunspec.c index 0c61daf1b..85bcd041a 100644 --- a/src/services/energy/sunspec/sunspec.c +++ b/src/services/energy/sunspec/sunspec.c @@ -10,8 +10,8 @@ #if PROTOCORE_ENABLE_SUNSPEC -#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/sunspec/sunspec.h" PROTOCORE_BEGIN_DECLS @@ -133,7 +133,7 @@ static proto_bool ss_put(SunSpecWriter *w, const uint8_t *p, size_t n) w->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 From 31e5d3b8a25019d0b02a27a6dbf1eae406c07370 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:17:41 +0000 Subject: [PATCH 053/185] services/iot/redis_resp: move onto MMgr --- src/services/iot/redis_resp/CMakeLists.txt | 3 +-- src/services/iot/redis_resp/redis_resp.c | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) 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'; From ca636b974b61663c403ca4a62dd2929322b74982 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:18:31 +0000 Subject: [PATCH 054/185] server/core/worker: worker slots borrow through MMgr cellblock guards Worker identity moves here from the old arena, the ghost slot's pools are the library's own LocusCarcerum, and the application binds each worker slot's guards with protocore_cellblocks_bind(). PROTO_ATOMIC_LOAD/STORE move to types.h. --- src/config/platform/types.h | 13 +++ src/server/core/worker/CMakeLists.txt | 5 +- src/server/core/worker/worker.c | 146 +++++++++++++++++++++++++- src/server/core/worker/worker.h | 72 ++++++++++++- 4 files changed, 225 insertions(+), 11 deletions(-) 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/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 From d39305ad46234bc1f6e6a661d54bc472aaeb5063 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:18:50 +0000 Subject: [PATCH 055/185] services/southbound/southbound: move onto MMgr --- .../southbound/southbound/CMakeLists.txt | 4 +-- .../southbound/southbound/southbound.c | 9 ++--- test/test_matrix.json | 33 ++----------------- 3 files changed, 9 insertions(+), 37 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index d3d515651..d2db06c38 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -1016,7 +1016,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -1034,30 +1033,15 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -6965,14 +6949,7 @@ "+", "+", "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -7903,14 +7880,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/southbound/southbound/test_southbound" From 987d624d4979f3668b477c1bda122d4477973eb9 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:19:12 +0000 Subject: [PATCH 056/185] network_drivers/application/smb/spnego: move onto MMgr --- .../application/smb/spnego/CMakeLists.txt | 2 +- src/network_drivers/application/smb/spnego/spnego.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) 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; } From e6beaffb7d273d39e0257af8e4406a37a19a225b Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:19:19 +0000 Subject: [PATCH 057/185] services/energy/iec60870: move onto MMgr --- src/services/energy/iec60870/CMakeLists.txt | 2 +- src/services/energy/iec60870/iec60870.c | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) 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; From 0560d4acb00f062708eb81fd7affb4518f80277c Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:19:26 +0000 Subject: [PATCH 058/185] services/fieldbus/cotp: move onto MMgr --- src/services/fieldbus/cotp/CMakeLists.txt | 2 +- src/services/fieldbus/cotp/cotp.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) 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; From b335a09dece1fe234f4c6cbab923740d3f18c7ff Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:19:33 +0000 Subject: [PATCH 059/185] services/fieldbus/simatic: move onto MMgr --- src/services/fieldbus/simatic/CMakeLists.txt | 4 ++-- src/services/fieldbus/simatic/simatic.c | 12 ++++++------ test/test_matrix.json | 9 ++------- 3 files changed, 10 insertions(+), 15 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index d2db06c38..bd737e798 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -7397,13 +7397,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/fieldbus/simatic/test_simatic" From d5c03c588d5230e78ee8f522f78ca994371eca2f Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:20:18 +0000 Subject: [PATCH 060/185] crypto/hash/sha1: move onto MMgr --- src/crypto/hash/sha1/CMakeLists.txt | 3 +-- src/crypto/hash/sha1/sha1.c | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) 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); } } From e38d99c61c1982e69c096f30ff7b7b188fcd5ae2 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:20:26 +0000 Subject: [PATCH 061/185] services/energy/mms: move onto MMgr --- src/services/energy/mms/CMakeLists.txt | 3 +-- src/services/energy/mms/mms.c | 13 +++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) 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..0c59a7f53 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 + // NOSONAR - see above: bound proven, analyzer follows an infeasible path + EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + k, .src = val, .bytes = n - k); } 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); } From 3d5e18612b41a60324ef607c120d4bef8e5491a2 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:20:42 +0000 Subject: [PATCH 062/185] services/energy/mms: keep the NOSONAR on the call it annotates --- src/services/energy/mms/mms.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/energy/mms/mms.c b/src/services/energy/mms/mms.c index 0c59a7f53..4887abaed 100644 --- a/src/services/energy/mms/mms.c +++ b/src/services/energy/mms/mms.c @@ -75,8 +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) { - // NOSONAR - see above: bound proven, analyzer follows an infeasible path - EMBED_CALL(memor.cpy, MemoriaCfg, .dst = out + k, .src = val, .bytes = n - k); + 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; } From ab4e0389c9ca2e531d38b53c7abff3e0326f2a2a Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:20:49 +0000 Subject: [PATCH 063/185] services/file_transfer/ftp/ftp: move onto MMgr --- src/services/file_transfer/ftp/ftp/CMakeLists.txt | 3 +-- src/services/file_transfer/ftp/ftp/ftp.c | 13 +++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) 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); From e88bc55ea680802b3c498a279b7a3df6d34b8ab0 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:20:56 +0000 Subject: [PATCH 064/185] services/iot/grpcweb: move onto MMgr --- src/services/iot/grpcweb/CMakeLists.txt | 3 +-- src/services/iot/grpcweb/grpcweb.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) 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; From e59f5b075b115644d30a63ff53c47eba384efdd2 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:21:07 +0000 Subject: [PATCH 065/185] services/iot/stomp: move onto MMgr --- src/services/iot/stomp/CMakeLists.txt | 3 +-- src/services/iot/stomp/stomp.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) 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; From 766a15b68524e2fe9494b74719a7bdeee617cf29 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:21:14 +0000 Subject: [PATCH 066/185] services/machine_tool/lsv2: move onto MMgr --- src/services/machine_tool/lsv2/CMakeLists.txt | 2 +- src/services/machine_tool/lsv2/lsv2.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) 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) From 48f19e1969bf9c4a711f960ec3198615774c8bc1 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:21:21 +0000 Subject: [PATCH 067/185] network_drivers/datalink/roaming: move onto MMgr --- .../datalink/roaming/CMakeLists.txt | 2 +- src/network_drivers/datalink/roaming/roaming.c | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) 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; } } From adf36753042adf81907d5c8de4efebebd95ac608 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:22:44 +0000 Subject: [PATCH 068/185] network_drivers/presentation/codec/deflate/rfc1951: move onto MMgr --- .../codec/deflate/rfc1951/CMakeLists.txt | 4 +-- .../codec/deflate/rfc1951/rfc1951.c | 20 ++++++----- .../codec/deflate/rfc1951/rfc1951.h | 6 ++-- .../codec/deflate/test_rfc1951/test_rfc1951.c | 34 +++++++++---------- 4 files changed, 32 insertions(+), 32 deletions(-) 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/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]); } From e8bdeef57c275352b9769da49afdbed7a97c3788 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:23:39 +0000 Subject: [PATCH 069/185] server/core/preempt_queue: move onto MMgr --- src/server/core/preempt_queue/CMakeLists.txt | 4 ++-- src/server/core/preempt_queue/preempt_queue.c | 15 +++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) 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]); } } From 43c04ca90ff66869b986c02cb94b90a7a8e01237 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:23:42 +0000 Subject: [PATCH 070/185] services/iot/lwm2m/lwm2m_tlv: move onto MMgr --- src/services/iot/lwm2m/lwm2m_tlv/CMakeLists.txt | 5 ++--- src/services/iot/lwm2m/lwm2m_tlv/lwm2m_tlv.c | 15 ++++++++------- test/test_matrix.json | 10 ++-------- 3 files changed, 12 insertions(+), 18 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index bd737e798..ed05ae170 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -4274,14 +4274,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/iot/lwm2m/test_lwm2m_tlv" From 8af1d4b608f5f60ffdbff2410b97cde329447784 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:24:53 +0000 Subject: [PATCH 071/185] services/iot/nats: move onto MMgr --- src/services/iot/nats/CMakeLists.txt | 3 +-- src/services/iot/nats/nats.c | 14 +++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) 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; } From d8c5d2a1dc6a927e01360b9ab0534e1dd4e4bdc5 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:24:59 +0000 Subject: [PATCH 072/185] services/machine_tool/focas: move onto MMgr --- src/services/machine_tool/focas/CMakeLists.txt | 2 +- src/services/machine_tool/focas/focas.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) 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; } From d652043ee1c7e9124f26df4e8f2accef5f04fe1c Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:25:06 +0000 Subject: [PATCH 073/185] network_drivers/presentation/http/http3/quic_packet: move onto MMgr --- .../http/http3/quic_packet/CMakeLists.txt | 2 +- .../http/http3/quic_packet/quic_packet.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) 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++) { From 71facf8b97ba732f60858aa169aed0755855883f Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:26:46 +0000 Subject: [PATCH 074/185] network_drivers/presentation/ssh/app/server: move onto MMgr --- .../ssh/app/server/CMakeLists.txt | 3 +-- .../presentation/ssh/app/server/server.c | 27 +++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) 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 From 7aaf003d5fc2d63ee9f5408b9dd9687c0bc41c07 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:26:49 +0000 Subject: [PATCH 075/185] server/web/spa_router: move onto MMgr --- src/server/web/spa_router/CMakeLists.txt | 3 +-- src/server/web/spa_router/spa_router.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) 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 From 2bc3cb728be71de2f0bb1faf24cab40485056fba Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:26:57 +0000 Subject: [PATCH 076/185] services/fieldbus/bacnet: move onto MMgr --- src/services/fieldbus/bacnet/CMakeLists.txt | 2 +- src/services/fieldbus/bacnet/bacnet.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) 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) From ae3eda674c4825ba5428cc44cad39398dbc488ae Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:26:59 +0000 Subject: [PATCH 077/185] services/iot/xmpp: move onto MMgr --- src/services/iot/xmpp/CMakeLists.txt | 3 +-- src/services/iot/xmpp/xmpp.c | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) 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; } From 0a3c6b8178480879a8bc39773ca042f5066b6b15 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:27:10 +0000 Subject: [PATCH 078/185] services/energy/goose: move onto MMgr --- src/services/energy/goose/CMakeLists.txt | 3 +-- src/services/energy/goose/goose.c | 17 +++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) 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; From 670330f2007cea6ba1aa90eb1a910f069a8c1e48 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:27:20 +0000 Subject: [PATCH 079/185] server/storage/config_store: move onto MMgr --- .../storage/config_store/CMakeLists.txt | 5 ++-- .../storage/config_store/config_store.c | 22 ++++++++++-------- test/test_matrix.json | 23 ++++--------------- 3 files changed, 18 insertions(+), 32 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index ed05ae170..100e35be5 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -1098,18 +1098,9 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": ["unit/src/server/storage/config_io/test_config_io"], "extra_scripts": ["pre:test/gen_test_runners.py"] @@ -1120,14 +1111,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": ["unit/src/server/storage/config_store/test_config_store"], "extra_scripts": ["pre:test/gen_test_runners.py"] From 905f2629bfb9d3f08fd8d9bd7d6a89bc894a26f6 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:27:23 +0000 Subject: [PATCH 080/185] services/instrumentation/hislip: move onto MMgr --- .../instrumentation/hislip/CMakeLists.txt | 4 +--- src/services/instrumentation/hislip/hislip.c | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) 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); } From 2176cda79acdc02572ab626fcced16bb1534cadb Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:27:26 +0000 Subject: [PATCH 081/185] services/radio/espnow: move onto MMgr --- src/services/radio/espnow/CMakeLists.txt | 4 ++-- src/services/radio/espnow/espnow.c | 21 +++++++++++---------- test/test_matrix.json | 9 ++------- 3 files changed, 15 insertions(+), 19 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 100e35be5..f4a230a1c 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -2390,13 +2390,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/radio/espnow/test_espnow" From 69b9d96d905b7f2005cc62ee005c6330333e56a9 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:27:28 +0000 Subject: [PATCH 082/185] services/instrumentation/vxi11: move onto MMgr --- .../instrumentation/vxi11/CMakeLists.txt | 4 +--- src/services/instrumentation/vxi11/vxi11.c | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 13 deletions(-) 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); } From 4f91a76ed2d6e35c301e6ef9268dee2c2f46c184 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:27:48 +0000 Subject: [PATCH 083/185] crypto/hash/md: move onto MMgr --- src/crypto/hash/md/CMakeLists.txt | 4 +--- src/crypto/hash/md/md.c | 17 ++++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) 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++) From beb236df66202fea94a69de262b8661157f3bf33 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:27:55 +0000 Subject: [PATCH 084/185] network_drivers/application/ptp: move onto MMgr --- .../application/ptp/CMakeLists.txt | 2 +- src/network_drivers/application/ptp/ptp.c | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) 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; From 59faeeb75550e0be688d941d2d3db27f68271098 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:27:58 +0000 Subject: [PATCH 085/185] services/iot/mqtt/mqtt_sn: move onto MMgr --- src/services/iot/mqtt/mqtt_sn/CMakeLists.txt | 3 +-- src/services/iot/mqtt/mqtt_sn/mqtt_sn.c | 24 +++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) 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; From 028232ffdd6071687c837f4e62b314325995dcb8 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:28:01 +0000 Subject: [PATCH 086/185] services/iot/protobuf: move onto MMgr --- src/services/iot/protobuf/CMakeLists.txt | 5 ++--- src/services/iot/protobuf/protobuf.c | 23 ++++++++++++----------- test/test_matrix.json | 20 ++++---------------- 3 files changed, 18 insertions(+), 30 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index f4a230a1c..6600ded40 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -5967,14 +5967,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/iot/protobuf/test_protobuf" @@ -7894,14 +7888,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/iot/sparkplug/test_sparkplug" From c2030675fde518cd40f51a73cc64c6c9699b5268 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:28:01 +0000 Subject: [PATCH 087/185] services/storage/wal/wal: move onto MMgr --- src/services/storage/wal/wal/CMakeLists.txt | 3 +-- src/services/storage/wal/wal/wal.c | 23 +++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) 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) From 815dc5aee99d697b2c25c8ddf0bcbed144aaf822 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:28:04 +0000 Subject: [PATCH 088/185] shared/pcap: move onto MMgr --- src/shared/pcap/CMakeLists.txt | 2 +- src/shared/pcap/pcap.c | 24 +++++++++++++----------- src/shared/pcap/pcap.h | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) 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 From 996e60d041a58076b9e7238ebffb8d7a0313804b Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:28:10 +0000 Subject: [PATCH 089/185] crypto/mac/ghash: move onto MMgr --- src/crypto/mac/ghash/CMakeLists.txt | 2 +- src/crypto/mac/ghash/ghash.c | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) 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 ----------------------------------------------------------- From b74dee1ffdc63edfcad0f230267d170816dac26d Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:28:13 +0000 Subject: [PATCH 090/185] services/fieldbus/enip: move onto MMgr --- src/services/fieldbus/enip/CMakeLists.txt | 2 +- src/services/fieldbus/enip/enip.c | 26 +++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) 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; From 06af33e025a745dcdc7d9279c813862994ea908a Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:28:16 +0000 Subject: [PATCH 091/185] services/storage/sqlite/sqlite_format: move onto MMgr --- .../sqlite/sqlite_format/CMakeLists.txt | 3 +-- .../sqlite/sqlite_format/sqlite_format.c | 27 ++++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) 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}; From fbc195501f34b2236100a9b7cc04b9ebcb653b04 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:30:07 +0000 Subject: [PATCH 092/185] server/signaling/hw_health: move onto MMgr --- src/server/signaling/hw_health/CMakeLists.txt | 2 +- src/server/signaling/hw_health/hw_health.c | 28 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) 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) From 0cf489f5a2fb06dfce8878848b98efe5e892f1a5 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:30:14 +0000 Subject: [PATCH 093/185] services/machine_tool/haas_mdc: move onto MMgr --- .../machine_tool/haas_mdc/CMakeLists.txt | 2 +- src/services/machine_tool/haas_mdc/haas_mdc.c | 26 +++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) 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..e4c2ce314 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); + sb_q = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = buf, .cap = cap, .at = sb_q, + .ch = '\n'); // [NGC] Query Format: the query is "terminated with a new line" + 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); + sb_var = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = buf, .cap = cap, .at = sb_var, + .ch = '\n'); // the ?Q600 line is a query in the ?Q### family, same sentence + 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) From 589c0368a27003b48a4ec81c060c44557796949b Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:30:29 +0000 Subject: [PATCH 094/185] services/machine_tool/haas_mdc: keep each comment above the call it annotates --- src/services/machine_tool/haas_mdc/haas_mdc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/services/machine_tool/haas_mdc/haas_mdc.c b/src/services/machine_tool/haas_mdc/haas_mdc.c index e4c2ce314..629368869 100644 --- a/src/services/machine_tool/haas_mdc/haas_mdc.c +++ b/src/services/machine_tool/haas_mdc/haas_mdc.c @@ -90,8 +90,8 @@ size_t protocore_haas_mdc_build_q(char *buf, size_t cap, uint16_t qnum) 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); - sb_q = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = buf, .cap = cap, .at = sb_q, - .ch = '\n'); // [NGC] Query Format: the query is "terminated with a new line" + // [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); } @@ -105,8 +105,8 @@ size_t protocore_haas_mdc_build_var(char *buf, size_t cap, uint32_t var) 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); - sb_var = EMBED_CALL(verba_littera.ch, VerbaLitteraCfg, .out = buf, .cap = cap, .at = sb_var, - .ch = '\n'); // the ?Q600 line is a query in the ?Q### family, same sentence + // 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); } From 066ac81de8268eacca35f9ccab0aff66c2f1e771 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:30:37 +0000 Subject: [PATCH 095/185] network_drivers/session/scp/scp: move onto MMgr --- .../session/scp/scp/CMakeLists.txt | 3 +- src/network_drivers/session/scp/scp/scp.c | 28 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) 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 From 3051a1cdf24830e509a73020e59576d5230986ff Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:30:41 +0000 Subject: [PATCH 096/185] services/file_transfer/http_delivery: move onto MMgr --- .../http_delivery/CMakeLists.txt | 2 +- .../http_delivery/http_delivery.c | 40 ++++++++++--------- test/test_matrix.json | 26 ++---------- 3 files changed, 26 insertions(+), 42 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 6600ded40..66cf0caa2 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -4163,18 +4163,9 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/shared/log/test_log" @@ -4190,18 +4181,9 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/core/test_logbuf" From 98a97868b4ac4619ab176f1152566950f57a4866 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:31:16 +0000 Subject: [PATCH 097/185] server/core/logbuf: move onto MMgr --- src/server/core/logbuf/CMakeLists.txt | 6 ++---- src/server/core/logbuf/logbuf.c | 21 +++++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) 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) { From 5eeb920c408574462e823dc79edb7800607c11c7 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:31:19 +0000 Subject: [PATCH 098/185] services/instrumentation/scpi: move onto MMgr --- .../instrumentation/scpi/CMakeLists.txt | 4 +-- src/services/instrumentation/scpi/scpi.c | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 15 deletions(-) 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 From 75d90343714763899ecd680ebab93f53a35f7e99 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:31:28 +0000 Subject: [PATCH 099/185] server/core/guardrails: move onto MMgr --- src/server/core/guardrails/CMakeLists.txt | 4 +-- src/server/core/guardrails/guardrails.c | 38 ++++++++++++++--------- test/test_matrix.json | 12 ++----- 3 files changed, 27 insertions(+), 27 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 66cf0caa2..81fd8cdd4 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -2931,18 +2931,10 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/core/guardrails/test_guardrails" From e7474ad6c1f795852daffcfd010f9dbd34bacb76 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:31:31 +0000 Subject: [PATCH 100/185] server/core/power_mgmt: move onto MMgr --- src/server/core/power_mgmt/CMakeLists.txt | 4 +-- src/server/core/power_mgmt/power_mgmt.c | 33 ++++++++++++----------- test/test_matrix.json | 12 ++------- 3 files changed, 22 insertions(+), 27 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 81fd8cdd4..5b3dd58b6 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -5710,18 +5710,10 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/core/power_mgmt/test_power_mgmt" From efd718ade64ff688210be01ad5a8437835d8ba47 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:31:34 +0000 Subject: [PATCH 101/185] services/fieldbus/melsec: move onto MMgr --- src/services/fieldbus/melsec/CMakeLists.txt | 3 +- src/services/fieldbus/melsec/melsec.c | 43 +++++++++++++-------- 2 files changed, 27 insertions(+), 19 deletions(-) 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; From 76c477b94a883a3d0c7e027973351cd1d19898df Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:31:37 +0000 Subject: [PATCH 102/185] services/iot/amqp: move onto MMgr --- src/services/iot/amqp/CMakeLists.txt | 3 +- src/services/iot/amqp/amqp.c | 43 ++++++++++++++++------------ 2 files changed, 26 insertions(+), 20 deletions(-) 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; From 829ca47e35327a491b949ac4803441f4412e5465 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:32:03 +0000 Subject: [PATCH 103/185] services/transportation/utmc: move onto MMgr --- .../transportation/utmc/CMakeLists.txt | 3 +- src/services/transportation/utmc/utmc.c | 50 ++++++++++--------- 2 files changed, 27 insertions(+), 26 deletions(-) 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..b8bc979f7 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,40 @@ 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); + 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); + 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 +72,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; } From 3335c359126ae3738c3e615f80cc62614f30897e Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:33:46 +0000 Subject: [PATCH 104/185] services/transportation/utmc: refuse a missing or empty buffer before writing --- src/services/transportation/utmc/utmc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/services/transportation/utmc/utmc.c b/src/services/transportation/utmc/utmc.c index b8bc979f7..24c95169d 100644 --- a/src/services/transportation/utmc/utmc.c +++ b/src/services/transportation/utmc/utmc.c @@ -36,6 +36,10 @@ static size_t put_u(char *out, size_t cap, size_t at, uint32_t v) size_t protocore_utmc_request(const char *object_id, char *out, size_t cap) { + if (!out || cap == 0) + { + return 0; + } size_t b = 0; b = EMBED_CALL(verba_textus.put, VerbaTextusCfg, .out = out, .cap = cap, .at = b, .text = " Date: Wed, 30 Sep 2026 20:33:52 +0000 Subject: [PATCH 105/185] network_drivers/application/smb/ntlmssp: move onto MMgr --- .../application/smb/ntlmssp/CMakeLists.txt | 3 +- .../application/smb/ntlmssp/ntlmssp.c | 58 ++++++++++--------- 2 files changed, 33 insertions(+), 28 deletions(-) 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; } From d8647e7f96ed90e84f6b4da692d6cd0701b16699 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:35:07 +0000 Subject: [PATCH 106/185] network_drivers/presentation/codec/base64: move onto MMgr --- .../presentation/codec/base64/CMakeLists.txt | 3 +- .../presentation/codec/base64/base64.c | 53 +++++++++++-------- 2 files changed, 32 insertions(+), 24 deletions(-) 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; From 8086d3169419e98af30650911ef3a3dec685d9ac Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:36:02 +0000 Subject: [PATCH 107/185] services/machine_tool/atc: move onto MMgr --- src/services/machine_tool/atc/CMakeLists.txt | 3 +- src/services/machine_tool/atc/atc.c | 66 ++++++++++---------- 2 files changed, 33 insertions(+), 36 deletions(-) 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) { From 3cbde5f03b541f12c99ca47918345d136a692492 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:36:11 +0000 Subject: [PATCH 108/185] services/iot/graphql: move onto MMgr --- src/services/iot/graphql/CMakeLists.txt | 6 +-- src/services/iot/graphql/graphql.c | 59 ++++++++++++++----------- test/test_matrix.json | 24 +--------- 3 files changed, 38 insertions(+), 51 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 5b3dd58b6..e31549f48 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -2892,17 +2892,9 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/iot/graphql/test_graphql" @@ -5492,23 +5484,11 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+", "+", From dde169b653c841060ea2428cdc2169b17420aad6 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:36:20 +0000 Subject: [PATCH 109/185] services/net/flow_export: move onto MMgr --- src/services/net/flow_export/CMakeLists.txt | 5 +- src/services/net/flow_export/flow_export.c | 60 +++++++++++---------- test/test_matrix.json | 10 +--- 3 files changed, 35 insertions(+), 40 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index e31549f48..0d001ed59 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -2564,14 +2564,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/net/flow_export/test_flow_export" From 0edc0ad962a839ac4db19e0de15baaa0634b05ce Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:36:23 +0000 Subject: [PATCH 110/185] network_drivers/transport/proxy_protocol: move onto MMgr --- .../transport/proxy_protocol/CMakeLists.txt | 3 +- .../transport/proxy_protocol/proxy_protocol.c | 76 +++++++++++-------- 2 files changed, 46 insertions(+), 33 deletions(-) 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 From a0e43873c6d09e6f0a8297902e6c6281b8217ac9 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:36:42 +0000 Subject: [PATCH 111/185] services/timing_position/nmea0183: move onto MMgr --- .../timing_position/nmea0183/CMakeLists.txt | 3 +- .../timing_position/nmea0183/nmea0183.c | 93 ++++++++++++------- .../timing_position/nmea0183/nmea0183.h | 2 +- 3 files changed, 61 insertions(+), 37 deletions(-) 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 From 5f6b4f84cc64162560c039e32d56abeffe583c40 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:37:23 +0000 Subject: [PATCH 112/185] crypto/hash/sha384: move onto MMgr --- src/crypto/hash/sha384/CMakeLists.txt | 3 +- src/crypto/hash/sha384/sha384.c | 67 ++++++++++++++------------- 2 files changed, 35 insertions(+), 35 deletions(-) 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 ----------------------------------------------------------- From 8b9ea603b932b2788a0e05aa0ec045432fbb0833 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:37:30 +0000 Subject: [PATCH 113/185] server/storage/partition_monitor: move onto MMgr --- .../storage/partition_monitor/CMakeLists.txt | 3 +- .../partition_monitor/partition_monitor.c | 65 ++++++++++--------- 2 files changed, 34 insertions(+), 34 deletions(-) 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; From 1f0ea49ec2b20f348159cc5ee1beef60f768179a Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:38:39 +0000 Subject: [PATCH 114/185] services/energy/openadr: move onto MMgr --- src/services/energy/openadr/CMakeLists.txt | 2 +- src/services/energy/openadr/openadr.c | 95 ++++++++++++---------- 2 files changed, 52 insertions(+), 45 deletions(-) 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 From b97bf9cd85dcf2dae2ef55675cc74133d15fac67 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:38:48 +0000 Subject: [PATCH 115/185] crypto/hash/sha512: move onto MMgr --- src/crypto/hash/sha512/CMakeLists.txt | 3 +- src/crypto/hash/sha512/sha512.c | 71 ++++++++++++++------------- 2 files changed, 37 insertions(+), 37 deletions(-) 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 ----------------------------------------------------------- From 06710d2fb8e6b0af29a53467e215bbfea8f5093a Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:38:51 +0000 Subject: [PATCH 116/185] services/instrumentation/gpib: move onto MMgr --- .../instrumentation/gpib/CMakeLists.txt | 3 +- src/services/instrumentation/gpib/gpib.c | 84 +++++++++++-------- 2 files changed, 50 insertions(+), 37 deletions(-) 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; From 41f102b67539e015711c08f863a708112b7bd231 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:39:29 +0000 Subject: [PATCH 117/185] services/energy/sep2: move onto MMgr --- src/services/energy/sep2/CMakeLists.txt | 2 +- src/services/energy/sep2/sep2.c | 117 ++++++++++++++---------- 2 files changed, 68 insertions(+), 51 deletions(-) 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 = " Date: Wed, 30 Sep 2026 20:39:38 +0000 Subject: [PATCH 118/185] services/machine_tool/fanuc_j519: move onto MMgr --- .../machine_tool/fanuc_j519/CMakeLists.txt | 3 +- .../machine_tool/fanuc_j519/fanuc_j519.c | 107 ++++++++++-------- 2 files changed, 58 insertions(+), 52 deletions(-) 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; From fa2c65b0ad7efce7b1317f22fdd16803b03f8551 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:39:52 +0000 Subject: [PATCH 119/185] services/timing_position/gnss/ntrip_caster: move onto MMgr --- .../gnss/ntrip_caster/CMakeLists.txt | 3 +- .../gnss/ntrip_caster/ntrip_caster.c | 149 ++++++++++-------- 2 files changed, 85 insertions(+), 67 deletions(-) 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; From b070cbc5dcda98d280eae33423032bd792c0e164 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:39:55 +0000 Subject: [PATCH 120/185] services/fieldbus/ads: move onto MMgr --- src/services/fieldbus/ads/CMakeLists.txt | 3 +- src/services/fieldbus/ads/ads.c | 140 +++++++++++++---------- 2 files changed, 78 insertions(+), 65 deletions(-) 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) { From aec5665bae2d5e3aee2d3b59b2d43f94c3e89568 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:15 +0000 Subject: [PATCH 121/185] server/web/dashboard: move onto MMgr --- src/server/web/dashboard/CMakeLists.txt | 6 +- src/server/web/dashboard/dashboard.c | 158 +++++++++++++----------- test/test_matrix.json | 13 +- 3 files changed, 93 insertions(+), 84 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 0d001ed59..fae315347 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -1336,19 +1336,10 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/web/dashboard/test_dashboard" From 1c45c8eb22f6c68ff4ca35e28c62143b7f6dec34 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:24 +0000 Subject: [PATCH 122/185] crypto/aead/chachapoly: move onto MMgr --- src/crypto/aead/chachapoly/chachapoly.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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( From cb948a001c8d6e5744f94a60a72cbb66b11c83b8 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:25 +0000 Subject: [PATCH 123/185] network_drivers/presentation/ssh/transport/ssh_kexhash: move onto MMgr --- .../presentation/ssh/transport/ssh_kexhash/ssh_kexhash.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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, From 6bac223011beeb9e0109c5c5014f5e45517d0189 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:28 +0000 Subject: [PATCH 124/185] crypto/x509/x509: move onto MMgr --- src/crypto/x509/x509/CMakeLists.txt | 2 +- src/crypto/x509/x509/x509.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; From d42ae036ff4f4a6163b65ba92584e6a4070900ce Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:31 +0000 Subject: [PATCH 125/185] network_drivers/presentation/codec/inflate: move onto MMgr --- src/network_drivers/presentation/codec/inflate/CMakeLists.txt | 2 +- src/network_drivers/presentation/codec/inflate/inflate.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; From 194e53b0eafaa9da4dd8772df78239f4f0d15e31 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:34 +0000 Subject: [PATCH 126/185] services/fieldbus/mbplus: move onto MMgr --- src/services/fieldbus/mbplus/CMakeLists.txt | 2 +- src/services/fieldbus/mbplus/mbplus.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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; From 9ff2444b3f6182561a93d2bf7fd15f980518993d Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:37 +0000 Subject: [PATCH 127/185] services/machine_tool/dnc/dnc_stream: move onto MMgr --- src/services/machine_tool/dnc/dnc_stream/CMakeLists.txt | 2 +- src/services/machine_tool/dnc/dnc_stream/dnc_stream.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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); From ecef2ccd81c742936e691b186e68ec63da2720b0 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:40 +0000 Subject: [PATCH 128/185] services/radio/enocean: move onto MMgr --- src/services/radio/enocean/CMakeLists.txt | 2 +- src/services/radio/enocean/enocean.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 From 481f594304b7d992edf1503fcde29b495efb4689 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:43 +0000 Subject: [PATCH 129/185] services/transportation/nema_ts2: move onto MMgr --- src/services/transportation/nema_ts2/CMakeLists.txt | 2 +- src/services/transportation/nema_ts2/nema_ts2.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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 From 56684b53618d3e319af06f24787d2885fb2e5a85 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:47 +0000 Subject: [PATCH 130/185] network_drivers/presentation/http/http3/h3_frame: move onto MMgr --- .../presentation/http/http3/h3_frame/CMakeLists.txt | 2 +- .../presentation/http/http3/h3_frame/h3_frame.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) 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; } From b57ecde4e90c3ccbfc1ee0ed010eb95ad5a7b1c9 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:50 +0000 Subject: [PATCH 131/185] server/peripherals/pca9685: move onto MMgr --- src/server/peripherals/pca9685/CMakeLists.txt | 3 ++- src/server/peripherals/pca9685/pca9685.c | 10 +++++----- test/test_matrix.json | 19 ++++--------------- 3 files changed, 11 insertions(+), 21 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index fae315347..1e44c578b 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -376,15 +376,9 @@ "+", "+", "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "env/peripherals/test_bus_wire" @@ -5332,14 +5326,9 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/pca9685/test_pca9685" From 7397a80faefb359a85e0b712c380793293838272 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:54 +0000 Subject: [PATCH 132/185] server/peripherals/rcwl0516: move onto MMgr --- src/server/peripherals/rcwl0516/CMakeLists.txt | 3 ++- src/server/peripherals/rcwl0516/rcwl0516.c | 10 +++++----- test/test_matrix.json | 9 ++------- 3 files changed, 9 insertions(+), 13 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 1e44c578b..01567c7db 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -6526,13 +6526,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/rcwl0516/test_rcwl0516" From 80a706ca909721d929b455ca24b4dedcbe1bf1f1 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:40:57 +0000 Subject: [PATCH 133/185] server/peripherals/rtc: move onto MMgr --- src/server/peripherals/rtc/CMakeLists.txt | 3 ++- src/server/peripherals/rtc/rtc.c | 8 ++++---- test/test_matrix.json | 9 ++------- 3 files changed, 8 insertions(+), 12 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 01567c7db..68a2d370e 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -6760,13 +6760,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/rtc/test_rtc" From 35d7432de5479d328c56eebda401d039d41ae532 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:01 +0000 Subject: [PATCH 134/185] server/peripherals/sen0192: move onto MMgr --- src/server/peripherals/sen0192/CMakeLists.txt | 3 ++- src/server/peripherals/sen0192/sen0192.c | 8 ++++---- test/test_matrix.json | 9 ++------- 3 files changed, 8 insertions(+), 12 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 68a2d370e..dc50caedf 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -7043,13 +7043,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/sen0192/test_sen0192" From 68120523db81308b1595aa5e936656db7de79384 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:05 +0000 Subject: [PATCH 135/185] server/peripherals/smbus: move onto MMgr --- src/server/peripherals/smbus/CMakeLists.txt | 3 ++- src/server/peripherals/smbus/smbus.c | 8 ++++---- test/test_matrix.json | 18 ++++-------------- 3 files changed, 10 insertions(+), 19 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index dc50caedf..5f0ddfcfb 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -5605,14 +5605,9 @@ "src": [ "+", "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/test_pmbus" @@ -7521,14 +7516,9 @@ ], "src": [ "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/test_smbus" From 3aa8fdc96f6ed0af784c62f615a67d320c80910f Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:08 +0000 Subject: [PATCH 136/185] server/peripherals/vl53l0x: move onto MMgr --- src/server/peripherals/vl53l0x/CMakeLists.txt | 3 ++- src/server/peripherals/vl53l0x/vl53l0x.c | 8 ++++---- test/test_matrix.json | 9 ++------- 3 files changed, 8 insertions(+), 12 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 5f0ddfcfb..b9aeb9f16 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -10118,13 +10118,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/vl53l0x/test_vl53l0x" From c8c1ecdfcf70c75b8b2c9f18a2466a323182f1d1 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:12 +0000 Subject: [PATCH 137/185] server/signaling/bus_capture: move onto MMgr --- src/server/signaling/bus_capture/CMakeLists.txt | 3 ++- src/server/signaling/bus_capture/bus_capture.c | 8 ++++---- test/test_matrix.json | 10 ++-------- 3 files changed, 8 insertions(+), 13 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index b9aeb9f16..7a0653c78 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -342,16 +342,10 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/signaling/test_bus_capture" From d2605f073d6b29a880e12df183271773015f3f49 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:13 +0000 Subject: [PATCH 138/185] crypto/mac/hmac_sha256: move onto MMgr --- src/crypto/mac/hmac_sha256/CMakeLists.txt | 2 +- src/crypto/mac/hmac_sha256/hmac_sha256.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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. From 5f06cd2de6cf418959d8e456674f22a5ab5438be Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:14 +0000 Subject: [PATCH 139/185] crypto/mac/hmac_sha384: move onto MMgr --- src/crypto/mac/hmac_sha384/CMakeLists.txt | 2 +- src/crypto/mac/hmac_sha384/hmac_sha384.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) 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++) { From 3fcce07f7ab0d7b95785a559ed224419fefbbf39 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:17 +0000 Subject: [PATCH 140/185] network_drivers/presentation/http/http3/quic_tp: move onto MMgr --- .../presentation/http/http3/quic_tp/CMakeLists.txt | 2 +- .../presentation/http/http3/quic_tp/quic_tp.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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; From 55a35ea6f1f15e50b721430c9baf57221267a08e Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:20 +0000 Subject: [PATCH 141/185] server/signaling/trace_capture: move onto MMgr --- src/server/signaling/trace_capture/CMakeLists.txt | 4 ++-- src/server/signaling/trace_capture/trace_capture.c | 9 +++++---- test/test_matrix.json | 9 ++------- 3 files changed, 9 insertions(+), 13 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 7a0653c78..0a8774e58 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -9840,13 +9840,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/signaling/test_trace_capture" From f7f802ecd550f728cfba915eed57da12cc2eddee Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:24 +0000 Subject: [PATCH 142/185] services/timing_position/gnss/gnss_survey: move onto MMgr --- .../timing_position/gnss/gnss_survey/CMakeLists.txt | 3 +-- .../timing_position/gnss/gnss_survey/gnss_survey.c | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) 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; From 6fbe41ca9630f5319987600a037a65064f717ee6 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:27 +0000 Subject: [PATCH 143/185] crypto/mac/hmac_sha512: move onto MMgr --- src/crypto/mac/hmac_sha512/CMakeLists.txt | 2 +- src/crypto/mac/hmac_sha512/hmac_sha512.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) 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++) { From d1fc9e65b698ce39f2548089cb3758d0deb1f8ff Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:30 +0000 Subject: [PATCH 144/185] network_drivers/presentation/http/http3/quic_frame: move onto MMgr --- .../presentation/http/http3/quic_frame/CMakeLists.txt | 2 +- .../presentation/http/http3/quic_frame/quic_frame.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) 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; } From 2c8c950443c27d924b5599be3852b3201db16f4b Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:31 +0000 Subject: [PATCH 145/185] server/io/middleware: move onto MMgr --- src/server/io/middleware/CMakeLists.txt | 2 +- src/server/io/middleware/middleware.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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; From f101942ef2b3bb807f585274428ea3135dc51704 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:34 +0000 Subject: [PATCH 146/185] server/peripherals/mpr121: move onto MMgr --- src/server/peripherals/mpr121/CMakeLists.txt | 4 ++-- src/server/peripherals/mpr121/mpr121.c | 14 +++++++------- test/test_matrix.json | 9 ++------- 3 files changed, 11 insertions(+), 16 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 0a8774e58..c8e8f94f0 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -4484,13 +4484,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/mpr121/test_mpr121" From 5e606e3fda311252e1e00e4b31365acb55ee3ac6 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:37 +0000 Subject: [PATCH 147/185] server/peripherals/sht3x: move onto MMgr --- src/server/peripherals/sht3x/CMakeLists.txt | 4 ++-- src/server/peripherals/sht3x/sht3x.c | 15 ++++++++------- test/test_matrix.json | 10 ++-------- 3 files changed, 12 insertions(+), 17 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index c8e8f94f0..e81d5d22d 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -7199,15 +7199,9 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/sht3x/test_sht3x" From 33304b0e4029c7fe3930d53b83c8d3954cad3177 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:41 +0000 Subject: [PATCH 148/185] server/net/gateway: move onto MMgr --- src/server/net/gateway/CMakeLists.txt | 4 ++-- src/server/net/gateway/gateway.c | 16 +++++++++------- test/test_matrix.json | 9 ++------- 3 files changed, 13 insertions(+), 16 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index e81d5d22d..1fb89983d 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -2760,13 +2760,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/net/gateway/test_gateway" From 27e877d95966ccd843aa5bae62811abc09fedf4c Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:44 +0000 Subject: [PATCH 149/185] server/peripherals/ads1115: move onto MMgr --- src/server/peripherals/ads1115/CMakeLists.txt | 4 ++-- src/server/peripherals/ads1115/ads1115.c | 17 +++++++++-------- test/test_matrix.json | 10 ++-------- 3 files changed, 13 insertions(+), 18 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 1fb89983d..099ed3664 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -90,14 +90,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ads1115/test_ads1115" From f00a7a709aca353226775ec74cded6c7e8517d48 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:41:48 +0000 Subject: [PATCH 150/185] server/peripherals/ina219: move onto MMgr --- src/server/peripherals/ina219/CMakeLists.txt | 4 ++-- src/server/peripherals/ina219/ina219.c | 15 ++++++++------- test/test_matrix.json | 10 ++-------- 3 files changed, 12 insertions(+), 17 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 099ed3664..0eca131be 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -3720,15 +3720,9 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ina219/test_ina219" From c81a3f03dab07512cbd1839c94bc14215c0fecc9 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:42:45 +0000 Subject: [PATCH 151/185] crypto/rng: move onto MMgr --- src/crypto/rng/CMakeLists.txt | 4 +- src/crypto/rng/rng.c | 15 +- test/test_matrix.json | 365 +--------------------------------- 3 files changed, 12 insertions(+), 372 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 0eca131be..77b80e574 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -3616,19 +3616,9 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -3656,19 +3646,9 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -3693,19 +3673,9 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -3937,8 +3907,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -3960,30 +3928,17 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -5043,21 +4998,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -6401,8 +6344,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -6416,7 +6357,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -6429,26 +6369,14 @@ "+", "+", "+", - "+", "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -6886,8 +6814,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -6900,7 +6826,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -6923,25 +6848,15 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", "+", "+", "+" @@ -7105,8 +7020,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -7119,7 +7032,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -7142,27 +7054,17 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -7274,18 +7176,10 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -7411,16 +7305,8 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+" ], @@ -7452,19 +7338,9 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", "+", "+" ], @@ -7797,7 +7673,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -7818,13 +7693,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -7834,16 +7705,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+", "+" @@ -7954,8 +7817,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -7968,7 +7829,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -7993,12 +7853,9 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", "+", "+", "+", @@ -8006,16 +7863,9 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", "+", "+" ], @@ -8039,7 +7889,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8064,13 +7913,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -8081,17 +7926,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+" ], @@ -8120,8 +7956,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -8134,7 +7968,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8157,22 +7990,12 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", "+", "+" ], @@ -8190,16 +8013,8 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+" ], @@ -8214,16 +8029,8 @@ "+", "+", "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+" @@ -8368,20 +8175,8 @@ ], "src": [ "-<*>", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -8393,7 +8188,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8433,20 +8227,8 @@ ], "src": [ "-<*>", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -8458,7 +8240,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8513,8 +8294,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -8527,7 +8306,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8550,12 +8328,9 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", - "+", "+", "+", "+", @@ -8563,16 +8338,9 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", "+", "+" ], @@ -8592,7 +8360,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8614,13 +8381,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -8630,16 +8393,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+" ], @@ -8689,7 +8444,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8710,13 +8464,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -8726,16 +8476,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+" ], @@ -8762,7 +8504,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8783,13 +8524,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -8799,16 +8536,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+", "+" @@ -8829,7 +8558,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -8853,13 +8581,9 @@ "+", "+", "+", - "+", - "+", "+", - "+", "+", "+", - "+", "+", "+", "+", @@ -8869,16 +8593,8 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", - "+", "+", "+" ], @@ -8994,8 +8710,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -9019,7 +8733,6 @@ "+", "+", "+", - "+", "+", "+", "+", @@ -9027,25 +8740,13 @@ "+", "+", "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -9740,14 +9441,6 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", @@ -9763,11 +9456,7 @@ "+", "+", "+", - "+", "+", - "+", - "+", - "+", "+", "+", "+", @@ -9985,8 +9674,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -10009,30 +9696,17 @@ "+", "+", "+", - "+", "+", "+", - "+", "+", "+", - "+", - "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -10228,8 +9902,6 @@ "+", "+", "+", - "+", - "+", "+", "+", "+", @@ -10255,33 +9927,20 @@ "+", "+", "+", - "+", "+", "+", "+", "+", - "+", "+", - "+", - "+", "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", "+", "+", "+", - "+", "+", "+", "+", @@ -10458,21 +10117,11 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", "+", - "+" + "+" ], "tests": [ "unit/src/services/net/ws_client/test_ws_client" @@ -10495,21 +10144,11 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", "+", "+", - "+", - "+", "+", - "+" + "+" ], "tests": [] }, From ff043874fa69b8a8c85fdcfa9003c23ba1354e29 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:43:18 +0000 Subject: [PATCH 152/185] server/peripherals/fdc2214: move onto MMgr --- src/server/peripherals/fdc2214/CMakeLists.txt | 4 ++-- src/server/peripherals/fdc2214/fdc2214.c | 20 +++++++++++-------- test/test_matrix.json | 10 ++-------- 3 files changed, 16 insertions(+), 18 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 77b80e574..3787e26c2 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -2461,14 +2461,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/fdc2214/test_fdc2214" From fffe84a251e3d88d8018353760dcb74b4df432c4 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:43:22 +0000 Subject: [PATCH 153/185] server/peripherals/ld2410: move onto MMgr --- src/server/peripherals/ld2410/CMakeLists.txt | 4 ++-- src/server/peripherals/ld2410/ld2410.c | 16 ++++++++-------- test/test_matrix.json | 18 ++++-------------- 3 files changed, 14 insertions(+), 24 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 3787e26c2..cf258d68b 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -3951,13 +3951,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ld2410/test_ld2410" @@ -3975,13 +3970,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ld2410/test_ld2410" From 35bab1257f90f8706269d07344b00a0d65126664 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:43:25 +0000 Subject: [PATCH 154/185] server/peripherals/ldc1614: move onto MMgr --- src/server/peripherals/ldc1614/CMakeLists.txt | 4 ++-- src/server/peripherals/ldc1614/ldc1614.c | 20 +++++++++++-------- test/test_matrix.json | 10 ++-------- 3 files changed, 16 insertions(+), 18 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index cf258d68b..1d8ca67e4 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -3987,14 +3987,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/ldc1614/test_ldc1614" From abcc36f386bd7934865de1ae926a0eeda33f86ae Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:43:28 +0000 Subject: [PATCH 155/185] services/fieldbus/devicenet: move onto MMgr --- src/services/fieldbus/devicenet/CMakeLists.txt | 2 +- src/services/fieldbus/devicenet/devicenet.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) 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; } From bd086802554ad3c40fbfa17d3d2b2a5675862c37 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:43:31 +0000 Subject: [PATCH 156/185] services/fieldbus/rawl2: move onto MMgr --- src/services/fieldbus/rawl2/CMakeLists.txt | 2 +- src/services/fieldbus/rawl2/rawl2.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) 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; } From b0f32ff8c630c73a4bfe06b1932ff610fd7fb897 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:44:12 +0000 Subject: [PATCH 157/185] network_drivers/presentation/codec/deflate/deflate: move onto MMgr --- .../codec/deflate/deflate/CMakeLists.txt | 3 +- .../codec/deflate/deflate/deflate.c | 34 +++++++------------ 2 files changed, 13 insertions(+), 24 deletions(-) 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; } From a2c9fa44cdd7a3e3fc2bb0e924e50857df05c157 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:44:21 +0000 Subject: [PATCH 158/185] services/radio/radio_sniff: move onto MMgr --- src/services/radio/radio_sniff/CMakeLists.txt | 2 +- src/services/radio/radio_sniff/radio_sniff.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) 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 From 99bb3829e8c5afba43f948362ed0d148d5710f4c Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:44:25 +0000 Subject: [PATCH 159/185] server/peripherals/hmmd: move onto MMgr --- src/server/peripherals/hmmd/CMakeLists.txt | 4 ++-- src/server/peripherals/hmmd/hmmd.c | 20 ++++++++++---------- test/test_matrix.json | 18 ++++-------------- 3 files changed, 16 insertions(+), 26 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 1d8ca67e4..39d6ff391 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -3237,13 +3237,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/hmmd/test_hmmd" @@ -3261,13 +3256,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/peripherals/hmmd/test_hmmd" From b822f691ea192315ffe62f33f09cbe54c19e2510 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:46:21 +0000 Subject: [PATCH 160/185] server/signaling/device_id: move onto MMgr --- src/server/signaling/device_id/CMakeLists.txt | 4 ++-- src/server/signaling/device_id/device_id.c | 16 ++++++++-------- test/test_matrix.json | 10 ++-------- 3 files changed, 12 insertions(+), 18 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 39d6ff391..5fe4744c5 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -1414,16 +1414,10 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": ["unit/src/server/signaling/test_device_id"], "extra_scripts": ["pre:test/gen_test_runners.py"] From 7613b93457cc0151eb358ebdb1dc981fd668030a Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:47:16 +0000 Subject: [PATCH 161/185] services/fieldbus/j1939: move onto MMgr --- src/services/fieldbus/j1939/CMakeLists.txt | 4 ++-- src/services/fieldbus/j1939/j1939.c | 26 ++++++++++++---------- test/test_matrix.json | 18 ++++----------- 3 files changed, 20 insertions(+), 28 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 5fe4744c5..c6d91a4cf 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -3769,13 +3769,8 @@ ], "src": [ "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/fieldbus/j1939/test_j1939" @@ -4645,13 +4640,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/services/timing_position/nmea2000/test_nmea2000" From 2de9558d8b557ef8c9e2f63a3d027ea62e05f61f Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:47:37 +0000 Subject: [PATCH 162/185] services/machine_tool/mtconnect: move onto MMgr --- .../machine_tool/mtconnect/CMakeLists.txt | 5 ++-- .../machine_tool/mtconnect/mtconnect.c | 24 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) 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); } } From ccb7f1636f943cdd5944bfffb5d4342c8f4e0838 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:47:45 +0000 Subject: [PATCH 163/185] services/fieldbus/canopen: move onto MMgr --- src/services/fieldbus/canopen/CMakeLists.txt | 2 +- src/services/fieldbus/canopen/canopen.c | 23 ++++++++++---------- 2 files changed, 13 insertions(+), 12 deletions(-) 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; From 3e4a1c7914a787035fe17fbee30533e4a223ce2a Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:47:49 +0000 Subject: [PATCH 164/185] shared/ip: move onto MMgr --- src/shared/ip/CMakeLists.txt | 2 +- src/shared/ip/ip.c | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) 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; } From fdc368b23c94bcec83fd31223c30d2e75b1f1ae3 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:47:50 +0000 Subject: [PATCH 165/185] crypto/asymmetric/rsa: move onto MMgr --- src/crypto/asymmetric/rsa/CMakeLists.txt | 2 +- src/crypto/asymmetric/rsa/rsa.c | 26 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) 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 From 35eb896ba9265e80837e9cadf2a342d31b42abce Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:47:53 +0000 Subject: [PATCH 166/185] network_drivers/presentation/http/http3/qpack: move onto MMgr --- .../http/http3/qpack/CMakeLists.txt | 3 +-- .../presentation/http/http3/qpack/qpack.c | 22 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) 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; From 686ca1a54aa125b9a67bb3d723b92cff8360c787 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:47:56 +0000 Subject: [PATCH 167/185] crypto/pqc/mlkem: move onto MMgr --- src/crypto/pqc/mlkem/CMakeLists.txt | 2 +- src/crypto/pqc/mlkem/mlkem.c | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) 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)); From c7b10c5dc0e08cea83007c2c52174f1d1f3d95b3 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:48:22 +0000 Subject: [PATCH 168/185] services/security/totp: move onto MMgr --- src/services/security/totp/CMakeLists.txt | 5 ++--- src/services/security/totp/totp.c | 25 ++++++++++++----------- test/test_matrix.json | 10 ++------- 3 files changed, 17 insertions(+), 23 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index c6d91a4cf..44f4323c8 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -9432,14 +9432,8 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": ["unit/src/services/security/totp/test_totp"], "extra_scripts": ["pre:test/gen_test_runners.py"] From c87bf025aa786b44ba009d228071f5faa7399e4b Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:48:30 +0000 Subject: [PATCH 169/185] network_drivers/presentation/codec/json: move onto MMgr --- .../presentation/codec/json/CMakeLists.txt | 3 +- .../presentation/codec/json/json.c | 31 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) 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; From 3e2b1c0569277b372e64ce2e127b3fbd57265a03 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:48:33 +0000 Subject: [PATCH 170/185] network_drivers/presentation/http/http2/hpack: move onto MMgr --- .../http/http2/hpack/CMakeLists.txt | 3 +- .../presentation/http/http2/hpack/hpack.c | 28 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) 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; From 3b19b2dc51e0ec9f9d9bb89f2192ee1a76e6f9ee Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:48:36 +0000 Subject: [PATCH 171/185] server/peripherals/sdi12: move onto MMgr --- src/server/peripherals/sdi12/CMakeLists.txt | 3 +-- src/server/peripherals/sdi12/sdi12.c | 29 +++++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) 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. */ From 657be8e322e10cc2bd60e1c71b99971ff7338cae Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:48:39 +0000 Subject: [PATCH 172/185] server/storage/hotswap: move onto MMgr --- src/server/storage/hotswap/CMakeLists.txt | 4 +-- src/server/storage/hotswap/hotswap.c | 34 +++++++++++++---------- test/test_matrix.json | 12 ++------ 3 files changed, 23 insertions(+), 27 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index 44f4323c8..be946bf1e 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -3280,17 +3280,9 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/storage/hotswap/test_hotswap" From 4ce02ddcaf9777484034e3b7e97dafc8fb1471fe Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:48:43 +0000 Subject: [PATCH 173/185] server/storage/mnt_ram: move onto MMgr --- src/server/storage/mnt_ram/CMakeLists.txt | 3 +-- src/server/storage/mnt_ram/mnt_ram.c | 32 +++++++++++++---------- 2 files changed, 19 insertions(+), 16 deletions(-) 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; From 0817cbb80f9f84af03b522628f45616060d1ffab Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:48:46 +0000 Subject: [PATCH 174/185] services/energy/c37118: move onto MMgr --- src/services/energy/c37118/CMakeLists.txt | 3 +- src/services/energy/c37118/c37118.c | 34 ++++++++++++----------- 2 files changed, 19 insertions(+), 18 deletions(-) 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 From 6ec6bfa29705e8973f61c901bba2706b4dfbe018 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:48:46 +0000 Subject: [PATCH 175/185] services/net/snmp/snmp_crypto: move onto MMgr --- .../net/snmp/snmp_crypto/CMakeLists.txt | 4 +-- .../net/snmp/snmp_crypto/snmp_crypto.c | 33 ++++++++++--------- 2 files changed, 18 insertions(+), 19 deletions(-) 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; } From 79144f8f8e63dd62f767683694bf8637ae63f273 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:49:05 +0000 Subject: [PATCH 176/185] services/radio/ble_gatt: move onto MMgr --- src/services/radio/ble_gatt/CMakeLists.txt | 3 +- src/services/radio/ble_gatt/ble_gatt.c | 42 +++++++++++----------- 2 files changed, 22 insertions(+), 23 deletions(-) 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 cc20fe40f..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; } @@ -162,14 +162,14 @@ proto_bool protocore_ble_gatt_att_parse(uint8_t *work, const uint8_t *pdu, size_ 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 From 73da58560b90f723b25f47be40f3c9842f3ef97b Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:49:25 +0000 Subject: [PATCH 177/185] shared/http_date: move onto MMgr --- src/shared/http_date/CMakeLists.txt | 2 +- src/shared/http_date/http_date.c | 43 +++++++++++++++++------------ 2 files changed, 27 insertions(+), 18 deletions(-) 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. From dd31d5337cd78866f2e08daea9f0db749db9cb11 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:49:44 +0000 Subject: [PATCH 178/185] server/web/web_terminal: move onto MMgr --- src/server/web/web_terminal/CMakeLists.txt | 4 +-- src/server/web/web_terminal/web_terminal.c | 34 +++++++++++++--------- src/server/web/web_terminal/web_terminal.h | 10 +++---- 3 files changed, 27 insertions(+), 21 deletions(-) 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(...) ... From a6e46ecffa573b560f762c8061aece25e01bea78 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:50:06 +0000 Subject: [PATCH 179/185] network_drivers/application/sftp/sftp: move onto MMgr --- .../application/sftp/sftp/CMakeLists.txt | 4 +- .../application/sftp/sftp/sftp.c | 48 ++++++++++--------- 2 files changed, 27 insertions(+), 25 deletions(-) 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. */ From 38cd7eee9a00af39644a34fa859a694e6e60bcc5 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:50:21 +0000 Subject: [PATCH 180/185] server/storage/filesystem: move onto MMgr --- src/server/storage/filesystem/CMakeLists.txt | 7 +-- src/server/storage/filesystem/filesystem.c | 58 +++++++++++--------- src/server/storage/filesystem/filesystem.h | 12 ++-- test/test_matrix.json | 39 ++----------- 4 files changed, 46 insertions(+), 70 deletions(-) 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/test/test_matrix.json b/test/test_matrix.json index be946bf1e..333029d44 100644 --- a/test/test_matrix.json +++ b/test/test_matrix.json @@ -4276,19 +4276,10 @@ "src": [ "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/server/storage/mnt/test_mnt" @@ -6692,19 +6683,10 @@ "+", "+", "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/network_drivers/session/scp/test_scp" @@ -8556,22 +8538,13 @@ ], "src": [ "+", - "+", "+", "+", - "+", - "+", - "+", - "+", - "+", "+", - "+", "+", - "+", - "+", - "+", "+", - "+" + "+", + "+" ], "tests": [ "unit/src/network_drivers/application/sftp/test_ssh_sftp" From fa6b63ae38ae2aae2613fa18b3a38d1248b002d0 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:50:30 +0000 Subject: [PATCH 181/185] services/energy/dnp3: move onto MMgr --- src/services/energy/dnp3/CMakeLists.txt | 3 +- src/services/energy/dnp3/dnp3.c | 50 +++++++++++++------------ 2 files changed, 27 insertions(+), 26 deletions(-) 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; From b4cbb995376d58259131d16389db503e4bbf96e1 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:50:33 +0000 Subject: [PATCH 182/185] server/signaling/gpio_map: move onto MMgr --- src/server/signaling/gpio_map/CMakeLists.txt | 4 +- src/server/signaling/gpio_map/gpio_map.c | 55 ++++++++++---------- 2 files changed, 29 insertions(+), 30 deletions(-) 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; } From 83eeef2b73e5b2bd38d17161d82ce34279a75ba4 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:50:36 +0000 Subject: [PATCH 183/185] services/storage/wal/wal_store: move onto MMgr --- .../storage/wal/wal_store/CMakeLists.txt | 3 +- .../storage/wal/wal_store/wal_store.c | 63 ++++++++++--------- 2 files changed, 36 insertions(+), 30 deletions(-) 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; From 40cc0dd16779cf09b45f552677b19a2121d7eb25 Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 20:50:51 +0000 Subject: [PATCH 184/185] server/core/exc_decoder: move onto MMgr --- src/server/core/exc_decoder/CMakeLists.txt | 3 +- src/server/core/exc_decoder/exc_decoder.c | 97 ++++++++++++---------- 2 files changed, 55 insertions(+), 45 deletions(-) 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 From 17f771613e6b1c8b577a873445eec55086c6028b Mon Sep 17 00:00:00 2001 From: "dstroy0 (Douglas Quigg)" Date: Wed, 30 Sep 2026 21:01:22 +0000 Subject: [PATCH 185/185] Move remaining src modules onto MMgr: in-progress presentation codecs, ssh and udp headers --- include/protocore.h | 7 +- src/CMakeLists.txt | 1 - src/config/memory_sizing/buffer_sizing.h | 2 +- src/mmgr/CMakeLists.txt | 23 - src/mmgr/arena/CMakeLists.txt | 8 - src/mmgr/arena/arena.c | 362 ----- src/mmgr/arena/arena.h | 303 ---- src/mmgr/bitio/CMakeLists.txt | 6 - src/mmgr/bitio/bitio.c | 58 - src/mmgr/bitio/bitio.h | 81 - src/mmgr/bytes/CMakeLists.txt | 11 - src/mmgr/bytes/bytes.c | 122 -- src/mmgr/bytes/bytes.h | 113 -- src/mmgr/dma/CMakeLists.txt | 7 - src/mmgr/dma/dma.c | 75 - src/mmgr/dma/dma.h | 135 -- src/mmgr/endian/CMakeLists.txt | 6 - src/mmgr/endian/endian.c | 109 -- src/mmgr/endian/endian.h | 128 -- src/mmgr/float_bits/CMakeLists.txt | 8 - src/mmgr/float_bits/float_bits.c | 46 - src/mmgr/float_bits/float_bits.h | 89 -- src/mmgr/membuild/CMakeLists.txt | 11 - src/mmgr/membuild/membuild.c | 659 -------- src/mmgr/membuild/membuild.h | 209 --- src/mmgr/plaintext/CMakeLists.txt | 10 - src/mmgr/plaintext/plaintext.c | 257 ---- src/mmgr/plaintext/plaintext.h | 248 --- src/mmgr/protoframe/CMakeLists.txt | 11 - src/mmgr/protoframe/protoframe.c | 141 -- src/mmgr/protoframe/protoframe.h | 245 --- src/mmgr/protomem/CMakeLists.txt | 10 - src/mmgr/protomem/protomem.c | 227 --- src/mmgr/protomem/protomem.h | 101 -- src/mmgr/protostr/CMakeLists.txt | 8 - src/mmgr/protostr/protostr.c | 1336 ----------------- src/mmgr/protostr/protostr.h | 142 -- src/mmgr/psram_pool/CMakeLists.txt | 7 - src/mmgr/psram_pool/psram_pool.c | 95 -- src/mmgr/psram_pool/psram_pool.h | 77 - src/mmgr/rawmemcpy/CMakeLists.txt | 6 - src/mmgr/rawmemcpy/rawmemcpy.c | 83 - src/mmgr/rawmemcpy/rawmemcpy.h | 357 ----- src/mmgr/ring/CMakeLists.txt | 9 - src/mmgr/ring/ring.h | 356 ----- src/mmgr/secure/CMakeLists.txt | 11 - src/mmgr/secure/secure.c | 238 --- src/mmgr/secure/secure.h | 255 ---- src/mmgr/span/CMakeLists.txt | 6 - src/mmgr/span/span.c | 103 -- src/mmgr/span/span.h | 168 --- src/mmgr/swar/CMakeLists.txt | 8 - src/mmgr/swar/swar.c | 202 --- src/mmgr/swar/swar.h | 213 --- .../presentation/codec/CMakeLists.txt | 2 +- .../presentation/codec/cbor/cbor.h | 14 +- .../presentation/codec/codec.h | 53 +- .../presentation/codec/msgpack/CMakeLists.txt | 6 +- .../presentation/codec/msgpack/msgpack.c | 12 +- .../presentation/codec/msgpack/msgpack.h | 12 +- .../presentation/ssh/auth/auth.h | 2 +- .../presentation/ssh/common/CMakeLists.txt | 3 +- .../presentation/ssh/common/common.h | 53 +- .../ssh/transport/transport/transport.h | 34 +- .../transport/tcp/common/CMakeLists.txt | 2 +- .../transport/tcp/common/common.h | 75 +- .../transport/udp/common/CMakeLists.txt | 3 +- .../transport/udp/common/common.h | 58 +- .../storage/wal/wal_fs/CMakeLists.txt | 2 +- src/services/storage/wal/wal_fs/wal_fs.h | 4 +- 70 files changed, 167 insertions(+), 7677 deletions(-) delete mode 100644 src/mmgr/CMakeLists.txt delete mode 100644 src/mmgr/arena/CMakeLists.txt delete mode 100644 src/mmgr/arena/arena.c delete mode 100644 src/mmgr/arena/arena.h delete mode 100644 src/mmgr/bitio/CMakeLists.txt delete mode 100644 src/mmgr/bitio/bitio.c delete mode 100644 src/mmgr/bitio/bitio.h delete mode 100644 src/mmgr/bytes/CMakeLists.txt delete mode 100644 src/mmgr/bytes/bytes.c delete mode 100644 src/mmgr/bytes/bytes.h delete mode 100644 src/mmgr/dma/CMakeLists.txt delete mode 100644 src/mmgr/dma/dma.c delete mode 100644 src/mmgr/dma/dma.h delete mode 100644 src/mmgr/endian/CMakeLists.txt delete mode 100644 src/mmgr/endian/endian.c delete mode 100644 src/mmgr/endian/endian.h delete mode 100644 src/mmgr/float_bits/CMakeLists.txt delete mode 100644 src/mmgr/float_bits/float_bits.c delete mode 100644 src/mmgr/float_bits/float_bits.h delete mode 100644 src/mmgr/membuild/CMakeLists.txt delete mode 100644 src/mmgr/membuild/membuild.c delete mode 100644 src/mmgr/membuild/membuild.h delete mode 100644 src/mmgr/plaintext/CMakeLists.txt delete mode 100644 src/mmgr/plaintext/plaintext.c delete mode 100644 src/mmgr/plaintext/plaintext.h delete mode 100644 src/mmgr/protoframe/CMakeLists.txt delete mode 100644 src/mmgr/protoframe/protoframe.c delete mode 100644 src/mmgr/protoframe/protoframe.h delete mode 100644 src/mmgr/protomem/CMakeLists.txt delete mode 100644 src/mmgr/protomem/protomem.c delete mode 100644 src/mmgr/protomem/protomem.h delete mode 100644 src/mmgr/protostr/CMakeLists.txt delete mode 100644 src/mmgr/protostr/protostr.c delete mode 100644 src/mmgr/protostr/protostr.h delete mode 100644 src/mmgr/psram_pool/CMakeLists.txt delete mode 100644 src/mmgr/psram_pool/psram_pool.c delete mode 100644 src/mmgr/psram_pool/psram_pool.h delete mode 100644 src/mmgr/rawmemcpy/CMakeLists.txt delete mode 100644 src/mmgr/rawmemcpy/rawmemcpy.c delete mode 100644 src/mmgr/rawmemcpy/rawmemcpy.h delete mode 100644 src/mmgr/ring/CMakeLists.txt delete mode 100644 src/mmgr/ring/ring.h delete mode 100644 src/mmgr/secure/CMakeLists.txt delete mode 100644 src/mmgr/secure/secure.c delete mode 100644 src/mmgr/secure/secure.h delete mode 100644 src/mmgr/span/CMakeLists.txt delete mode 100644 src/mmgr/span/span.c delete mode 100644 src/mmgr/span/span.h delete mode 100644 src/mmgr/swar/CMakeLists.txt delete mode 100644 src/mmgr/swar/swar.c delete mode 100644 src/mmgr/swar/swar.h 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/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/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/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/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/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/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/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/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/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)