|
| 1 | +# Flash Driver Model |
| 2 | + |
| 3 | +This document describes the architecture of the layered flash userspace driver |
| 4 | +under drivers/flash and how it integrates with platform server bindings. |
| 5 | + |
| 6 | +## 1. Layer Overview |
| 7 | + |
| 8 | +``` |
| 9 | +┌──────────────────────────────────────────────────────────┐ |
| 10 | +│ Application / Client Task │ |
| 11 | +│ FlashClient (drivers/flash/client) │ |
| 12 | +│ channel_transact(request) -> response │ |
| 13 | +└────────────────────────┬─────────────────────────────────┘ |
| 14 | + │ Pigweed IPC channel |
| 15 | + ▼ |
| 16 | +┌──────────────────────────────────────────────────────────┐ |
| 17 | +│ Server Binary (platform binding) │ |
| 18 | +│ rust_app wires handles + backend + runtime loop │ |
| 19 | +└────────────────────────┬─────────────────────────────────┘ |
| 20 | + │ |
| 21 | + ▼ |
| 22 | +┌──────────────────────────────────────────────────────────┐ |
| 23 | +│ Server Library (platform binding) │ |
| 24 | +│ dispatch_request: protocol -> backend translation │ |
| 25 | +│ runtime loop: channel_read -> dispatch -> respond │ |
| 26 | +└────────────────────────┬─────────────────────────────────┘ |
| 27 | + │ FlashBackend trait |
| 28 | + ▼ |
| 29 | +┌──────────────────────────────────────────────────────────┐ |
| 30 | +│ Platform Backend (platform binding) │ |
| 31 | +│ PlatformFlashBackend : FlashBackend │ |
| 32 | +└────────────────────────┬─────────────────────────────────┘ |
| 33 | + │ |
| 34 | + ▼ |
| 35 | +┌──────────────────────────────────────────────────────────┐ |
| 36 | +│ Controller Driver (SMC/FMC or equivalent) │ |
| 37 | +│ Raw MMIO or HAL-level flash controller implementation │ |
| 38 | +└──────────────────────────────────────────────────────────┘ |
| 39 | +``` |
| 40 | + |
| 41 | +## 2. Crate Map |
| 42 | + |
| 43 | +| Bazel target | Crate | Role | |
| 44 | +|---|---|---| |
| 45 | +| //drivers/flash/api:flash_api | flash_api | Wire protocol, error/status model, geometry types, backend trait contract | |
| 46 | +| //drivers/flash/client:flash_client | flash_client | Userspace IPC facade for read/write/erase/discovery | |
| 47 | + |
| 48 | +The API/client layers are target-agnostic within Pigweed kernel userspace |
| 49 | +targets. |
| 50 | + |
| 51 | +## 3. Wire Protocol (flash_api::protocol) |
| 52 | + |
| 53 | +Operations are encoded by FlashOp in FlashRequestHeader (16 bytes, |
| 54 | +repr(C, packed), little-endian), with an optional payload up to |
| 55 | +MAX_PAYLOAD_SIZE (256 bytes). |
| 56 | + |
| 57 | +| Op | Value | Request shape | Response shape | |
| 58 | +|---|---|---|---| |
| 59 | +| Exists | 0x01 | header only | value = 0/1 | |
| 60 | +| GetCapacity | 0x02 | header only | value = capacity bytes | |
| 61 | +| Read | 0x03 | address + length | payload = bytes read, value = byte count | |
| 62 | +| Write | 0x04 | address + length + payload | value = byte count | |
| 63 | +| Erase | 0x05 | address + length | success/error only | |
| 64 | +| GetGeometry | 0x06 | header only | payload = FlashGeometry | |
| 65 | + |
| 66 | +FlashResponseHeader (8 bytes) carries status (FlashError), payload length, |
| 67 | +and an op-specific value word. |
| 68 | + |
| 69 | +## 4. Backend Contract (flash_api::backend) |
| 70 | + |
| 71 | +The server-side backend contract is defined by FlashBackend: |
| 72 | + |
| 73 | +- info(route_key) -> FlashInfo |
| 74 | +- exists(route_key) -> Result<bool, BackendError> |
| 75 | +- read(route_key, address, out) -> Result<usize, BackendError> |
| 76 | +- write(route_key, address, data) -> Result<usize, BackendError> |
| 77 | +- erase(route_key, address, length) -> Result<(), BackendError> |
| 78 | +- enable_interrupts() / disable_interrupts() |
| 79 | + |
| 80 | +Geometry discovery is exposed via FlashGeometryProvider, which can derive a |
| 81 | +default geometry from info() or be overridden by backends that need richer |
| 82 | +semantics. |
| 83 | + |
| 84 | +## 5. Client Library (flash_client) |
| 85 | + |
| 86 | +FlashClient is a synchronous userspace facade that: |
| 87 | + |
| 88 | +- serializes request headers/payloads into caller-provided request buffers, |
| 89 | +- performs channel_transact with optional timeout, |
| 90 | +- parses/validates response headers and payload lengths, |
| 91 | +- maps transport and wire errors into ClientError. |
| 92 | + |
| 93 | +Current client behavior and constraints: |
| 94 | + |
| 95 | +- no_std, blocking IPC calls. |
| 96 | +- single call in flight per client instance (&mut self API). |
| 97 | +- per-call data cap is FlashClient::chunk_size() (MAX_PAYLOAD_SIZE). |
| 98 | +- explicit support for discovery calls: exists, capacity, geometry. |
| 99 | + |
| 100 | +For detailed usage and method-level behavior, see: |
| 101 | + |
| 102 | +- drivers/flash/api/README.md |
| 103 | +- drivers/flash/client/README.md |
| 104 | + |
| 105 | +## 6. Error Surface |
| 106 | + |
| 107 | +Wire-level status is FlashError. Common categories: |
| 108 | + |
| 109 | +- protocol misuse: InvalidOperation, InvalidAddress, InvalidLength |
| 110 | +- runtime contention: Busy, Timeout |
| 111 | +- media/policy failures: IoError, NotPermitted |
| 112 | +- fallback: InternalError |
| 113 | + |
| 114 | +ClientError wraps three classes of failure: |
| 115 | + |
| 116 | +- IpcError(pw_status::Error): transport syscall failure |
| 117 | +- ServerError(FlashError): valid response reporting flash-level failure |
| 118 | +- InvalidResponse: malformed/truncated response frame |
| 119 | +- BufferTooSmall: local request/response buffer constraints |
| 120 | + |
| 121 | +## 7. Integration Model |
| 122 | + |
| 123 | +drivers/flash is split so protocol and client can evolve independently from |
| 124 | +platform backend/server bring-up: |
| 125 | + |
| 126 | +- Keep wire schema and trait contract stable in flash_api. |
| 127 | +- Keep userspace ergonomics and parsing hardening in flash_client. |
| 128 | +- Implement server runtime and concrete backend per target tree. |
| 129 | + |
| 130 | +This separation allows host-side validation of protocol and client logic before |
| 131 | +hardware-specific bindings are ready. |
| 132 | + |
| 133 | +## 8. Extension Points |
| 134 | + |
| 135 | +- New backend: implement FlashBackend (and optionally FlashGeometryProvider) |
| 136 | + in a platform crate, then bind server channel handles to route keys. |
| 137 | +- New operation: add FlashOp variant, define header/payload semantics, extend |
| 138 | + backend trait and server dispatch. |
| 139 | +- New geometry flags semantics: preserve wire compatibility by treating flags |
| 140 | + as opaque at protocol level and documenting interpretation at backend level. |
| 141 | + |
| 142 | +## 9. Testing Focus |
| 143 | + |
| 144 | +Recommended tests by layer: |
| 145 | + |
| 146 | +- flash_api: wire layout, endian correctness, enum/status round-trips, |
| 147 | + short-buffer decode rejection. |
| 148 | +- flash_client: response validation paths, timeout behavior, chunk-size checks, |
| 149 | + and retry handling for Busy. |
| 150 | +- platform server/backend: operation dispatch, alignment rules, erase granule |
| 151 | + correctness, and hardware fault mapping to FlashError. |
0 commit comments