summaryrefslogtreecommitdiffstats
path: root/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md
diff options
context:
space:
mode:
Diffstat (limited to 'debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md')
-rw-r--r--debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md149
1 files changed, 149 insertions, 0 deletions
diff --git a/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md b/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md
new file mode 100644
index 0000000..26f1ffb
--- /dev/null
+++ b/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md
@@ -0,0 +1,149 @@
+# 12 — Injection SDK specification (v1, demo ABI)
+
+> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status and
+> [`GREEN-EYE-ROADMAP.md`](../GREEN-EYE-ROADMAP.md) §H1/H3 for the program.
+
+## 1. Goals and non-goals
+
+**Goals**
+* a repeatable, scriptable way to compile a piece of RV64 code, load it into a
+ live firmware target, register it, invoke it, and observe it with the same
+ hooks/sessions/analysis as firmware;
+* a clear ABI so services can be written once and run under the demo uproc
+ today and under a simulated RM core later;
+* an evidence trail: every load, registration and invocation is recorded.
+
+**Non-goals (v1)**
+* shipping any injected code (development-only);
+* hot-patching signed firmware on hardware;
+* bypassing security boundaries (the simulator is a study environment).
+
+## 2. Blob contract
+
+* **Format:** ELF64 `EM_RISCV`, `RV64IMAC`, soft-float ABI, one or more
+ `PT_LOAD` segments.
+* **Position independence:** built PIC (`-fPIC`, `-mcmodel=medany`,
+ `-mno-relax`, `-fno-asynchronous-unwind-tables`), no dynamic relocations.
+ The loader verifies by writing segments at the chosen load address; the SDK
+ `make relocs` target must report none.
+* **Self-sufficiency:** no libc, no global data containing addresses.
+ Caller-provided addresses (future RM-core tables) arrive as arguments.
+* **Entry symbol:** `ge_demo_service_dispatch` by default (override with
+ `--entry`/`entry_symbol=`).
+* **Optional metadata:** a `ge_service_t` block can be exported for future
+ loaders (`magic 0x47455356`, version 1, name, dispatch).
+
+## 3. ABI v1
+
+```c
+typedef ge_u64 (*ge_service_fn)(ge_u64 cmd, ge_u64 a0, ge_u64 a1);
+```
+
+* `a0`, `a1`, `a2` registers carry `(cmd, a0, a1)` on entry.
+* The return value is `a0`.
+* The service may use `a3..a7`, `t0..t6`, `s0..s11` and the stack; the
+ injector supplies a private stack below the scratch page.
+* Traps do not return: the call loop times out, records the stop, restores
+ registers and raises `RspTimeout`.
+* No calling convention for callbacks in v1; the loader registers a **single
+ dispatch entry** per slot.
+
+## 4. Demo registration model
+
+* The firmware exposes eight handler slots (`gsp_ctrl.handlers[0..7]`).
+* Mailbox commands **16..23** select slot `cmd-16`.
+* On dispatch the firmware calls
+ `handlers[slot](arg0, arg1, arg2)` — i.e. `cmd = arg0`, parameters
+ `arg1`, `arg2`.
+* Slots 0..5 are used by the built-in demo RPCs; **slot 6** is the SDK
+ default (`--slot`).
+
+### Control-block fields used (demo)
+
+| Field | Offset | Role |
+|---|---|---|
+| `mailbox` | `+0x20` | command (`16 + slot` selects an injected service) |
+| `arg0` | `+0x28` | service command |
+| `arg1` | `+0x30` | parameter 0 |
+| `arg2` | `+0x38` | parameter 1 |
+| `result` | `+0x40` | service return value |
+| `handlers` | `+0x150` | eight entry slots |
+
+Offsets are demo-firmware-specific; use `greeneye/inject.py` constants and the
+schema at `firmware/uproc_demo/gsp_ctrl.schema.json` rather than hardcoding.
+
+## 5. Lifecycle
+
+```
+compile (PIC) ──► verify relocations ──► load PT_LOADs at load_addr
+ │ │
+ │ ├─► register entry in slot
+ │ └─► record "service_injected"
+ ▼
+invoke_remote (direct call) invoke_via_firmware (mailbox dispatch)
+ └──────────────► both record call_enter/call_return events
+```
+
+* **Load address:** default `ram_base + 0x01000000`, auto-shrunk to fit if
+ the image is larger; explicit with `--load-addr`.
+* **Cleanup:** v1 does not unregister automatically. A service is removed by
+ zeroing its slot and (optionally) clearing the blob; sessions record the
+ injection so runs are reproducible from a known state.
+* **Multiple services:** one per slot; multi-entry services are one dispatch
+ with subcommands.
+
+## 6. Observability contract
+
+The injector records, in the session directory:
+* `service_injected` — path, name, load address, entry address, slot, size;
+* `mem_write` events for every segment written;
+* `call_enter` / `call_return` — address, args, return value;
+* hook/watch events from user instrumentation inside the service;
+* `qemu.log`-style blobs are not applicable (no probe here), but the TCG
+ trace can be enabled for full coverage.
+
+Comparison of injected-service runs uses the standard `greeneye compare`
+profiles, so a change in a service's behaviour is visible like any firmware
+change.
+
+## 7. Building (reference)
+
+```makefile
+CC := clang
+LLD ?= /usr/lib/llvm-18/bin/ld.lld
+CFLAGS := --target=riscv64-unknown-elf -march=rv64imac -mabi=lp64 \
+ -mcmodel=medany -mno-relax -fPIC -ffreestanding -nostdlib \
+ -fno-builtin -fno-stack-protector -fno-asynchronous-unwind-tables -O2
+$(LLD) -m elf64lriscv --no-relax -e ge_demo_service_dispatch -o service.elf service.o
+```
+
+The tracked SDK (`sdk/`) is the executable reference.
+
+## 8. Versioning and compatibility
+
+* ABI version 1 is the demo contract described here.
+* Future ABI v2 (RM-core shim) will pass a call table and a service context
+ instead of relying on firmware slots; blobs declare their ABI via the
+ optional metadata block so loaders can refuse mismatches.
+* Breaking ABI changes require a compatibility shim plus a note in the
+ session metadata and this document.
+
+## 9. Security and safety
+
+* Injected code runs with the simulator's full privileges; the bridge and
+ injector are local-only tools.
+* Never inject into a guest or a shipped environment; never use injection to
+ bypass a hardware protection.
+* Fuzzing/mutation harnesses (roadmap H4.3) must run against the simulator
+ or re-hosted code, with sessions attached as evidence.
+* Treat every injected service as untrusted code for the purposes of
+ watching: it may corrupt firmware state, so always record and restart clean
+ after crashes.
+
+## 10. Roadmap hooks
+
+* **H1.3** — RM service registration and RM-core call interception.
+* **H3** — native-simulator loader with snapshots and branch exploration.
+* **H4** — differential testing of injected services across firmware
+ versions and capability inference from their access patterns.
+* **H5** — services spanning GSP and adjacent microcontrollers.