THEORY OF OPERATION(9)
π¦ Theory of operation π¦
okay so bestie, welcome to Theory of operation(9) from the Kernel API Manual β this is the SCMI Raw mode lore, and itβs actually iconic once you get the vibe. π
When enabled, SCMI Raw mode support exposes a userspace API that lets a user application send and receive SCMI commands, replies, and notifications by injecting and snooping bare SCMI messages in binary little-endian format. Yes, weβre down at the bare-message level. No cap.
Those injected SCMI transactions then get routed through the SCMI core stack toward the SCMI backend server, using whatever SCMI transport is currently configured on the system under test. β¨
Itβs meant to help run any sort of SCMI backend server testing, no matter where the server is placed, as long as itβs normally reachable via the transport configured on the system. Thatβs the whole point, fr fr.
Big warning energy: this is activated by a Kernel configuration option because it is NOT meant to be used in production β only during development and in CI deployments. Do not bring this to the production function, bestie. π
πΈ regular drivers vs raw mode πΈ
So to avoid possible interferences between SCMI Raw transactions originated from a test-suite and the normal operations of the SCMI drivers, thereβs a default vibe: when Raw mode is enabled, by default all the regular SCMI drivers are inhibited, unless CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX is enabled.
In that coexistence case, the regular SCMI stack drivers will be loaded as usual β and it is up to the user of this interface to take care of manually inhibiting the regular SCMI drivers in order to avoid interferences during the test runs. Thatβs on you, bestie. π«Ά
π the exposed API π
The exposed API is as follows.
All SCMI Raw entries are rooted under a common top /raw debugfs directory, which in turn is rooted under the corresponding underlying SCMI instance.
/sys/kernel/debug/scmi/
`-- 0
|-- atomic_threshold_us
|-- instance_name
|-- raw
| |-- channels
| | |-- 0x10
| | | |-- message
| | | `-- message_async
| | `-- 0x13
| | |-- message
| | `-- message_async
| |-- errors
| |-- message
| |-- message_async
| |-- notification
| `-- reset
`-- transport
|-- is_atomic
|-- max_msg_size
|-- max_rx_timeout_ms
|-- rx_max_msg
|-- tx_max_msg
`-- type
where:
errorsβ used to read back timed-out and unexpected replies.message*β used to send sync/async commands and read back immediate and delayed responses (if any).notificationβ used to read any notification being emitted by the system (if previously enabled by the user app).resetβ used to flush the queues of messages (of any kind) still pending to be read; this is useful at test-suite start/stop to get rid of any unread messages from the previous run.
The per-channel entries rooted at /channels are present only on a system where multiple transport channels have been configured.
Those per-channel entries can be used to explicitly choose a specific channel for SCMI bare message injection. This is in contrast with the general entries above, where the selection of the proper channel to use is automatically performed based on the protocol embedded in the injected message and on how the transport is configured on the system. iykyk. π¦
Note that other common general entries are available under transport/ to let the user applications properly make up their expectations in terms of timeouts and message characteristics.
π message behavior, timeouts, and sequence numbers π
Each write to the message* entries causes one command request to be built and sent, while the replies or delayed response are read back from those same entries one message at a time β receiving an EOF at each message boundary.
The user application running the test is in charge of handling timeouts on replies and properly choosing SCMI sequence numbers for the outgoing requests. Using the same sequence number is supported, but discouraged. π
Injection of multiple in-flight requests is supported as long as the user application uses properly distinct sequence numbers for concurrent requests and takes care to properly manage all the related issues about concurrency and command/reply pairing. Keep in mind that, anyway, the real level of parallelism attainable in such a scenario is dependent on the characteristics of the underlying transport being used. Thatβs the tea. π
Since the SCMI core regular stack is partially used to deliver and collect the messages, late replies arrived after timeouts and any other sort of unexpected message can be identified by the SCMI core as usual, and they will be reported as messages under "errors" for later analysis. Not me being dramatic, thatβs just where they show up. π
β¨ SEE ALSO β¨
- Kernel file
./drivers/firmware/arm_scmi/raw_mode.c struct scmi_raw_queue(9)struct scmi_raw_mode_info(9)struct scmi_xfer_raw_waiter(9)struct scmi_raw_buffer(9)struct scmi_dbg_raw_data(9)scmi_xfer_raw_worker(9)scmi_xfer_raw_get_init(9)scmi_do_xfer_raw_start(9)scmi_raw_message_send(9)scmi_raw_message_receive(9)scmi_raw_mode_init(9)scmi_raw_mode_cleanup(9)scmi_raw_message_report(9)scmi_raw_error_report(9)
source/version: ./drivers/firmware/arm_scmi Β· date: October 2026 Β· page: Theory of operation(9) β mwah, go slay your tests bestie ππ
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms